gecko-dev/browser/actors/LightweightThemeChild.jsm
Felipe Gomes 93a0f8e0fd Bug 1490810 - Simulate Fission for browser actors by blocking them from receiving sub-frame events. r=kmag
If the pref browser.fission.simulate is true, the event dispatcher in ActorManagerChild will not dispatch events to actors that aren't associated with the same window as the event's target.

In addition, when that pref is on, the actors associated with sub-frames will have their content property bound to the correct content window, that might differ from the message manager's window (which is always related to the top level).

Then, in order to write Fission-compatible code, that specific actor will need to be declared with allFrames = true, meaning that it wants to be instantiated for every frame, and not just top-level ones

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

--HG--
extra : moz-landing-system : lando
2018-09-26 21:46:18 +00:00

88 lines
2.7 KiB
JavaScript

/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
var EXPORTED_SYMBOLS = ["LightweightThemeChild"];
ChromeUtils.import("resource://gre/modules/ActorChild.jsm");
ChromeUtils.import("resource://gre/modules/Services.jsm");
/**
* LightweightThemeChild forwards theme data to in-content pages.
* It is both instantiated by the traditional Actor mechanism,
* and also manually within the sidebar JS global (which has no message manager)
*/
class LightweightThemeChild extends ActorChild {
constructor(dispatcher) {
if (dispatcher.mm) {
// This is being instantiated by the Actor mechanism.
super(dispatcher);
} else {
// Manually instantiated by the sidebar.
let fakeDispatcher = {
mm: dispatcher,
window: dispatcher.content,
addEventListener: dispatcher.content.addEventListener,
};
super(fakeDispatcher);
}
this.init();
}
/**
* Initializes the actor for the current page, sending it any existing
* theme data, and adding shared data change listeners so it can
* notify the page of future updates.
*
* This is called when the actor is constructed, and any time
* ActorManagerChild receives a pageshow event for the page we're
* attached to.
*/
init() {
Services.cpmm.sharedData.addEventListener("change", this);
this.update(this.mm.chromeOuterWindowID, this.content);
}
/**
* Cleans up any global listeners registered by the actor.
*
* This is called by ActorManagerChild any time it receives a pagehide
* event for the page we're attached to.
*/
cleanup() {
super.cleanup();
Services.cpmm.sharedData.removeEventListener("change", this);
}
/**
* Handles "change" events on the child sharedData map, and notifies
* our content page if its theme data was among the changed keys.
*/
handleEvent(event) {
if (event.type === "change") {
if (event.changedKeys.includes(`theme/${this.mm.chromeOuterWindowID}`)) {
this.update(this.mm.chromeOuterWindowID, this.content);
}
}
}
/**
* Forward the theme data to the page.
* @param {Object} outerWindowID The outerWindowID the parent process window has.
* @param {Object} content The receiving global
*/
update(outerWindowID, content) {
const event = Cu.cloneInto({
detail: {
data: Services.cpmm.sharedData.get(`theme/${outerWindowID}`),
},
}, content);
content.dispatchEvent(new content.CustomEvent("LightweightTheme:Set",
event));
}
}