blob: 991afa501f6fcf307dacf8b02e5ea0e9999a0098 [file] [log] [blame]
import StylesheetManager from '../../../StylesheetManager';
import { StylesheetAttributes } from '../../../contentScriptsUtils';
import OptionsProvider from '../../../options/OptionsProvider';
import DependenciesProviderSingleton, {
OptionsProviderDependency,
} from '../../dependenciesProvider/DependenciesProvider';
import Script, { ScriptEnvironment, ScriptRunPhase } from '../Script';
/**
* Script which injects a stylesheet depending on a set condition. It
* dynamically reevaluates the condition when the options configuration changes.
*/
export default abstract class StylesheetScript extends Script {
readonly environment = ScriptEnvironment.ContentScript;
readonly runPhase = ScriptRunPhase.Start;
/**
* Relative path to the stylesheet from the extension root.
*/
abstract readonly stylesheet: string;
/**
* Attributes to include in the injected <link> element.
*/
readonly attributes: StylesheetAttributes = {};
protected optionsProvider: OptionsProvider;
private stylesheetManager: StylesheetManager;
constructor() {
super();
const dependenciesProvider = DependenciesProviderSingleton.getInstance();
this.optionsProvider = dependenciesProvider.getDependency(
OptionsProviderDependency,
);
}
/**
* Condition which decides whether the stylesheet should be injected or not.
*
* @returns {boolean} Whether the stylesheet should be injected.
*/
abstract shouldBeInjected(): Promise<boolean>;
execute() {
this.stylesheetManager = new StylesheetManager(
this.stylesheet,
this.attributes,
);
this.optionsProvider.addListener(this.evaluateInjection.bind(this));
this.evaluateInjection();
}
async evaluateInjection() {
const shouldBeInjected = await this.shouldBeInjected();
if (!this.stylesheetManager.isInjected() && shouldBeInjected) {
this.stylesheetManager.inject();
}
if (this.stylesheetManager.isInjected() && !shouldBeInjected) {
this.stylesheetManager.remove();
}
}
}