tor-browser

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

font-utils.js (3323B)


      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 module.exports = {
      8  /**
      9   * Given a CSS unit type, get the amount by which to increment a numeric value.
     10   * Used as the step attribute in inputs of type "range" or "number".
     11   *
     12   * @param {string} unit
     13   *        CSS unit type (px, %, em, rem, vh, vw, ...)
     14   * @return {number}
     15   *         Amount by which to increment.
     16   */
     17  getStepForUnit(unit) {
     18    let step;
     19    switch (unit) {
     20      case "":
     21      case "em":
     22      case "rem":
     23      case "vw":
     24      case "vh":
     25      case "vmin":
     26      case "vmax":
     27        step = 0.1;
     28        break;
     29      default:
     30        step = 1;
     31    }
     32 
     33    return step;
     34  },
     35 
     36  /**
     37   * Get the unit type from the end of a CSS value string.
     38   * Returns null for non-string input or unitless values.
     39   *
     40   * @param {string} value
     41   *        CSS value string.
     42   * @return {string | null}
     43   *         CSS unit type, like "px", "em", "rem", etc or null.
     44   */
     45  getUnitFromValue(value) {
     46    if (typeof value !== "string" || isNaN(parseFloat(value))) {
     47      return null;
     48    }
     49 
     50    const match = value.match(/\D+?$/);
     51    return match?.length ? match[0] : null;
     52  },
     53 
     54  /**
     55   * Parse the string value of CSS font-variation-settings into an object with
     56   * axis tag names and corresponding values. If the string is a keyword or does not
     57   * contain axes, return an empty object.
     58   *
     59   * @param {string} string
     60   *        Value of font-variation-settings property coming from node's computed style.
     61   *        Its contents are expected to be stable having been already parsed by the
     62   *        browser.
     63   * @return {object}
     64   */
     65  parseFontVariationAxes(string) {
     66    let axes = {};
     67    const keywords = ["initial", "normal", "inherit", "unset"];
     68 
     69    if (!string || keywords.includes(string.trim())) {
     70      return axes;
     71    }
     72 
     73    // Parse font-variation-settings CSS declaration into an object
     74    // with axis tags as keys and axis values as values.
     75    axes = string.split(",").reduce((acc, pair) => {
     76      // Tags are always in quotes. Split by quote and filter excessive whitespace.
     77      pair = pair.split(/["']/).filter(part => part.trim() !== "");
     78      // Guard against malformed input that may have slipped through.
     79      if (pair.length === 0) {
     80        return acc;
     81      }
     82 
     83      const tag = pair[0];
     84      const value = pair[1].trim();
     85      // Axis tags shorter or longer than 4 characters are invalid. Whitespace is valid.
     86      if (tag.length === 4) {
     87        acc[tag] = parseFloat(value);
     88      }
     89      return acc;
     90    }, {});
     91 
     92    return axes;
     93  },
     94 
     95  /**
     96   * Limit the decimal count of a number. Unlike Number.toFixed(),
     97   * this function does not pad with extra zeros. If the input is not a number,
     98   * the function throws an error.
     99   *
    100   * @param {number} number
    101   * @param {number} decimals
    102   *        Decimal count in the output number. Default to one decimal.
    103   * @return {number}
    104   */
    105  toFixed(number, decimals = 1) {
    106    if (typeof number !== "number") {
    107      throw new Error(`Input: "${number}" is not a number.`);
    108    }
    109 
    110    return Math.floor(number * Math.pow(10, decimals)) / Math.pow(10, decimals);
    111  },
    112 };