Merge pull request #14665 from Snuffleupagus/Preferences-private

Convert the `BasePreferences` class to use private fields
This commit is contained in:
Tim van der Meij 2022-03-13 20:45:29 +01:00 committed by GitHub
commit dd4af1c60d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 34 deletions

View File

@ -21,8 +21,7 @@ import { GenericScripting } from "./generic_scripting.js";
if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("GENERIC")) { if (typeof PDFJSDev !== "undefined" && !PDFJSDev.test("GENERIC")) {
throw new Error( throw new Error(
'Module "pdfjs-web/genericcom" shall not be used outside ' + 'Module "pdfjs-web/genericcom" shall not be used outside GENERIC build.'
"GENERIC build."
); );
} }

View File

@ -21,29 +21,36 @@ import { AppOptions, OptionKind } from "./app_options.js";
* or every time the viewer is loaded. * or every time the viewer is loaded.
*/ */
class BasePreferences { class BasePreferences {
#defaults = Object.freeze(
typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")
? AppOptions.getAll(OptionKind.PREFERENCE)
: PDFJSDev.eval("DEFAULT_PREFERENCES")
);
#prefs = Object.create(null);
#initializedPromise = null;
constructor() { constructor() {
if (this.constructor === BasePreferences) { if (this.constructor === BasePreferences) {
throw new Error("Cannot initialize BasePreferences."); throw new Error("Cannot initialize BasePreferences.");
} }
Object.defineProperty(this, "defaults", {
value: Object.freeze(
typeof PDFJSDev === "undefined" || !PDFJSDev.test("PRODUCTION")
? AppOptions.getAll(OptionKind.PREFERENCE)
: PDFJSDev.eval("DEFAULT_PREFERENCES")
),
writable: false,
enumerable: true,
configurable: false,
});
this.prefs = Object.create(null);
this._initializedPromise = this._readFromStorage(this.defaults).then( if (typeof PDFJSDev !== "undefined" && PDFJSDev.test("CHROME")) {
Object.defineProperty(this, "defaults", {
get() {
return this.#defaults;
},
});
}
this.#initializedPromise = this._readFromStorage(this.#defaults).then(
prefs => { prefs => {
for (const name in this.defaults) { for (const name in this.#defaults) {
const prefValue = prefs?.[name]; const prefValue = prefs?.[name];
// Ignore preferences whose types don't match the default values. // Ignore preferences whose types don't match the default values.
if (typeof prefValue === typeof this.defaults[name]) { if (typeof prefValue === typeof this.#defaults[name]) {
this.prefs[name] = prefValue; this.#prefs[name] = prefValue;
} }
} }
} }
@ -76,9 +83,15 @@ class BasePreferences {
* have been reset. * have been reset.
*/ */
async reset() { async reset() {
await this._initializedPromise; await this.#initializedPromise;
this.prefs = Object.create(null); const prefs = this.#prefs;
return this._writeToStorage(this.defaults);
this.#prefs = Object.create(null);
return this._writeToStorage(this.#defaults).catch(reason => {
// Revert all preference values, since writing to storage failed.
this.#prefs = prefs;
throw reason;
});
} }
/** /**
@ -89,16 +102,17 @@ class BasePreferences {
* provided that the preference exists and the types match. * provided that the preference exists and the types match.
*/ */
async set(name, value) { async set(name, value) {
await this._initializedPromise; await this.#initializedPromise;
const defaultValue = this.defaults[name]; const defaultValue = this.#defaults[name],
prefs = this.#prefs;
if (defaultValue === undefined) { if (defaultValue === undefined) {
throw new Error(`Set preference: "${name}" is undefined.`); throw new Error(`Set preference: "${name}" is undefined.`);
} else if (value === undefined) { } else if (value === undefined) {
throw new Error("Set preference: no value is specified."); throw new Error("Set preference: no value is specified.");
} }
const valueType = typeof value; const valueType = typeof value,
const defaultType = typeof defaultValue; defaultType = typeof defaultValue;
if (valueType !== defaultType) { if (valueType !== defaultType) {
if (valueType === "number" && defaultType === "string") { if (valueType === "number" && defaultType === "string") {
@ -113,8 +127,13 @@ class BasePreferences {
throw new Error(`Set preference: "${value}" must be an integer.`); throw new Error(`Set preference: "${value}" must be an integer.`);
} }
} }
this.prefs[name] = value;
return this._writeToStorage(this.prefs); this.#prefs[name] = value;
return this._writeToStorage(this.#prefs).catch(reason => {
// Revert all preference values, since writing to storage failed.
this.#prefs = prefs;
throw reason;
});
} }
/** /**
@ -124,14 +143,13 @@ class BasePreferences {
* containing the value of the preference. * containing the value of the preference.
*/ */
async get(name) { async get(name) {
await this._initializedPromise; await this.#initializedPromise;
const defaultValue = this.defaults[name], const defaultValue = this.#defaults[name];
prefValue = this.prefs[name];
if (defaultValue === undefined) { if (defaultValue === undefined) {
throw new Error(`Get preference: "${name}" is undefined.`); throw new Error(`Get preference: "${name}" is undefined.`);
} }
return prefValue !== undefined ? prefValue : defaultValue; return this.#prefs[name] ?? defaultValue;
} }
/** /**
@ -140,12 +158,11 @@ class BasePreferences {
* the values of all preferences. * the values of all preferences.
*/ */
async getAll() { async getAll() {
await this._initializedPromise; await this.#initializedPromise;
const obj = Object.create(null); const obj = Object.create(null);
for (const name in this.defaults) { for (const name in this.#defaults) {
const prefValue = this.prefs[name]; obj[name] = this.#prefs[name] ?? this.#defaults[name];
obj[name] = prefValue !== undefined ? prefValue : this.defaults[name];
} }
return obj; return obj;
} }