98 lines
2.1 KiB
JavaScript
98 lines
2.1 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";
|
|
|
|
const EXPORTED_SYMBOLS = ["SharedDataMap"];
|
|
|
|
const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
|
ChromeUtils.defineModuleGetter(
|
|
this,
|
|
"PromiseUtils",
|
|
"resource://gre/modules/PromiseUtils.jsm"
|
|
);
|
|
|
|
const IS_MAIN_PROCESS =
|
|
Services.appinfo.processType === Services.appinfo.PROCESS_TYPE_DEFAULT;
|
|
|
|
class SharedDataMap {
|
|
constructor(sharedDataKey) {
|
|
this._sharedDataKey = sharedDataKey;
|
|
this._isParent = IS_MAIN_PROCESS;
|
|
this._isReady = this.isParent;
|
|
this._readyDeferred = PromiseUtils.defer();
|
|
this._map = null;
|
|
|
|
if (this.isParent) {
|
|
this._map = new Map();
|
|
this._syncToChildren({ flush: true });
|
|
this._checkIfReady();
|
|
} else {
|
|
this._syncFromParent();
|
|
Services.cpmm.sharedData.addEventListener("change", this);
|
|
}
|
|
}
|
|
|
|
get sharedDataKey() {
|
|
return this._sharedDataKey;
|
|
}
|
|
|
|
get isParent() {
|
|
return this._isParent;
|
|
}
|
|
|
|
ready() {
|
|
return this._readyDeferred.promise;
|
|
}
|
|
|
|
get(key) {
|
|
return this._map.get(key);
|
|
}
|
|
|
|
set(key, value) {
|
|
if (!this.isParent) {
|
|
throw new Error(
|
|
"Setting values from within a content process is not allowed"
|
|
);
|
|
}
|
|
this._map.set(key, value);
|
|
this._syncToChildren();
|
|
}
|
|
|
|
has(key) {
|
|
return this._map.has(key);
|
|
}
|
|
|
|
toObject() {
|
|
return Object.fromEntries(this._map);
|
|
}
|
|
|
|
_syncToChildren({ flush = false } = {}) {
|
|
Services.ppmm.sharedData.set(this.sharedDataKey, this._map);
|
|
if (flush) {
|
|
Services.ppmm.sharedData.flush();
|
|
}
|
|
}
|
|
|
|
_syncFromParent() {
|
|
this._map = Services.cpmm.sharedData.get(this.sharedDataKey);
|
|
this._checkIfReady();
|
|
}
|
|
|
|
_checkIfReady() {
|
|
if (!this._isReady && this._map) {
|
|
this._isReady = true;
|
|
this._readyDeferred.resolve();
|
|
}
|
|
}
|
|
|
|
handleEvent(event) {
|
|
if (event.type === "change") {
|
|
if (event.changedKeys.includes(this.sharedDataKey)) {
|
|
this._syncFromParent();
|
|
}
|
|
}
|
|
}
|
|
}
|