tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }