Skip to content

Commit

Permalink
Add stopFormSync
Browse files Browse the repository at this point in the history
  • Loading branch information
fregante committed Jul 31, 2019
1 parent 74bb0a3 commit 34650a2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 10 deletions.
38 changes: 28 additions & 10 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class OptionsSync<TOptions extends Options> {
}: Setup<TOptions> = {}) {
this.storageName = storageName;
this.defaults = defaults;
this._handleFormInput = debounce(600, this._handleFormInput.bind(this));

if (logging === false) {
this._log = () => {};
Expand Down Expand Up @@ -169,20 +170,27 @@ class OptionsSync<TOptions extends Options> {
form :
document.querySelector<HTMLFormElement>(form)!;

element.addEventListener('input', debounce(600, this._handleFormInput.bind(this)));
chrome.storage.onChanged.addListener((changes, namespace) => {
if (
namespace === 'sync' &&
changes[this.storageName] &&
!element.contains(document.activeElement) // Avoid applying changes while the user is editing a field
) {
deserialize(element, changes[this.storageName].newValue);
}
});
element.addEventListener('input', this._handleFormInput);
chrome.storage.onChanged.addListener(this._handleStorageChangeOnForm.bind(this, element));

deserialize(element, await this.getAll());
}

/**
Removes any listeners added by `syncForm`
@param selector - The `<form>` that needs to be unsynchronized or a CSS selector (one element).
The form fields' `name` attributes will have to match the option names.
*/
async stopSyncForm(form: string | HTMLFormElement): Promise<void> {
const element = form instanceof HTMLFormElement ?
form :
document.querySelector<HTMLFormElement>(form)!;

element.removeEventListener('input', this._handleFormInput);
chrome.storage.onChanged.removeListener(this._handleStorageChangeOnForm.bind(this, element));
}

private _log(method: keyof Console, ...args: any[]): void {
console[method](...args);
}
Expand Down Expand Up @@ -214,6 +222,16 @@ class OptionsSync<TOptions extends Options> {
bubbles: true
}));
}

private _handleStorageChangeOnForm(form: HTMLFormElement, changes: Record<string, any>, areaName: string): void {
if (
areaName === 'sync' &&
changes[this.storageName] &&
!form.contains(document.activeElement) // Avoid applying changes while the user is editing a field
) {
deserialize(form, changes[this.storageName].newValue);
}
}
}

export default OptionsSync;
4 changes: 4 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,10 @@ Type: `HTMLFormElement`, `string`

It's the `<form>` that needs to be synchronized or a CSS selector (one element). The form fields' `name` attributes will have to match the option names.

#### opts.stopSyncForm(form)

Removes any listeners added by `syncForm`.

## Related

* [webext-storage-cache](https://github.com/fregante/webext-storage-cache) - Map-like promised cache storage with expiration.
Expand Down

0 comments on commit 34650a2

Please sign in to comment.