Bug 639777 - Port Bug 625257 [Undo Close Tab does not work for not-yet-loaded tab]. r=Neil
authorMisak Khachatryan <misak.bugzilla@gmail.com>
Tue, 08 Mar 2011 17:56:54 +0400
changeset 7280 ffc62985589918ffe3396d4d95344a85cf44eb7f
parent 7279 6499341dae5e67ecaa141020850bc815ebe8777e
child 7281 22e2a5cf34abcdd83602d705135666c1863512f2
push idunknown
push userunknown
push dateunknown
reviewersNeil
bugs639777, 625257
Bug 639777 - Port Bug 625257 [Undo Close Tab does not work for not-yet-loaded tab]. r=Neil
suite/common/src/nsSessionStore.js
suite/common/tests/browser/Makefile.in
suite/common/tests/browser/browser_625257.js
--- a/suite/common/src/nsSessionStore.js
+++ b/suite/common/src/nsSessionStore.js
@@ -1365,16 +1365,17 @@ SessionStoreService.prototype = {
       history = browser.sessionHistory;
     }
     catch (ex) { } // this could happen if we catch a tab during (de)initialization
 
     // XXXzeniko anchor navigation doesn't reset __SS_data, so we could reuse
     //           data even when we shouldn't (e.g. Back, different anchor)
     if (history && browser.__SS_data &&
         browser.__SS_data.entries[history.index] &&
+        browser.__SS_data.entries[history.index].url == browser.currentURI.spec &&
         history.index < this._sessionhistory_max_entries - 1 && !aFullData) {
       tabData = browser.__SS_data;
       tabData.index = history.index + 1;
     }
     else if (history && history.count > 0) {
       for (var j = 0; j < history.count; j++) {
         let entry = this._serializeHistoryEntry(history.getEntryAtIndex(j, false),
                                                 aFullData, false);
--- a/suite/common/tests/browser/Makefile.in
+++ b/suite/common/tests/browser/Makefile.in
@@ -96,16 +96,17 @@ include $(topsrcdir)/config/rules.mk
 	browser_597315_index.html \
 	browser_597315_a.html \
 	browser_597315_b.html \
 	browser_597315_c.html \
 	browser_597315_c1.html \
 	browser_597315_c2.html \
 	browser_607016.js \
 	browser_615394-SSWindowState_events.js \
+	browser_625257.js \
 	browser_isempty.js \
 	browser_markPageAsFollowedLink.js \
 	framedPage.html \
 	frameLeft.html \
 	frameRight.html \
 	$(NULL)
 
 libs::	$(_BROWSER_FILES)
new file mode 100644
--- /dev/null
+++ b/suite/common/tests/browser/browser_625257.js
@@ -0,0 +1,123 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is sessionstore test code.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Foundation.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Mehdi Mulani <mmmulani@uwaterloo.ca>
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK *****/
+
+// This tests that a tab which is closed while loading is not lost.
+// Specifically, that session store does not rely on an invalid cache when
+// constructing data for a tab which is loading.
+
+let ss = Components.classes["@mozilla.org/suite/sessionstore;1"]
+                   .getService(Components.interfaces.nsISessionStore);
+
+// The newly created tab which we load a URL into and try closing/undoing.
+let tab;
+
+// This test steps through the following parts:
+//  1. Tab has been created is loading URI_TO_LOAD.
+//  2. Before URI_TO_LOAD finishes loading, browser.currentURI has changed and
+//     tab is scheduled to be removed.
+//  3. After the tab has been closed, undoCloseTab() has been called and the tab
+//     should fully load.
+const URI_TO_LOAD = "about:logo";
+
+function test() {
+  waitForExplicitFinish();
+
+  Services.prefs.setIntPref("browser.tabs.max_tabs_undo", 0);
+  getBrowser().addTabsProgressListener(tabsListener);
+
+  tab = getBrowser().addTab();
+
+  tab.linkedBrowser.addEventListener("load", firstOnLoad, true);
+
+  getBrowser().tabContainer.addEventListener("TabClose", onTabClose, true);
+}
+
+function firstOnLoad(aEvent) {
+  tab.linkedBrowser.removeEventListener("load", firstOnLoad, true);
+
+  let uri = aEvent.target.location;
+  is(uri, "about:blank", "first load should be for about:blank");
+
+  // Trigger a save state.
+  ss.getBrowserState();
+
+  is(getBrowser().tabs[1], tab, "newly created tab should exist by now");
+  ok(tab.linkedBrowser.__SS_data, "newly created tab should be in save state");
+
+  tab.linkedBrowser.loadURI(URI_TO_LOAD);
+}
+
+let tabsListener = {
+  onLocationChange: function onLocationChange(aBrowser) {
+    getBrowser().removeTabsProgressListener(tabsListener);
+
+    is(aBrowser.currentURI.spec, URI_TO_LOAD,
+       "should occur after about:blank load and be loading next page");
+
+    // Since we are running in the context of tabs listeners, we do not
+    // want to disrupt other tabs listeners.
+    executeSoon(function() {
+      getBrowser().removeTab(tab);
+    });
+  }
+};
+
+function onTabClose(aEvent) {
+  getBrowser().tabContainer.removeEventListener("TabClose", onTabClose, true);
+
+  is(tab.linkedBrowser.currentURI.spec, URI_TO_LOAD,
+     "should only remove when loading page");
+
+  executeSoon(function() {
+    tab = ss.undoCloseTab(window, 0);
+    tab.linkedBrowser.addEventListener("load", secondOnLoad, true);
+  });
+}
+
+function secondOnLoad(aEvent) {
+  let uri = aEvent.target.location;
+  is(uri, URI_TO_LOAD, "should load page from undoCloseTab");
+  done();
+}
+
+function done() {
+  tab.linkedBrowser.removeEventListener("load", secondOnLoad, true);
+  getBrowser().removeTab(tab);
+  Services.prefs.clearUserPref("browser.tabs.max_tabs_undo");
+
+  executeSoon(finish);
+}