зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1698663 - Make Document::RemoveFromBFCacheSync() work with SHIP+BFCache, r=peterv
Depends on D108487 Differential Revision: https://phabricator.services.mozilla.com/D108851
This commit is contained in:
Родитель
dd5347ded5
Коммит
b535d5b970
|
@ -0,0 +1,29 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
onpageshow = function(pageShowEvent) {
|
||||
var bc = new BroadcastChannel("evict_from_bfcache");
|
||||
bc.onmessage = function(event) {
|
||||
if (event.data == "nextpage") {
|
||||
bc.close();
|
||||
location.href += "?nextpage";
|
||||
} else if (event.data == "back") {
|
||||
bc.close();
|
||||
history.back();
|
||||
} else if (event.data == "forward") {
|
||||
// Note, we don't close BroadcastChannel
|
||||
history.forward();
|
||||
} else if (event.data == "close") {
|
||||
bc.postMessage("closed");
|
||||
bc.close();
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
bc.postMessage({ type: "pageshow", persisted: pageShowEvent.persisted});
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
|
@ -100,6 +100,8 @@ support-files = file_bug1536471.html
|
|||
[test_child.html]
|
||||
[test_docshell_gotoindex.html]
|
||||
support-files = file_docshell_gotoindex.html
|
||||
[test_evict_from_bfcache.html]
|
||||
support-files = file_evict_from_bfcache.html
|
||||
[test_grandchild.html]
|
||||
[test_load_history_entry.html]
|
||||
[test_meta_refresh.html]
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Evict a page from bfcache</title>
|
||||
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" href="/tests/SimpleTest/test.css"/>
|
||||
<script>
|
||||
/*
|
||||
* This test checks that a page can be evicted from bfcache. Sending a
|
||||
* message to an open BroadcastChannel is used for this.
|
||||
*
|
||||
* First the test opens a window and loads a page there. Another page is then
|
||||
* loaded and then session history is navigated back to check if bfcache is
|
||||
* enabled. If not, close message is sent to close the opened window and this
|
||||
* controller page will finish the test.
|
||||
* If bfcache is enabled, session history goes forward, but the
|
||||
* BroadcastChannel in the page isn't closed. Then sending the message to go
|
||||
* back again should evict the bfcached page.
|
||||
* Close message is sent and window closed and test finishes.
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
var bc = new BroadcastChannel("evict_from_bfcache");
|
||||
var pageshowCount = 0;
|
||||
bc.onmessage = function(event) {
|
||||
if (event.data.type == "pageshow") {
|
||||
++pageshowCount;
|
||||
info("pageshow " + pageshowCount);
|
||||
if (pageshowCount == 1) {
|
||||
bc.postMessage("nextpage");
|
||||
} else if (pageshowCount == 2) {
|
||||
bc.postMessage("back");
|
||||
} else if (pageshowCount == 3) {
|
||||
if (!event.data.persisted) {
|
||||
ok(true, "BFCache isn't enabled.");
|
||||
bc.postMessage("close");
|
||||
} else {
|
||||
bc.postMessage("forward");
|
||||
}
|
||||
} else if (pageshowCount == 4) {
|
||||
bc.postMessage("back");
|
||||
} else if (pageshowCount == 5) {
|
||||
ok(!event.data.persisted,
|
||||
"The page should have been evicted from BFCache");
|
||||
bc.postMessage("close");
|
||||
}
|
||||
} else if (event.data == "closed") {
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
function runTest() {
|
||||
window.open("file_evict_from_bfcache.html", "", "noopener");
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="runTest()">
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test"></pre>
|
||||
</body>
|
||||
</html>
|
|
@ -6632,6 +6632,22 @@ bool Document::RemoveFromBFCacheSync() {
|
|||
entry->RemoveFromBFCacheSync();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
if (BrowsingContext* bc = GetBrowsingContext()) {
|
||||
BrowsingContext* top = bc->Top();
|
||||
if (top->GetIsInBFCache()) {
|
||||
ContentChild* cc = ContentChild::GetSingleton();
|
||||
// IPC is asynchronous but the caller is supposed to check the return
|
||||
// value. The reason for 'Sync' in the method name is that the old
|
||||
// implementation may run scripts. There is Async variant in
|
||||
// the old session history implementation for the cases where
|
||||
// synchronous operation isn't safe.
|
||||
cc->SendRemoveFromBFCache(top);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -7368,6 +7368,49 @@ ContentParent::RecvGetLoadingSessionHistoryInfoFromParent(
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvRemoveFromBFCache(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext) {
|
||||
if (aContext.IsNullOrDiscarded()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsFrameLoaderOwner> owner =
|
||||
do_QueryInterface(aContext.get_canonical()->GetEmbedderElement());
|
||||
if (!owner) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
RefPtr<nsFrameLoader> frameLoader = owner->GetFrameLoader();
|
||||
if (!frameLoader || !frameLoader->GetMaybePendingBrowsingContext()) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISHistory> shistory = frameLoader->GetMaybePendingBrowsingContext()
|
||||
->Canonical()
|
||||
->GetSessionHistory();
|
||||
if (!shistory) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
uint32_t count = shistory->GetCount();
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsISHEntry> entry;
|
||||
shistory->GetEntryAtIndex(i, getter_AddRefs(entry));
|
||||
nsCOMPtr<SessionHistoryEntry> she = do_QueryInterface(entry);
|
||||
if (she) {
|
||||
if (RefPtr<nsFrameLoader> frameLoader = she->GetFrameLoader()) {
|
||||
if (frameLoader->GetMaybePendingBrowsingContext() == aContext.get()) {
|
||||
she->SetFrameLoader(nullptr);
|
||||
frameLoader->Destroy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult ContentParent::RecvSetActiveSessionHistoryEntry(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
const Maybe<nsPoint>& aPreviousScrollPos, SessionHistoryInfo&& aInfo,
|
||||
|
|
|
@ -1384,6 +1384,9 @@ class ContentParent final
|
|||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
GetLoadingSessionHistoryInfoFromParentResolver&& aResolver);
|
||||
|
||||
mozilla::ipc::IPCResult RecvRemoveFromBFCache(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext);
|
||||
|
||||
mozilla::ipc::IPCResult RecvSetActiveSessionHistoryEntry(
|
||||
const MaybeDiscarded<BrowsingContext>& aContext,
|
||||
const Maybe<nsPoint>& aPreviousScrollPos, SessionHistoryInfo&& aInfo,
|
||||
|
|
|
@ -958,6 +958,8 @@ parent:
|
|||
async GetLoadingSessionHistoryInfoFromParent(MaybeDiscardedBrowsingContext aContext)
|
||||
returns (LoadingSessionHistoryInfo? aLoadingInfo, int32_t aRequestedIndex, int32_t aLength);
|
||||
|
||||
async RemoveFromBFCache(MaybeDiscardedBrowsingContext aContext);
|
||||
|
||||
async InitBackground(Endpoint<PBackgroundParent> aEndpoint);
|
||||
|
||||
async CreateGMPService();
|
||||
|
|
Загрузка…
Ссылка в новой задаче