diff options
Diffstat (limited to 'dom/manifest/ValueExtractor.sys.mjs')
-rw-r--r-- | dom/manifest/ValueExtractor.sys.mjs | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/dom/manifest/ValueExtractor.sys.mjs b/dom/manifest/ValueExtractor.sys.mjs new file mode 100644 index 0000000000..d08cd24e1c --- /dev/null +++ b/dom/manifest/ValueExtractor.sys.mjs @@ -0,0 +1,97 @@ +/* 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 https://mozilla.org/MPL/2.0/. */ +/* + * Helper functions extract values from manifest members + * and reports conformance errors. + */ + +export class ValueExtractor { + constructor(errors, aBundle) { + this.errors = errors; + this.domBundle = aBundle; + } + + /** + * @param options + * The 'spec' object. + * @note This function takes a 'spec' object and destructures it to extract + * a value. If the value is of the wrong type, it warns the developer + * and returns undefined. + * expectedType: is the type of a JS primitive (string, number, etc.) + * object: is the object from which to extract the value. + * objectName: string used to construct the developer warning. + * property: the name of the property being extracted. + * throwTypeError: boolean, throw a TypeError if the type is incorrect. + * trim: boolean, if the value should be trimmed (used by string type). + */ + extractValue(options) { + const { expectedType, object, objectName, property, throwTypeError, trim } = + options; + const value = object[property]; + const isArray = Array.isArray(value); + + // We need to special-case "array", as it's not a JS primitive. + const type = isArray ? "array" : typeof value; + if (type !== expectedType) { + if (type !== "undefined") { + const warn = this.domBundle.formatStringFromName( + "ManifestInvalidType", + [objectName, property, expectedType] + ); + this.errors.push({ warn }); + if (throwTypeError) { + throw new TypeError(warn); + } + } + return undefined; + } + + // Trim string and returned undefined if the empty string. + const shouldTrim = expectedType === "string" && value && trim; + if (shouldTrim) { + return value.trim() || undefined; + } + return value; + } + + extractColorValue(spec) { + const value = this.extractValue(spec); + let color; + if (InspectorUtils.isValidCSSColor(value)) { + const rgba = InspectorUtils.colorToRGBA(value); + color = + "#" + + rgba.r.toString(16).padStart(2, "0") + + rgba.g.toString(16).padStart(2, "0") + + rgba.b.toString(16).padStart(2, "0") + + Math.round(rgba.a * 255) + .toString(16) + .padStart(2, "0"); + } else if (value) { + const warn = this.domBundle.formatStringFromName( + "ManifestInvalidCSSColor", + [spec.property, value] + ); + this.errors.push({ warn }); + } + return color; + } + + extractLanguageValue(spec) { + let langTag; + const value = this.extractValue(spec); + if (value !== undefined) { + try { + langTag = Intl.getCanonicalLocales(value)[0]; + } catch (err) { + const warn = this.domBundle.formatStringFromName( + "ManifestLangIsInvalid", + [spec.property, value] + ); + this.errors.push({ warn }); + } + } + return langTag; + } +} |