import OptionsSync from 'webext-options-sync'; import {isBackgroundPage} from 'webext-detect-page'; import {getAdditionalPermissions} from 'webext-additional-permissions'; export interface RGHOptions { customCSS: string; personalToken: string; logging: boolean; minimizedUsers: string; [featureName: string]: string | boolean; } function featureWasRenamed(from: string, to: string): any { // TODO: any should probably be `Migration` after `webext-options-sync`'s types are fixed return (options: RGHOptions) => { if (typeof options[`feature:${from}`] === 'boolean') { options[`feature:${to}`] = options[`feature:${from}`]; } }; } const defaults: RGHOptions = { customCSS: '', personalToken: '', logging: false, minimizedUsers: '' }; // This variable is replaced at build time with the list for (const feature of __featuresList__) { defaults[`feature:${feature}`] = true; } const migrations = [ featureWasRenamed('make-discussion-sidebar-sticky', 'sticky-discussion-sidebar'), // Merged on August 1st // Removed features will be automatically removed from the options as well OptionsSync.migrations.removeUnused ]; // Keep this function "dumb". Don't move more "smart" domain selection logic in here function getStorageName(host: string): string { if (/(^|\.)github\.com$/.test(host)) { return 'options'; } return `options-${host}`; } function getOptions(host: string): OptionsSync { return new OptionsSync({storageName: getStorageName(host), migrations, defaults}); } // This should return the options for the current domain or, if called from an extension page, for `github.com` export default getOptions(location.protocol.startsWith('http') ? location.host : 'github.com'); export async function getAllOptions(): Promise>> { const optionsByDomain = new Map>(); optionsByDomain.set('github.com', getOptions('github.com')); const {origins} = await getAdditionalPermissions(); for (const origin of origins) { const {host} = new URL(origin); optionsByDomain.set(host, getOptions(host)); } return optionsByDomain; } async function initializeAllOptions(): Promise { // Run migrations for every domain const {origins} = await getAdditionalPermissions(); for (const origin of origins) { getOptions(new URL(origin).host); } // Add new domains browser.permissions.onAdded!.addListener(({origins}) => { if (origins) { for (const origin of origins) { getOptions(new URL(origin).host); } } }); // Remove old domains browser.permissions.onRemoved!.addListener(({origins}) => { if (origins) { const optionKeysToRemove = origins.map(origin => getStorageName(new URL(origin).host)); browser.storage.sync.remove(optionKeysToRemove); } }); } if (isBackgroundPage()) { initializeAllOptions(); }