From d2f1a99d9cfae6ee8b8d49765841e4c5f4604549 Mon Sep 17 00:00:00 2001 From: Tim Taubert Date: Fri, 9 Dec 2011 19:24:49 +0100 Subject: [PATCH] Bug 705597 - about:blank subframe entries in session restore make browser slow; r=dietrich --- .../sessionstore/src/nsSessionStore.js | 28 +++++---- .../sessionstore/test/browser/Makefile.in | 1 + .../test/browser/browser_705597.js | 57 +++++++++++++++++++ 3 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 browser/components/sessionstore/test/browser/browser_705597.js diff --git a/browser/components/sessionstore/src/nsSessionStore.js b/browser/components/sessionstore/src/nsSessionStore.js index bdb14eaac5f7..41ae9022167c 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 3e3445b99c06..a455692387cf 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 000000000000..3eb7d57b1c15 --- /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)); +}