mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 22:01:30 +00:00
Bug 449780. When doing a frameloader swap, clear the bfcache on both docshells, since we can't deal with all those presentations. r+sr=jst
This commit is contained in:
parent
8a568e773c
commit
9ab3dc1969
@ -73,6 +73,7 @@
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsISHistory.h"
|
||||
#include "nsISHistoryInternal.h"
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
@ -494,24 +495,23 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
nsCOMPtr<nsIDocShellTreeItem> ourRootTreeItem, otherRootTreeItem;
|
||||
ourTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(ourRootTreeItem));
|
||||
otherTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(otherRootTreeItem));
|
||||
if (ourRootTreeItem != ourTreeItem || otherRootTreeItem != otherTreeItem) {
|
||||
nsCOMPtr<nsIWebNavigation> ourRootWebnav =
|
||||
do_QueryInterface(ourRootTreeItem);
|
||||
nsCOMPtr<nsIWebNavigation> otherRootWebnav =
|
||||
do_QueryInterface(otherRootTreeItem);
|
||||
nsCOMPtr<nsIWebNavigation> ourRootWebnav =
|
||||
do_QueryInterface(ourRootTreeItem);
|
||||
nsCOMPtr<nsIWebNavigation> otherRootWebnav =
|
||||
do_QueryInterface(otherRootTreeItem);
|
||||
|
||||
if (!ourRootWebnav || !otherRootWebnav) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if (!ourRootWebnav || !otherRootWebnav) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISHistory> ourHistory;
|
||||
nsCOMPtr<nsISHistory> otherHistory;
|
||||
ourRootWebnav->GetSessionHistory(getter_AddRefs(ourHistory));
|
||||
otherRootWebnav->GetSessionHistory(getter_AddRefs(otherHistory));
|
||||
nsCOMPtr<nsISHistory> ourHistory;
|
||||
nsCOMPtr<nsISHistory> otherHistory;
|
||||
ourRootWebnav->GetSessionHistory(getter_AddRefs(ourHistory));
|
||||
otherRootWebnav->GetSessionHistory(getter_AddRefs(otherHistory));
|
||||
|
||||
if (ourHistory || otherHistory) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
if ((ourRootTreeItem != ourTreeItem || otherRootTreeItem != otherTreeItem) &&
|
||||
(ourHistory || otherHistory)) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Also make sure that the two docshells are the same type. Otherwise
|
||||
@ -524,7 +524,7 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// One more twist here. Setting up the right treeowners in a heterogenous
|
||||
// One more twist here. Setting up the right treeowners in a heterogeneous
|
||||
// tree is a bit of a pain. So make sure that if ourType is not
|
||||
// nsIDocShellTreeItem::typeContent then all of our descendants are the same
|
||||
// type as us.
|
||||
@ -692,6 +692,18 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
|
||||
aFirstToSwap.swap(aSecondToSwap);
|
||||
|
||||
// Drop any cached content viewers in the two session histories.
|
||||
nsCOMPtr<nsISHistoryInternal> ourInternalHistory =
|
||||
do_QueryInterface(ourHistory);
|
||||
nsCOMPtr<nsISHistoryInternal> otherInternalHistory =
|
||||
do_QueryInterface(otherHistory);
|
||||
if (ourInternalHistory) {
|
||||
ourInternalHistory->EvictAllContentViewers();
|
||||
}
|
||||
if (otherInternalHistory) {
|
||||
otherInternalHistory->EvictAllContentViewers();
|
||||
}
|
||||
|
||||
// We shouldn't have changed frames, but be really careful about it
|
||||
if (ourFrame == ourShell->GetPrimaryFrameFor(ourContent) &&
|
||||
otherFrame == otherShell->GetPrimaryFrameFor(otherContent)) {
|
||||
|
@ -52,7 +52,7 @@ interface nsIDocShell;
|
||||
#define NS_SHISTORY_INTERNAL_CONTRACTID "@mozilla.org/browser/shistory-internal;1"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(9c47c121-1c6e-4d8f-b904-3ac968116e88)]
|
||||
[scriptable, uuid(7ca0fd71-437c-48ad-985d-11ce9e2429b4)]
|
||||
interface nsISHistoryInternal: nsISupports
|
||||
{
|
||||
/**
|
||||
@ -105,4 +105,9 @@ interface nsISHistoryInternal: nsISupports
|
||||
* that has timed out.
|
||||
*/
|
||||
void evictExpiredContentViewerForEntry(in nsISHEntry aEntry);
|
||||
|
||||
/**
|
||||
* Evict all the content viewers in this session history
|
||||
*/
|
||||
void evictAllContentViewers();
|
||||
};
|
||||
|
@ -118,7 +118,7 @@ nsSHistoryObserver::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
nsSHistory::EvictGlobalContentViewer();
|
||||
} else if (!strcmp(aTopic, NS_CACHESERVICE_EMPTYCACHE_TOPIC_ID) ||
|
||||
!strcmp(aTopic, "memory-pressure")) {
|
||||
nsSHistory::EvictAllContentViewers();
|
||||
nsSHistory::EvictAllContentViewersGlobally();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -664,6 +664,17 @@ nsSHistory::EvictContentViewers(PRInt32 aPreviousIndex, PRInt32 aIndex)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSHistory::EvictAllContentViewers()
|
||||
{
|
||||
// XXXbz we don't actually do a good job of evicting things as we should, so
|
||||
// we might have viewers quite far from mIndex. So just evict everything.
|
||||
EvictContentViewersInRange(0, mLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsSHistory: nsIWebNavigation
|
||||
//*****************************************************************************
|
||||
@ -1038,7 +1049,7 @@ nsSHistory::EvictExpiredContentViewerForEntry(nsISHEntry *aEntry)
|
||||
|
||||
//static
|
||||
void
|
||||
nsSHistory::EvictAllContentViewers()
|
||||
nsSHistory::EvictAllContentViewersGlobally()
|
||||
{
|
||||
PRInt32 maxViewers = sHistoryMaxTotalViewers;
|
||||
sHistoryMaxTotalViewers = 0;
|
||||
|
@ -99,10 +99,12 @@ protected:
|
||||
nsresult PrintHistory();
|
||||
#endif
|
||||
|
||||
// Evict the viewers at indices between aStartIndex and aEndIndex,
|
||||
// including aStartIndex but not aEndIndex.
|
||||
void EvictContentViewersInRange(PRInt32 aStartIndex, PRInt32 aEndIndex);
|
||||
void EvictWindowContentViewers(PRInt32 aFromIndex, PRInt32 aToIndex);
|
||||
static void EvictGlobalContentViewer();
|
||||
static void EvictAllContentViewers();
|
||||
static void EvictAllContentViewersGlobally();
|
||||
|
||||
// Calculates a max number of total
|
||||
// content viewers to cache, based on amount of total memory
|
||||
|
@ -71,6 +71,8 @@ _TEST_FILES = \
|
||||
test_bug428288.html \
|
||||
test_bug449778.xul \
|
||||
bug449778_window.xul \
|
||||
test_bug449780.xul \
|
||||
bug449780_window.xul \
|
||||
test_bug454235.xul \
|
||||
bug454235-subframe.xul \
|
||||
test_bug456980.xul \
|
||||
|
78
docshell/test/chrome/bug449780_window.xul
Normal file
78
docshell/test/chrome/bug449780_window.xul
Normal file
@ -0,0 +1,78 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<window title="Mozilla Bug 449780" onload="doTheTest()"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<hbox id="parent">
|
||||
</hbox>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
var imports = [ "SimpleTest", "is", "isnot", "ok", "snapshotWindow",
|
||||
"compareSnapshots", "onerror" ];
|
||||
for each (var import in imports) {
|
||||
window[import] = window.opener.wrappedJSObject[import];
|
||||
}
|
||||
|
||||
function $(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function addBrowser(parent, id, width, height) {
|
||||
var b =
|
||||
document.createElementNS("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "browser");
|
||||
b.setAttribute("type", "content");
|
||||
b.setAttribute("id", id);
|
||||
b.setAttribute("width", width);
|
||||
b.setAttribute("height", height);
|
||||
$(parent).appendChild(b);
|
||||
}
|
||||
addBrowser("parent", "f1", 300, 200);
|
||||
addBrowser("parent", "f2", 300, 200);
|
||||
|
||||
/** Test for Bug 449780 **/
|
||||
var doc1 = "data:text/html,<html><body>This is a test</body></html>";
|
||||
var doc2 = "data:text/html,<html><body>This is a second test</body></html>";
|
||||
|
||||
function getDOM(id) {
|
||||
return $(id).contentDocument.documentElement.innerHTML;
|
||||
}
|
||||
|
||||
var tester = (function() {
|
||||
var origDOM = getDOM("f1");
|
||||
$("f1").contentDocument.body.textContent = "Modified";
|
||||
var modifiedDOM = getDOM("f1");
|
||||
isnot(origDOM, modifiedDOM, "DOM should be different");
|
||||
$("f1").contentWindow.location.href = doc2;
|
||||
yield;
|
||||
|
||||
$("f1").goBack();
|
||||
yield;
|
||||
|
||||
is(getDOM("f1"), modifiedDOM, "Should have been bfcached");
|
||||
$("f1").goForward();
|
||||
yield;
|
||||
|
||||
// Ignore the notifications during swap
|
||||
$("f1").removeEventListener("pageshow", testDriver, false);
|
||||
$("f1").swapDocShells($("f2"));
|
||||
$("f2").addEventListener("pageshow", testDriver, false);
|
||||
$("f2").goBack();
|
||||
yield;
|
||||
|
||||
is(getDOM("f2"), origDOM, "Should have not have been bfcached");
|
||||
window.close();
|
||||
SimpleTest.finish();
|
||||
yield;
|
||||
})();
|
||||
|
||||
function testDriver() {
|
||||
setTimeout(function() { tester.next() }, 0);
|
||||
}
|
||||
|
||||
function doTheTest() {
|
||||
$("f1").addEventListener("pageshow", testDriver, false);
|
||||
$("f1").setAttribute("src", doc1);
|
||||
}
|
||||
]]></script>
|
||||
</window>
|
33
docshell/test/chrome/test_bug449780.xul
Normal file
33
docshell/test/chrome/test_bug449780.xul
Normal file
@ -0,0 +1,33 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=449780
|
||||
-->
|
||||
<window title="Mozilla Bug 449780"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/WindowSnapshot.js"></script>
|
||||
|
||||
<!-- test results are displayed in the html:body -->
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=449780"
|
||||
target="_blank">Mozilla Bug 396519</a>
|
||||
</body>
|
||||
|
||||
<!-- test code goes here -->
|
||||
<script type="application/javascript"><![CDATA[
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
addLoadEvent(function() {
|
||||
window.open("bug449780_window.xul", "bug449780",
|
||||
"chrome,width=800,height=800");
|
||||
});
|
||||
|
||||
]]></script>
|
||||
</window>
|
Loading…
Reference in New Issue
Block a user