tor-browser

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

css-properties.js (6006B)


      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 http://mozilla.org/MPL/2.0/. */
      4 
      5 "use strict";
      6 
      7 const {
      8  FrontClassWithSpec,
      9  registerFront,
     10 } = require("resource://devtools/shared/protocol.js");
     11 const {
     12  cssPropertiesSpec,
     13 } = require("resource://devtools/shared/specs/css-properties.js");
     14 
     15 loader.lazyRequireGetter(
     16  this,
     17  "cssColors",
     18  "resource://devtools/shared/css/color-db.js",
     19  true
     20 );
     21 loader.lazyRequireGetter(
     22  this,
     23  "CSS_TYPES",
     24  "resource://devtools/shared/css/constants.js",
     25  true
     26 );
     27 loader.lazyRequireGetter(
     28  this,
     29  "isCssVariable",
     30  "resource://devtools/shared/inspector/css-logic.js",
     31  true
     32 );
     33 
     34 /**
     35 * The CssProperties front provides a mechanism to have a one-time asynchronous
     36 * load of a CSS properties database. This is then fed into the CssProperties
     37 * interface that provides synchronous methods for finding out what CSS
     38 * properties the current server supports.
     39 */
     40 class CssPropertiesFront extends FrontClassWithSpec(cssPropertiesSpec) {
     41  constructor(client, targetFront) {
     42    super(client, targetFront);
     43 
     44    // Attribute name from which to retrieve the actorID out of the target actor's form
     45    this.formAttributeName = "cssPropertiesActor";
     46  }
     47 
     48  async initialize() {
     49    const db = await super.getCSSDatabase();
     50    this.cssProperties = new CssProperties(normalizeCssData(db));
     51  }
     52 
     53  destroy() {
     54    this.cssProperties = null;
     55    super.destroy();
     56  }
     57 }
     58 
     59 /**
     60 * Ask questions to a CSS database. This class does not care how the database
     61 * gets loaded in, only the questions that you can ask to it.
     62 * Prototype functions are bound to 'this' so they can be passed around as helper
     63 * functions.
     64 *
     65 */
     66 class CssProperties {
     67  /**
     68   * @param {object} db
     69   *                 A database of CSS properties
     70   * @param {object} inheritedList
     71   *                 The key is the property name, the value is whether or not
     72   *                 that property is inherited.
     73   */
     74  constructor(db) {
     75    this.properties = db.properties;
     76 
     77    this.isKnown = this.isKnown.bind(this);
     78    this.isInherited = this.isInherited.bind(this);
     79    this.supportsType = this.supportsType.bind(this);
     80  }
     81  /**
     82   * Checks to see if the property is known by the browser. This function has
     83   * `this` already bound so that it can be passed around by reference.
     84   *
     85   * @param {string} property The property name to be checked.
     86   * @return {boolean}
     87   */
     88  isKnown(property) {
     89    // Custom Property Names (aka CSS Variables) are case-sensitive; do not lowercase.
     90    property = property.startsWith("--") ? property : property.toLowerCase();
     91    return !!this.properties[property] || isCssVariable(property);
     92  }
     93 
     94  /**
     95   * Checks to see if the property is an inherited one.
     96   *
     97   * @param {string} property The property name to be checked.
     98   * @return {boolean}
     99   */
    100  isInherited(property) {
    101    return this.properties[property]?.isInherited;
    102  }
    103 
    104  /**
    105   * Checks if the property supports the given CSS type.
    106   *
    107   * @param {string} property The property to be checked.
    108   * @param {string} type One of the values from InspectorPropertyType.
    109   * @return {boolean}
    110   */
    111  supportsType(property, type) {
    112    const id = CSS_TYPES[type];
    113    return (
    114      this.properties[property] &&
    115      (this.properties[property].supports.includes(type) ||
    116        this.properties[property].supports.includes(id))
    117    );
    118  }
    119 
    120  /**
    121   * Gets the CSS values for a given property name.
    122   *
    123   * @param {string} property The property to use.
    124   * @return {Array} An array of strings.
    125   */
    126  getValues(property) {
    127    return this.properties[property] ? this.properties[property].values : [];
    128  }
    129 
    130  /**
    131   * Gets the CSS property names.
    132   *
    133   * @return {Array} An array of strings.
    134   */
    135  getNames() {
    136    return Object.keys(this.properties);
    137  }
    138 
    139  /**
    140   * Return a list of subproperties for the given property.  If |name|
    141   * does not name a valid property, an empty array is returned.  If
    142   * the property is not a shorthand property, then array containing
    143   * just the property itself is returned.
    144   *
    145   * @param {string} name The property to query
    146   * @return {Array} An array of subproperty names.
    147   */
    148  getSubproperties(name) {
    149    // Custom Property Names (aka CSS Variables) are case-sensitive; do not lowercase.
    150    name = name.startsWith("--") ? name : name.toLowerCase();
    151    if (this.isKnown(name)) {
    152      if (this.properties[name] && this.properties[name].subproperties) {
    153        return this.properties[name].subproperties;
    154      }
    155      return [name];
    156    }
    157    return [];
    158  }
    159 }
    160 
    161 /**
    162 * Even if the target has the cssProperties actor, the returned data may not be in the
    163 * same shape or have all of the data we need. This normalizes the data and fills in
    164 * any missing information like color values.
    165 *
    166 * @return {object} The normalized CSS database.
    167 */
    168 function normalizeCssData(db) {
    169  // If there is a `from` attributes, it means that it comes from RDP
    170  // and it is not the client `generateCssProperties()` object passed by tests.
    171  if (typeof db.from == "string") {
    172    // This is where to put backward compat tweaks here to support old runtimes.
    173  }
    174 
    175  reattachCssColorValues(db);
    176 
    177  return db;
    178 }
    179 
    180 /**
    181 * Color values are omitted to save on space. Add them back here.
    182 *
    183 * @param {object} The CSS database.
    184 */
    185 function reattachCssColorValues(db) {
    186  if (db.properties.color.values[0] === "COLOR") {
    187    const colors = Object.keys(cssColors);
    188 
    189    for (const name in db.properties) {
    190      const property = db.properties[name];
    191      // "values" can be undefined if {name} was not found in CSS_PROPERTIES_DB.
    192      if (property.values && property.values[0] === "COLOR") {
    193        property.values.shift();
    194        property.values = property.values.concat(colors).sort();
    195      }
    196    }
    197  }
    198 }
    199 
    200 module.exports = {
    201  CssPropertiesFront,
    202  CssProperties,
    203  normalizeCssData,
    204 };
    205 registerFront(CssPropertiesFront);