diff --git a/browser/components/sessionstore/src/nsSessionStore.js b/browser/components/sessionstore/src/nsSessionStore.js index bdb14eaac5f..41ae9022167 100644 --- a/browser/components/sessionstore/src/nsSessionStore.js +++ b/browser/components/sessionstore/src/nsSessionStore.js @@ -1861,7 +1861,9 @@ SessionStoreService.prototype = { var entry = { url: aEntry.URI.spec }; try { - aHostSchemeData.push({ host: aEntry.URI.host, scheme: aEntry.URI.scheme }); + // throwing is expensive, we know that about: pages will throw + if (entry.url.indexOf("about:") != 0) + aHostSchemeData.push({ host: aEntry.URI.host, scheme: aEntry.URI.scheme }); } catch (ex) { // We just won't attempt to get cookies for this entry. @@ -1959,22 +1961,24 @@ SessionStoreService.prototype = { } if (aEntry.childCount > 0) { - entry.children = []; + let children = []; for (var i = 0; i < aEntry.childCount; i++) { var child = aEntry.GetChildAt(i); + if (child) { - entry.children.push(this._serializeHistoryEntry(child, aFullData, - aIsPinned, aHostSchemeData)); - } - else { // to maintain the correct frame order, insert a dummy entry - entry.children.push({ url: "about:blank" }); - } - // don't try to restore framesets containing wyciwyg URLs (cf. bug 424689 and bug 450595) - if (/^wyciwyg:\/\//.test(entry.children[i].url)) { - delete entry.children; - break; + // don't try to restore framesets containing wyciwyg URLs (cf. bug 424689 and bug 450595) + if (child.URI.schemeIs("wyciwyg")) { + children = []; + break; + } + + children.push(this._serializeHistoryEntry(child, aFullData, + aIsPinned, aHostSchemeData)); } } + + if (children.length) + entry.children = children; } return entry; diff --git a/browser/components/sessionstore/test/browser/Makefile.in b/browser/components/sessionstore/test/browser/Makefile.in index 3e3445b99c0..a455692387c 100644 --- a/browser/components/sessionstore/test/browser/Makefile.in +++ b/browser/components/sessionstore/test/browser/Makefile.in @@ -159,6 +159,7 @@ _BROWSER_TEST_FILES = \ browser_687710.js \ browser_687710_2.js \ browser_694378.js \ + browser_705597.js \ $(NULL) ifneq ($(OS_ARCH),Darwin) diff --git a/browser/components/sessionstore/test/browser/browser_705597.js b/browser/components/sessionstore/test/browser/browser_705597.js new file mode 100644 index 00000000000..3eb7d57b1c1 --- /dev/null +++ b/browser/components/sessionstore/test/browser/browser_705597.js @@ -0,0 +1,57 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +let tabState = { + entries: [{url: "about:home", children: [{url: "about:mozilla"}]}] +}; + +function test() { + waitForExplicitFinish(); + + let tab = gBrowser.addTab("about:blank"); + registerCleanupFunction(function () gBrowser.removeTab(tab)); + + let browser = tab.linkedBrowser; + + whenBrowserLoaded(browser, function () { + ss.setTabState(tab, JSON.stringify(tabState)); + + let sessionHistory = browser.sessionHistory; + let entry = sessionHistory.getEntryAtIndex(0, false); + + whenChildCount(entry, 1, function () { + whenChildCount(entry, 2, function () { + whenBrowserLoaded(browser, function () { + let {entries} = JSON.parse(ss.getTabState(tab)); + is(entries.length, 1, "tab has one history entry"); + ok(!entries[0].children, "history entry has no subframes"); + + finish(); + }); + + // reload the browser to deprecate the subframes + browser.reload(); + }); + + // create a dynamic subframe + let doc = browser.contentDocument; + let iframe = doc.createElement("iframe"); + iframe.setAttribute("src", "about:mozilla"); + doc.body.appendChild(iframe); + }); + }); +} + +function whenBrowserLoaded(aBrowser, aCallback) { + aBrowser.addEventListener("load", function onLoad() { + aBrowser.removeEventListener("load", onLoad, true); + executeSoon(aCallback); + }, true); +} + +function whenChildCount(aEntry, aChildCount, aCallback) { + if (aEntry.childCount == aChildCount) + aCallback(); + else + executeSoon(function () whenChildCount(aEntry, aChildCount, aCallback)); +}