forked from mirrors/gecko-dev
163 lines
4.2 KiB
JavaScript
163 lines
4.2 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";
|
|
|
|
/* globals browser, module */
|
|
|
|
class Injections {
|
|
constructor(availableInjections, customFunctions) {
|
|
this.INJECTION_PREF = "perform_injections";
|
|
|
|
this._injectionsEnabled = true;
|
|
|
|
this._availableInjections = availableInjections;
|
|
this._activeInjections = new Map();
|
|
this._customFunctions = customFunctions;
|
|
}
|
|
|
|
bindAboutCompatBroker(broker) {
|
|
this._aboutCompatBroker = broker;
|
|
}
|
|
|
|
bootup() {
|
|
browser.aboutConfigPrefs.onPrefChange.addListener(() => {
|
|
this.checkInjectionPref();
|
|
}, this.INJECTION_PREF);
|
|
this.checkInjectionPref();
|
|
}
|
|
|
|
checkInjectionPref() {
|
|
browser.aboutConfigPrefs.getPref(this.INJECTION_PREF).then(value => {
|
|
if (value === undefined) {
|
|
browser.aboutConfigPrefs.setPref(this.INJECTION_PREF, true);
|
|
} else if (value === false) {
|
|
this.unregisterContentScripts();
|
|
} else {
|
|
this.registerContentScripts();
|
|
}
|
|
});
|
|
}
|
|
|
|
getAvailableInjections() {
|
|
return this._availableInjections;
|
|
}
|
|
|
|
isEnabled() {
|
|
return this._injectionsEnabled;
|
|
}
|
|
|
|
async registerContentScripts() {
|
|
const platformMatches = ["all"];
|
|
let platformInfo = await browser.runtime.getPlatformInfo();
|
|
platformMatches.push(platformInfo.os == "android" ? "android" : "desktop");
|
|
|
|
for (const injection of this._availableInjections) {
|
|
if (platformMatches.includes(injection.platform)) {
|
|
injection.availableOnPlatform = true;
|
|
await this.enableInjection(injection);
|
|
}
|
|
}
|
|
|
|
this._injectionsEnabled = true;
|
|
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
|
|
interventionsChanged: this._aboutCompatBroker.filterOverrides(
|
|
this._availableInjections
|
|
),
|
|
});
|
|
}
|
|
|
|
assignContentScriptDefaults(contentScripts) {
|
|
let finalConfig = Object.assign({}, contentScripts);
|
|
|
|
if (!finalConfig.runAt) {
|
|
finalConfig.runAt = "document_start";
|
|
}
|
|
|
|
return finalConfig;
|
|
}
|
|
|
|
async enableInjection(injection) {
|
|
if (injection.active) {
|
|
return undefined;
|
|
}
|
|
|
|
if (injection.customFunc) {
|
|
return this.enableCustomInjection(injection);
|
|
}
|
|
|
|
return this.enableContentScripts(injection);
|
|
}
|
|
|
|
enableCustomInjection(injection) {
|
|
if (injection.customFunc in this._customFunctions) {
|
|
this._customFunctions[injection.customFunc](injection);
|
|
injection.active = true;
|
|
} else {
|
|
console.error(
|
|
`Provided function ${injection.customFunc} wasn't found in functions list`
|
|
);
|
|
}
|
|
}
|
|
|
|
async enableContentScripts(injection) {
|
|
try {
|
|
const handle = await browser.contentScripts.register(
|
|
this.assignContentScriptDefaults(injection.contentScripts)
|
|
);
|
|
this._activeInjections.set(injection, handle);
|
|
injection.active = true;
|
|
} catch (ex) {
|
|
console.error(
|
|
"Registering WebCompat GoFaster content scripts failed: ",
|
|
ex
|
|
);
|
|
}
|
|
}
|
|
|
|
unregisterContentScripts() {
|
|
for (const injection of this._availableInjections) {
|
|
this.disableInjection(injection);
|
|
}
|
|
|
|
this._injectionsEnabled = false;
|
|
this._aboutCompatBroker.portsToAboutCompatTabs.broadcast({
|
|
interventionsChanged: false,
|
|
});
|
|
}
|
|
|
|
async disableInjection(injection) {
|
|
if (!injection.active) {
|
|
return undefined;
|
|
}
|
|
|
|
if (injection.customFunc) {
|
|
return this.disableCustomInjections(injection);
|
|
}
|
|
|
|
return this.disableContentScripts(injection);
|
|
}
|
|
|
|
disableCustomInjections(injection) {
|
|
const disableFunc = injection.customFunc + "Disable";
|
|
|
|
if (disableFunc in this._customFunctions) {
|
|
this._customFunctions[disableFunc](injection);
|
|
injection.active = false;
|
|
} else {
|
|
console.error(
|
|
`Provided function ${disableFunc} for disabling injection wasn't found in functions list`
|
|
);
|
|
}
|
|
}
|
|
|
|
async disableContentScripts(injection) {
|
|
const contentScript = this._activeInjections.get(injection);
|
|
await contentScript.unregister();
|
|
this._activeInjections.delete(injection);
|
|
injection.active = false;
|
|
}
|
|
}
|
|
|
|
module.exports = Injections;
|