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;
 | 
