refactor: esm waterfox glue

This commit is contained in:
Alex Kontos
2022-09-20 10:36:38 +01:00
parent 740a64f68f
commit bf8f043095
3 changed files with 163 additions and 68 deletions

View File

@@ -80,7 +80,7 @@ ChromeUtils.defineESModuleGetters(lazy, {
"resource:///modules/WebProtocolHandlerRegistrar.sys.mjs", "resource:///modules/WebProtocolHandlerRegistrar.sys.mjs",
WindowsRegistry: "resource://gre/modules/WindowsRegistry.sys.mjs", WindowsRegistry: "resource://gre/modules/WindowsRegistry.sys.mjs",
setTimeout: "resource://gre/modules/Timer.sys.mjs", setTimeout: "resource://gre/modules/Timer.sys.mjs",
WaterfoxGlue: "resource:///modules/WaterfoxGlue.jsm", WaterfoxGlue: "resource:///modules/WaterfoxGlue.sys.mjs",
}); });
XPCOMUtils.defineLazyServiceGetters(lazy, { XPCOMUtils.defineLazyServiceGetters(lazy, {
@@ -234,7 +234,7 @@ BrowserGlue.prototype = {
const { BootstrapLoader } = ChromeUtils.importESModule( const { BootstrapLoader } = ChromeUtils.importESModule(
"resource:///modules/BootstrapLoader.sys.mjs" "resource:///modules/BootstrapLoader.sys.mjs"
); );
AddonManager.addExternalExtensionLoader(BootstrapLoader); lazy.AddonManager.addExternalExtensionLoader(BootstrapLoader);
break; break;
case "notifications-open-settings": case "notifications-open-settings":
this._openPreferences("privacy-permissions"); this._openPreferences("privacy-permissions");
@@ -402,7 +402,7 @@ BrowserGlue.prototype = {
lazy.DesktopActorRegistry.init(); lazy.DesktopActorRegistry.init();
WaterfoxGlue.init(); lazy.WaterfoxGlue.init();
}, },
// cleanup (called on application shutdown) // cleanup (called on application shutdown)

View File

@@ -2,20 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
"use strict";
const EXPORTED_SYMBOLS = ["WaterfoxGlue"];
const { XPCOMUtils } = ChromeUtils.import(
"resource://gre/modules/XPCOMUtils.jsm"
);
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
const lazy = {}; const lazy = {};
XPCOMUtils.defineLazyModuleGetters(lazy, { ChromeUtils.defineESModuleGetters(lazy, {
AddonManager: "resource://gre/modules/AddonManager.sys.mjs", AddonManager: "resource://gre/modules/AddonManager.sys.mjs",
AttributionCode: "resource:///modules/AttributionCode.sys.mjs",
BrowserUtils: "resource:///modules/BrowserUtils.sys.mjs", BrowserUtils: "resource:///modules/BrowserUtils.sys.mjs",
ChromeManifest: "resource:///modules/ChromeManifest.sys.mjs", ChromeManifest: "resource:///modules/ChromeManifest.sys.mjs",
Overlays: "resource:///modules/Overlays.sys.mjs", Overlays: "resource:///modules/Overlays.sys.mjs",
@@ -23,12 +14,24 @@ XPCOMUtils.defineLazyModuleGetters(lazy, {
PrivateTab: "resource:///modules/PrivateTab.sys.mjs", PrivateTab: "resource:///modules/PrivateTab.sys.mjs",
StatusBar: "resource:///modules/StatusBar.sys.mjs", StatusBar: "resource:///modules/StatusBar.sys.mjs",
TabFeatures: "resource:///modules/TabFeatures.sys.mjs", TabFeatures: "resource:///modules/TabFeatures.sys.mjs",
setTimeout: "resource://gre/modules/Timer.sys.mjs",
UICustomizations: "resource:///modules/UICustomizations.sys.mjs", UICustomizations: "resource:///modules/UICustomizations.sys.mjs",
}); });
XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]); const WATERFOX_CUSTOMIZATIONS_PREF =
"browser.theme.enableWaterfoxCustomizations";
const WaterfoxGlue = { const WATERFOX_DEFAULT_THEMES = [
"default-theme@mozilla.org",
"firefox-compact-light@mozilla.org",
"firefox-compact-dark@mozilla.org",
"firefox-alpenglow@mozilla.org",
];
const WATERFOX_USERCHROME = "chrome://browser/skin/userChrome.css";
const WATERFOX_USERCONTENT = "chrome://browser/skin/userContent.css";
export const WaterfoxGlue = {
_addonManagersListeners: [], _addonManagersListeners: [],
stylesEnabled: false, stylesEnabled: false,
@@ -36,12 +39,25 @@ const WaterfoxGlue = {
// Set pref observers // Set pref observers
this._setPrefObservers(); this._setPrefObservers();
// Load always on Waterfox custom CSS. // Load always-on Waterfox custom CSS.
// Add additional CSS here. lazy.BrowserUtils.registerStylesheet(
BrowserUtils.registerStylesheet(
"chrome://browser/skin/waterfox/general.css" "chrome://browser/skin/waterfox/general.css"
); );
// Maybe load Waterfox stylesheets
(async () => {
let amInitialized = false;
while (!amInitialized) {
try {
const activeThemeId = await this.getActiveThemeId();
this.updateCustomStylesheets({ id: activeThemeId, type: "theme" });
amInitialized = true;
} catch (ex) {
await new Promise(res => lazy.setTimeout(res, 500, {}));
}
}
})();
// Parse chrome.manifest // Parse chrome.manifest
this.startupManifest = await this.getChromeManifest("startup"); this.startupManifest = await this.getChromeManifest("startup");
this.privateManifest = await this.getChromeManifest("private"); this.privateManifest = await this.getChromeManifest("private");
@@ -52,37 +68,26 @@ const WaterfoxGlue = {
Services.obs.addObserver(this, "main-pane-loaded"); Services.obs.addObserver(this, "main-pane-loaded");
// Observe final-ui-startup to launch browser window dependant tasks // Observe final-ui-startup to launch browser window dependant tasks
Services.obs.addObserver(this, "final-ui-startup"); Services.obs.addObserver(this, "final-ui-startup");
// Observe browser shutdown
Services.obs.addObserver(this, "quit-application-granted");
// Listen for addon events
this.addAddonListener();
}, },
async _setPrefObservers() { async _setPrefObservers() {
this.leptonListener = PrefUtils.addObserver( this.leptonListener = lazy.PrefUtils.addObserver(
"userChrome.theme.enable", WATERFOX_CUSTOMIZATIONS_PREF,
isEnabled => { async _ => {
// Pref being false means we need to unload the sheets. const activeThemeId = await this.getActiveThemeId();
const userChromeSheet = "chrome://browser/skin/userChrome.css"; this.updateCustomStylesheets({ id: activeThemeId, type: "theme" });
const userContentSheet = "chrome://browser/skin/userContent.css";
// Only register userContent globally
BrowserUtils.registerOrUnregisterSheet(userContentSheet, isEnabled);
// Attach or detach userChrome per-window
if (isEnabled) {
this.attachUserChromeToAllWindows(userChromeSheet);
this.stylesEnabled = true;
} else {
this.detachUserChromeFromAllWindows(userChromeSheet);
this.stylesEnabled = false;
}
} }
); );
this.pinnedTabListener = lazy.PrefUtils.addObserver(
// Keep the pinned tabs observer
this.pinnedTabListener = PrefUtils.addObserver(
"browser.tabs.pinnedIconOnly", "browser.tabs.pinnedIconOnly",
isEnabled => { isEnabled => {
// Pref being true actually means we need to unload the sheet, so invert. // Pref being true actually means we need to unload the sheet, so invert.
const uri = "chrome://browser/content/tabfeatures/pinnedtab.css"; const uri = "chrome://browser/content/tabfeatures/pinnedtab.css";
BrowserUtils.registerOrUnregisterSheet(uri, !isEnabled); lazy.BrowserUtils.registerOrUnregisterSheet(uri, !isEnabled);
} }
); );
}, },
@@ -105,7 +110,7 @@ const WaterfoxGlue = {
uri = "resource://waterfox/overlays/preferences-other.overlay"; uri = "resource://waterfox/overlays/preferences-other.overlay";
break; break;
} }
let chromeManifest = new ChromeManifest(async () => { let chromeManifest = new lazy.ChromeManifest(async () => {
let res = await fetch(uri); let res = await fetch(uri);
let text = await res.text(); let text = await res.text();
if (privateWindow) { if (privateWindow) {
@@ -140,25 +145,25 @@ const WaterfoxGlue = {
const window = subject.defaultView; const window = subject.defaultView;
// Do not load non-private overlays in private window // Do not load non-private overlays in private window
if (window.PrivateBrowsingUtils.isWindowPrivate(window)) { if (window.PrivateBrowsingUtils.isWindowPrivate(window)) {
Overlays.load(this.privateManifest, window); lazy.Overlays.load(this.privateManifest, window);
} else { } else {
Overlays.load(this.startupManifest, window); lazy.Overlays.load(this.startupManifest, window);
// Only load in non-private browser windows // Only load in non-private browser windows
PrivateTab.init(window); lazy.PrivateTab.init(window);
} }
// Load in all browser windows (private and normal) // Load in all browser windows (private and normal)
TabFeatures.init(window); lazy.TabFeatures.init(window);
StatusBar.init(window); lazy.StatusBar.init(window);
UICustomizations.init(window); lazy.UICustomizations.init(window);
// Attach userChrome.css to this chrome window if styles are enabled // Attach userChrome.css to this chrome window if styles are enabled
if (this.stylesEnabled) { if (this.stylesEnabled) {
try { try {
window.windowUtils.loadSheetUsingURIString( window.windowUtils.loadSheetUsingURIString(
"chrome://browser/skin/userChrome.css", WATERFOX_USERCHROME,
Ci.nsIStyleSheetService.USER_SHEET Ci.nsIStyleSheetService.USER_SHEET
); );
} catch (_) {} } catch (_e) {}
} }
} }
break; break;
@@ -169,7 +174,7 @@ const WaterfoxGlue = {
// exists before we attempt to load our overlay. If we are loading directly on privacy // exists before we attempt to load our overlay. If we are loading directly on privacy
// this exists before overlaying occurs, so we have no issues. Loading overlays on // this exists before overlaying occurs, so we have no issues. Loading overlays on
// #general is fine regardless of which pane we refresh/initially load. // #general is fine regardless of which pane we refresh/initially load.
await Overlays.load( await lazy.Overlays.load(
await this.getChromeManifest("preferences-general"), await this.getChromeManifest("preferences-general"),
subject subject
); );
@@ -178,14 +183,14 @@ const WaterfoxGlue = {
!subject.document.getElementById("homeContentsGroup") !subject.document.getElementById("homeContentsGroup")
) { ) {
subject.setTimeout(async () => { subject.setTimeout(async () => {
await Overlays.load( await lazy.Overlays.load(
await this.getChromeManifest("preferences-other"), await this.getChromeManifest("preferences-other"),
subject subject
); );
subject.privacyInitialized = true; subject.privacyInitialized = true;
}, 500); }, 500);
} else { } else {
await Overlays.load( await lazy.Overlays.load(
await this.getChromeManifest("preferences-other"), await this.getChromeManifest("preferences-other"),
subject subject
); );
@@ -196,6 +201,7 @@ const WaterfoxGlue = {
break; break;
case "final-ui-startup": case "final-ui-startup":
this._beforeUIStartup(); this._beforeUIStartup();
this._delayedTasks();
break; break;
} }
}, },
@@ -203,7 +209,7 @@ const WaterfoxGlue = {
async _beforeUIStartup() { async _beforeUIStartup() {
this._migrateUI(); this._migrateUI();
AddonManager.maybeInstallBuiltinAddon( lazy.AddonManager.maybeInstallBuiltinAddon(
"addonstores@waterfox.net", "addonstores@waterfox.net",
"1.0.0", "1.0.0",
"resource://builtin-addons/addonstores/" "resource://builtin-addons/addonstores/"
@@ -216,8 +222,13 @@ const WaterfoxGlue = {
128 128
); );
const waterfoxUIVersion = lazy.PrefUtils.get(
"browser.migration.waterfox_version",
0
);
async function enableTheme(id) { async function enableTheme(id) {
const addon = await AddonManager.getAddonByID(id); const addon = await lazy.AddonManager.getAddonByID(id);
// If we found it, enable it. // If we found it, enable it.
addon?.enable(); addon?.enable();
} }
@@ -239,37 +250,121 @@ const WaterfoxGlue = {
case "australis-dark@waterfox.net": case "australis-dark@waterfox.net":
enableTheme("firefox-compact-dark@mozilla.org"); enableTheme("firefox-compact-dark@mozilla.org");
break; break;
default:
enableTheme(DEFAULT_THEME);
} }
} else { } else {
// If no activeTheme detected, set default. // If no activeTheme detected, set default.
enableTheme(DEFAULT_THEME); enableTheme(DEFAULT_THEME);
} }
} }
if (waterfoxUIVersion < 1) {
const themeEnablePref = "userChrome.theme.enable";
const enabled = lazy.PrefUtils.get(themeEnablePref);
lazy.PrefUtils.set(WATERFOX_CUSTOMIZATIONS_PREF, enabled ? 1 : 2);
}
lazy.PrefUtils.set("browser.migration.waterfox_version", 1);
},
async _delayedTasks() {
let tasks = [
{
task: () => {
// Reset prefs
Services.prefs.clearUserPref(
"startup.homepage_welcome_url.additional"
);
Services.prefs.clearUserPref("startup.homepage_override_url");
},
},
];
for (const task of tasks) {
task.task();
}
},
async getActiveThemeId() {
// Try to get active theme from the pref
const activeThemeID = lazy.PrefUtils.get("extensions.activeThemeID", "");
if (activeThemeID) {
return activeThemeID;
}
// Otherwise just grab it from AddonManager
const themes = await lazy.AddonManager.getAddonsByTypes(["theme"]);
return themes.find(addon => addon.isActive).id;
},
addAddonListener() {
let listener = {
onInstalled: addon => this.updateCustomStylesheets(addon),
onEnabled: addon => this.updateCustomStylesheets(addon),
};
this._addonManagersListeners.push(listener);
lazy.AddonManager.addAddonListener(listener);
},
removeAddonListeners() {
for (let listener of this._addonManagersListeners) {
lazy.AddonManager.removeAddonListener(listener);
}
},
updateCustomStylesheets(addon) {
if (addon.type === "theme") {
// If any theme and WF on any theme, reload stylesheets for every theme enable.
// If WF theme and WF customisations, then reload stylesheets.
// If no customizations, unregister sheets for every theme enable.
if (
lazy.PrefUtils.get(WATERFOX_CUSTOMIZATIONS_PREF, 0) === 0 ||
(lazy.PrefUtils.get(WATERFOX_CUSTOMIZATIONS_PREF, 0) === 1 &&
WATERFOX_DEFAULT_THEMES.includes(addon.id))
) {
this.loadWaterfoxStylesheets();
} else {
this.unloadWaterfoxStylesheets();
}
}
}, },
// Attach userChrome.css to all open browser windows (per-window). // Attach userChrome.css to all open browser windows (per-window).
attachUserChromeToAllWindows(uri) { attachUserChromeToAllWindows() {
BrowserUtils.executeInAllWindows((win, sheetURI) => { lazy.BrowserUtils.executeInAllWindows((win, uri) => {
try { try {
win.windowUtils.loadSheetUsingURIString( win.windowUtils.loadSheetUsingURIString(
sheetURI, uri,
Ci.nsIStyleSheetService.USER_SHEET Ci.nsIStyleSheetService.USER_SHEET
); );
} catch (_) {} } catch (_e) {}
}, uri); }, WATERFOX_USERCHROME);
}, },
// Detach userChrome.css from all open browser windows. // Detach userChrome.css from all open browser windows.
detachUserChromeFromAllWindows(uri) { detachUserChromeFromAllWindows() {
BrowserUtils.executeInAllWindows((win, sheetURI) => { lazy.BrowserUtils.executeInAllWindows((win, uri) => {
try { try {
win.windowUtils.removeSheetUsingURIString( win.windowUtils.removeSheetUsingURIString(
sheetURI, uri,
Ci.nsIStyleSheetService.USER_SHEET Ci.nsIStyleSheetService.USER_SHEET
); );
} catch (_) {} } catch (_e) {}
}, uri); }, WATERFOX_USERCHROME);
},
loadWaterfoxStylesheets() {
// Register content sheet globally
lazy.BrowserUtils.registerStylesheet(WATERFOX_USERCONTENT);
// Attach chrome sheet to all current browser windows
this.attachUserChromeToAllWindows();
// Track enabled state so new windows can attach on open
this.stylesEnabled = true;
},
unloadWaterfoxStylesheets() {
// Detach chrome sheet from all windows
this.detachUserChromeFromAllWindows();
// Unregister content sheet globally
lazy.BrowserUtils.unregisterStylesheet(WATERFOX_USERCONTENT);
// Track disabled state so new windows don't attach on open
this.stylesEnabled = false;
}, },
}; };

View File

@@ -16,7 +16,7 @@ DIRS += [
] ]
EXTRA_JS_MODULES += [ EXTRA_JS_MODULES += [
"WaterfoxGlue.jsm", "WaterfoxGlue.sys.mjs",
] ]
JAR_MANIFESTS += ["jar.mn"] JAR_MANIFESTS += ["jar.mn"]