Bug 1543098 - Emit executionContextDestroyed and executionContextCreated when the page goes into/out of the BF Cache. r=ato

Differential Revision: https://phabricator.services.mozilla.com/D28959

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Alexandre Poirot 2019-04-29 14:59:07 +00:00
Родитель 518602fb41
Коммит b17e090d38
2 изменённых файлов: 62 добавлений и 4 удалений

Просмотреть файл

@ -27,6 +27,12 @@ class Runtime extends ContentProcessDomain {
this.chromeEventHandler.addEventListener("DOMWindowCreated", this,
{mozSystemGroup: true});
// Listen for pageshow and pagehide to track pages going in/out to/from the BF Cache
this.chromeEventHandler.addEventListener("pageshow", this,
{mozSystemGroup: true});
this.chromeEventHandler.addEventListener("pagehide", this,
{mozSystemGroup: true});
Services.obs.addObserver(this, "inner-window-destroyed");
// Spin the event loop in order to send the `executionContextCreated` event right
@ -52,11 +58,15 @@ class Runtime extends ContentProcessDomain {
this.enabled = false;
this.chromeEventHandler.removeEventListener("DOMWindowCreated", this,
{mozSystemGroup: true});
this.chromeEventHandler.removeEventListener("pageshow", this,
{mozSystemGroup: true});
this.chromeEventHandler.removeEventListener("pagehide", this,
{mozSystemGroup: true});
Services.obs.removeObserver(this, "inner-window-destroyed");
}
}
handleEvent({type, target}) {
handleEvent({type, target, persisted}) {
const frameId = target.defaultView.windowUtils.outerWindowID;
const id = target.defaultView.windowUtils.currentInnerWindowID;
switch (type) {
@ -71,6 +81,32 @@ class Runtime extends ContentProcessDomain {
},
});
break;
case "pageshow":
// `persisted` is true when this is about a page being resurected from BF Cache
if (!persisted) {
return;
}
this.emit("Runtime.executionContextCreated", {
context: {
id,
auxData: {
isDefault: target == this.content.document,
frameId,
},
},
});
break;
case "pagehide":
// `persisted` is true when this is about a page being frozen into BF Cache
if (!persisted) {
return;
}
this.emit("Runtime.executionContextDestroyed", {
executionContextId: id,
});
break;
}
}

Просмотреть файл

@ -59,20 +59,42 @@ async function testCDP() {
ok(context1.auxData.isDefault, "The execution context is the default one");
ok(!!context1.auxData.frameId, "The execution context has a frame id set");
const executionContextCreated = Runtime.executionContextCreated();
info("Navigate to a new URL");
const executionContextDestroyed2 = Runtime.executionContextDestroyed();
const executionContextCreated2 = Runtime.executionContextCreated();
const url = "data:text/html;charset=utf-8,test-page";
const { frameId } = await Page.navigate({ url });
ok(true, "A new page has been loaded");
is(frameId, context1.auxData.frameId, "Page.navigate returns the same frameId than executionContextCreated");
const { context: context2 } = await executionContextCreated;
let { executionContextId } = await executionContextDestroyed2;
is(executionContextId, context1.id, "The destroyed event reports the previous context id");
const { context: context2 } = await executionContextCreated2;
ok(!!context2.id, "The execution context has an id");
isnot(context1.id, context2.id, "The new execution context has a different id");
ok(context2.auxData.isDefault, "The execution context is the default one");
is(context2.auxData.frameId, frameId, "The execution context frame id is the same " +
"the one returned by Page.navigate");
"than the one returned by Page.navigate");
isnot(executionContextId, context2.id, "The destroyed id is different from the " +
"created one");
// Navigates back to the previous page.
// This should resurect the original document from the BF Cache and recreate the
// context for it
info("Navigate back to the previous document");
const executionContextDestroyed3 = Runtime.executionContextDestroyed();
const executionContextCreated3 = Runtime.executionContextCreated();
gBrowser.selectedBrowser.goBack();
const { context: context3 } = await executionContextCreated3;
is(context3.id, context1.id, "The new execution context should be the same than the first one");
ok(context3.auxData.isDefault, "The execution context is the default one");
is(context3.auxData.frameId, frameId, "The execution context frame id is always the same");
({ executionContextId } = await executionContextDestroyed3);
is(executionContextId, context2.id, "The destroyed event reports the previous context id");
await client.close();
ok(true, "The client is closed");