ValueExtractor.sys.mjs (3123B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ 4 /* 5 * Helper functions extract values from manifest members 6 * and reports conformance errors. 7 */ 8 9 export class ValueExtractor { 10 constructor(errors, aBundle) { 11 this.errors = errors; 12 this.domBundle = aBundle; 13 } 14 15 /** 16 * @param options 17 * The 'spec' object. 18 * Note: This function takes a 'spec' object and destructures it to extract 19 * a value. If the value is of the wrong type, it warns the developer 20 * and returns undefined. 21 * expectedType: is the type of a JS primitive (string, number, etc.) 22 * object: is the object from which to extract the value. 23 * objectName: string used to construct the developer warning. 24 * property: the name of the property being extracted. 25 * throwTypeError: boolean, throw a TypeError if the type is incorrect. 26 * trim: boolean, if the value should be trimmed (used by string type). 27 */ 28 extractValue(options) { 29 const { expectedType, object, objectName, property, throwTypeError, trim } = 30 options; 31 const value = object[property]; 32 const isArray = Array.isArray(value); 33 34 // We need to special-case "array", as it's not a JS primitive. 35 const type = isArray ? "array" : typeof value; 36 if (type !== expectedType) { 37 if (type !== "undefined") { 38 const warn = this.domBundle.formatStringFromName( 39 "ManifestInvalidType", 40 [objectName, property, expectedType] 41 ); 42 this.errors.push({ warn }); 43 if (throwTypeError) { 44 throw new TypeError(warn); 45 } 46 } 47 return undefined; 48 } 49 50 // Trim string and returned undefined if the empty string. 51 const shouldTrim = expectedType === "string" && value && trim; 52 if (shouldTrim) { 53 return value.trim() || undefined; 54 } 55 return value; 56 } 57 58 extractColorValue(spec) { 59 const value = this.extractValue(spec); 60 let color; 61 if (InspectorUtils.isValidCSSColor(value)) { 62 const rgba = InspectorUtils.colorToRGBA(value); 63 color = 64 "#" + 65 rgba.r.toString(16).padStart(2, "0") + 66 rgba.g.toString(16).padStart(2, "0") + 67 rgba.b.toString(16).padStart(2, "0") + 68 Math.round(rgba.a * 255) 69 .toString(16) 70 .padStart(2, "0"); 71 } else if (value) { 72 const warn = this.domBundle.formatStringFromName( 73 "ManifestInvalidCSSColor", 74 [spec.property, value] 75 ); 76 this.errors.push({ warn }); 77 } 78 return color; 79 } 80 81 extractLanguageValue(spec) { 82 let langTag; 83 const value = this.extractValue(spec); 84 if (value !== undefined) { 85 try { 86 langTag = Intl.getCanonicalLocales(value)[0]; 87 } catch (err) { 88 const warn = this.domBundle.formatStringFromName( 89 "ManifestLangIsInvalid", 90 [spec.property, value] 91 ); 92 this.errors.push({ warn }); 93 } 94 } 95 return langTag; 96 } 97 }