/webext-options-sync-per-domain

Helps you manage and autosave your extension's options, separately for each additional permission

Primary LanguageTypeScriptMIT LicenseMIT

webext-options-sync-per-domain

Helps you manage and autosave your extension's options, separately for each additional permission.

Prerequisites

  • Your WebExtension’s options are managed by webext-options-sync
  • Your WebExtension can be enabled on multiple optional domains, maybe via webext-dynamic-content-scripts
  • Your users want to customize your extension’s options for each domain, independently.

In that case, webext-options-sync-per-domain extends webext-options-sync with these feature:

  • Automatically detects new origin permissions
  • Prepares a fresh set of options for each new origin
  • Transparently serves the right set of options based on the current domain
  • Adds a domain switcher on the options page — only if the user adds multiple origins

Install

You can download the standalone bundle and include it in your manifest.json.

Or use npm:

npm install webext-options-sync-per-domain
npm remove  webext-options-sync # This is now included

Usage

If you're following the suggested setup for webext-options-sync, here are the changes you should make:

Before After
// options-storage.js
import OptionsSync from 'webext-options-sync';
export default new OptionsSync({defaults, migrations});
// options-storage.js
import OptionsSyncPerDomain from 'webext-options-sync-per-domain';
export const perDomainOptions = new OptionsSyncPerDomain({defaults, migrations});
export default perDomainOptions.getOptionsForOrigin();

Now options-storage.js will export the same old OptionsSync instance, but it will very depending on the current domain.

You'll also need to change 2 lines on the options page:

Before After
// options.js in options.html
import optionsStorage from './options-storage';
optionsStorage.syncForm('form');
// options.js in options.html
import {perDomainOptions} from './options-storage';
perDomainOptions.syncForm('form');

That's all! A domain switcher will only appear if the user adds new additional domains via chrome.permissions.request() or webext-permission-toggle.

Concepts

Origins

Origins are what the browser calls each "website" permission; they look like https://example.com or https://*.example.com/*

Domains

Domains are the same as origins, except it's a less ambiguous word and it's generally shown protocol-less: example.com or *.example.com

Default

webext-options-sync-per-domain differentiates between origins that are part of manifest.json and origins added later via chrome.permission.request(). All manifest.json origins share the same options and these are considered the "default".

API

const perDomainOptions = new OptionsSyncPerDomain(setup?)

setup

This is identical to the setup in webext-options-sync

perDomainOptions.syncForm(form)

This is identical to syncForm() in webext-options-sync, but it will also:

  • add a domain selector dropdown if the user enabled the extension on more origins
  • switch the data of the form depending on the selected domain

If you want to customize the switcher or listen to its change, await this call and perform the changes after it runs. Example:

// options.js
import {perDomainOptions} from './options-storage';

async initOptions() {
	await perDomainOptions.syncForm('form');

	// Update domain-dependent page content when the domain is changed
	const dropdown = document.querySelector('.OptionsSyncPerDomain-picker select');
	if (dropdown) {
		dropdown.addEventListener('change', () => {
			select('#personal-token-link')!.host = dropdown.value === 'default' ? 'github.com' : dropdown.value;
		});
	}
}

initOptions();

perDomainOptions.getOptionsForOrigin(origin?)

Returns an origin-specific instance of OptionsSync. If called from an extension page (background.js, options.html, etc) and without the parameter, it will use the default origin.

origin

Type: string
Default: location.origin
Example: http://example.com

perDomainOptions.getAllOrigins()

Returns a Map of the OptionsSync instances, one for each origin. The default origins are on the key default and the other ones are on keys that look like domain.ext

const instances = perDomainOptions.getAllOrigins();

// Print the options of these 2 instances
console.log(await instances.get('default').getAll());
console.log(await instances.get('example.com').getAll());

Related

License

MIT © Federico Brigante