tor-browser

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

UnitConverterTemperature.sys.mjs (3276B)


      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 import { UrlbarUtils } from "moz-src:///browser/components/urlbar/UrlbarUtils.sys.mjs";
      6 
      7 const ABSOLUTE = ["celsius", "kelvin", "fahrenheit"];
      8 const ALIAS = ["c", "k", "f"];
      9 const UNITS = [...ABSOLUTE, ...ALIAS];
     10 
     11 const NUMBER_REGEX = "-?\\d+(?:\\.\\d+)?\\s*";
     12 const UNIT_REGEX = "\\w+";
     13 
     14 // NOTE: This regex need to be localized upon supporting multi locales
     15 //       since it supports en-US input format only.
     16 const QUERY_REGEX = new RegExp(
     17  `^(${NUMBER_REGEX})(${UNIT_REGEX})(?:\\s+in\\s+|\\s+to\\s+|\\s*=\\s*)(${UNIT_REGEX})`,
     18  "i"
     19 );
     20 
     21 /**
     22 * This module converts temperature unit.
     23 */
     24 export class UnitConverterTemperature {
     25  /**
     26   * Convert the given search string.
     27   *
     28   * @param {string} searchString
     29   *   The string to be converted
     30   * @returns {string} conversion result.
     31   */
     32  convert(searchString) {
     33    const regexResult = QUERY_REGEX.exec(searchString);
     34    if (!regexResult) {
     35      return null;
     36    }
     37 
     38    const target = findUnits(regexResult[2], regexResult[3]);
     39 
     40    if (!target) {
     41      return null;
     42    }
     43 
     44    const { inputUnit, outputUnit } = target;
     45    const inputNumber = Number(regexResult[1]);
     46    const inputChar = inputUnit.charAt(0);
     47    const outputChar = outputUnit.charAt(0);
     48 
     49    let outputNumber;
     50    if (inputChar === outputChar) {
     51      outputNumber = inputNumber;
     52    } else {
     53      outputNumber = this[`${inputChar}2${outputChar}`](inputNumber);
     54    }
     55 
     56    outputNumber = parseFloat(outputNumber);
     57 
     58    let formattedUnit;
     59    try {
     60      const formatter = new Intl.NumberFormat("en-US", {
     61        style: "unit",
     62        unit: outputUnit,
     63      });
     64      const parts = formatter.formatToParts(1);
     65      formattedUnit = parts.find(part => part.type == "unit").value;
     66    } catch (e) {
     67      formattedUnit = outputUnit;
     68    }
     69 
     70    let optionalSpace = formattedUnit[0] == "°" ? "" : " ";
     71 
     72    return `${UrlbarUtils.formatUnitConversionResult(outputNumber)}${optionalSpace}${formattedUnit}`;
     73  }
     74 
     75  c2k(t) {
     76    return t + 273.15;
     77  }
     78 
     79  c2f(t) {
     80    return t * 1.8 + 32;
     81  }
     82 
     83  k2c(t) {
     84    return t - 273.15;
     85  }
     86 
     87  k2f(t) {
     88    return this.c2f(this.k2c(t));
     89  }
     90 
     91  f2c(t) {
     92    return (t - 32) / 1.8;
     93  }
     94 
     95  f2k(t) {
     96    return this.c2k(this.f2c(t));
     97  }
     98 }
     99 
    100 /**
    101 * Returns the suitable units for the given two values.
    102 * If could not found suitable unit, returns null.
    103 *
    104 * @param {string} inputUnit
    105 *    A set of units to convert, mapped to the `inputUnit` value on the return
    106 * @param {string} outputUnit
    107 *    A set of units to convert, mapped to the `outputUnit` value on the return
    108 * @returns {{ inputUnit: string, outputUnit: string }} The suitable units.
    109 */
    110 function findUnits(inputUnit, outputUnit) {
    111  inputUnit = inputUnit.toLowerCase();
    112  outputUnit = outputUnit.toLowerCase();
    113 
    114  if (!UNITS.includes(inputUnit) || !UNITS.includes(outputUnit)) {
    115    return null;
    116  }
    117 
    118  return {
    119    inputUnit: toAbsoluteUnit(inputUnit),
    120    outputUnit: toAbsoluteUnit(outputUnit),
    121  };
    122 }
    123 
    124 function toAbsoluteUnit(unit) {
    125  if (unit.length !== 1) {
    126    return unit;
    127  }
    128 
    129  return ABSOLUTE.find(a => a.startsWith(unit));
    130 }