Bug 1483664: Part 1 - Use lazy actor infrastructure for LightweightThemeChild. r=ntim

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

--HG--
rename : browser/modules/LightweightThemeChildHelper.jsm => browser/actors/LightweightThemeChild.jsm
extra : rebase_source : 0f6e10f9ebe5674a001846fe7ad23d13ededa8fa
This commit is contained in:
Kris Maglione 2018-08-15 20:06:58 -07:00
parent 0c6cd02ae1
commit 870d813b3a
7 changed files with 113 additions and 90 deletions

View File

@ -0,0 +1,72 @@
/* 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.
*/
class LightweightThemeChild extends ActorChild {
constructor(mm) {
super(mm);
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() {
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));
}
}

View File

@ -7,6 +7,9 @@
with Files("**"):
BUG_COMPONENT = ("Firefox", "General")
with Files("LightweightThemeChild.jsm"):
BUG_COMPONENT = ("WebExtensions", "Themes")
with Files("LightWeightThemeInstallChild.jsm"):
BUG_COMPONENT = ("Firefox", "Theme")
@ -30,6 +33,7 @@ FINAL_TARGET_FILES.actors += [
'ContentSearchChild.jsm',
'ContextMenuChild.jsm',
'DOMFullscreenChild.jsm',
'LightweightThemeChild.jsm',
'LightWeightThemeInstallChild.jsm',
'LinkHandlerChild.jsm',
'NetErrorChild.jsm',

View File

@ -22,22 +22,6 @@ ActorManagerChild.attach(this, "browsers");
// TabChildGlobal
var global = this;
XPCOMUtils.defineLazyProxy(this, "LightweightThemeChildHelper",
"resource:///modules/LightweightThemeChildHelper.jsm");
let themeablePagesWhitelist = new Set([
"about:home",
"about:newtab",
"about:welcome",
]);
addEventListener("pageshow", function({ originalTarget }) {
if (originalTarget.defaultView == content && themeablePagesWhitelist.has(content.document.documentURI)) {
LightweightThemeChildHelper.listen(themeablePagesWhitelist);
LightweightThemeChildHelper.update(chromeOuterWindowID, content);
}
}, false, true);
// Keep a reference to the translation content handler to avoid it it being GC'ed.
var trHandler = null;
if (Services.prefs.getBoolPref("browser.translation.detectLanguage")) {

View File

@ -131,6 +131,16 @@ let ACTORS = {
},
},
LightweightTheme: {
child: {
module: "resource:///actors/LightweightThemeChild.jsm",
matches: ["about:home", "about:newtab", "about:welcome"],
events: {
"pageshow": {mozSystemGroup: true},
},
},
},
LinkHandler: {
child: {
module: "resource:///actors/LinkHandlerChild.jsm",

View File

@ -1,68 +0,0 @@
/* 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";
ChromeUtils.import("resource://gre/modules/Services.jsm");
var EXPORTED_SYMBOLS = ["LightweightThemeChildHelper"];
/**
* LightweightThemeChildHelper forwards theme data to in-content pages.
*/
var LightweightThemeChildHelper = {
listener: null,
whitelist: null,
/**
* Listen to theme updates for the current process
* @param {Array} whitelist The pages that can receive theme updates.
*/
listen(whitelist) {
if (!this.listener) {
// Clone the whitelist to avoid leaking the global the whitelist
// originates from.
this.whitelist = new Set([...whitelist]);
this.listener = ({ changedKeys }) => {
if (changedKeys.find(change => change.startsWith("theme/"))) {
this._updateProcess(changedKeys);
}
};
Services.cpmm.sharedData.addEventListener("change", this.listener);
}
},
/**
* Update the theme data for the whole process
* @param {Array} changedKeys The sharedData keys that were changed.
*/
_updateProcess(changedKeys) {
const windowEnumerator = Services.ww.getWindowEnumerator();
while (windowEnumerator.hasMoreElements()) {
const {
chromeOuterWindowID,
content,
} = windowEnumerator.getNext().docShell.messageManager;
if (changedKeys.includes(`theme/${chromeOuterWindowID}`) &&
content && this.whitelist.has(content.document.documentURI)) {
this.update(chromeOuterWindowID, 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));
},
};

View File

@ -61,9 +61,6 @@ with Files("ExtensionsUI.jsm"):
with Files("LaterRun.jsm"):
BUG_COMPONENT = ("Firefox", "Tours")
with Files("LightweightThemeChildHelper.jsm"):
BUG_COMPONENT = ("WebExtensions", "Themes")
with Files("OpenInTabsUtils.jsm"):
BUG_COMPONENT = ("Firefox", "Tabbed Browser")
@ -134,7 +131,6 @@ EXTRA_JS_MODULES += [
'FormValidationHandler.jsm',
'HomePage.jsm',
'LaterRun.jsm',
'LightweightThemeChildHelper.jsm',
'OpenInTabsUtils.jsm',
'PageActions.jsm',
'PermissionUI.jsm',

View File

@ -116,13 +116,27 @@ class SingletonDispatcher extends Dispatcher {
constructor(window, data) {
super(getMessageManager(window), data);
window.addEventListener("pageshow", this);
window.addEventListener("pagehide", this);
window.addEventListener("pageshow", this, {mozSystemGroup: true});
window.addEventListener("pagehide", this, {mozSystemGroup: true});
this.window = window;
this.listeners = [];
}
init() {
super.init();
for (let actor of this.instances.values()) {
if (typeof actor.init === "function") {
try {
actor.init();
} catch (e) {
Cu.reportError(e);
}
}
}
}
cleanup() {
super.cleanup();
@ -132,6 +146,17 @@ class SingletonDispatcher extends Dispatcher {
for (let [event, listener, options] of this.listeners) {
this.window.removeEventListener(event, listener, options);
}
for (let actor of this.instances.values()) {
if (typeof actor.cleanup === "function") {
try {
actor.cleanup();
} catch (e) {
Cu.reportError(e);
}
}
}
this.listeners = null;
}