diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:22:09 +0000 |
commit | 43a97878ce14b72f0981164f87f2e35e14151312 (patch) | |
tree | 620249daf56c0258faa40cbdcf9cfba06de2a846 /browser/components/urlbar/unitconverters/UnitConverterTemperature.sys.mjs | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 110.0.1.upstream/110.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | browser/components/urlbar/unitconverters/UnitConverterTemperature.sys.mjs | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/browser/components/urlbar/unitconverters/UnitConverterTemperature.sys.mjs b/browser/components/urlbar/unitconverters/UnitConverterTemperature.sys.mjs new file mode 100644 index 0000000000..5a78d20577 --- /dev/null +++ b/browser/components/urlbar/unitconverters/UnitConverterTemperature.sys.mjs @@ -0,0 +1,124 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const ABSOLUTE = ["celsius", "kelvin", "fahrenheit"]; +const ALIAS = ["c", "k", "f"]; +const UNITS = [...ABSOLUTE, ...ALIAS]; + +const NUMBER_REGEX = "-?\\d+(?:\\.\\d+)?\\s*"; +const UNIT_REGEX = "\\w+"; + +// NOTE: This regex need to be localized upon supporting multi locales +// since it supports en-US input format only. +const QUERY_REGEX = new RegExp( + `^(${NUMBER_REGEX})(${UNIT_REGEX})(?:\\s+in\\s+|\\s+to\\s+|\\s*=\\s*)(${UNIT_REGEX})`, + "i" +); + +const DECIMAL_PRECISION = 10; + +/** + * This module converts temperature unit. + */ +export class UnitConverterTemperature { + /** + * Convert the given search string. + * + * @param {string} searchString + * The string to be converted + * @returns {string} conversion result. + */ + convert(searchString) { + const regexResult = QUERY_REGEX.exec(searchString); + if (!regexResult) { + return null; + } + + const target = findUnits(regexResult[2], regexResult[3]); + + if (!target) { + return null; + } + + const { inputUnit, outputUnit } = target; + const inputNumber = Number(regexResult[1]); + const inputChar = inputUnit.charAt(0); + const outputChar = outputUnit.charAt(0); + + let outputNumber; + if (inputChar === outputChar) { + outputNumber = inputNumber; + } else { + outputNumber = this[`${inputChar}2${outputChar}`](inputNumber); + } + + outputNumber = parseFloat(outputNumber.toPrecision(DECIMAL_PRECISION)); + + try { + return new Intl.NumberFormat("en-US", { + style: "unit", + unit: outputUnit, + maximumFractionDigits: DECIMAL_PRECISION, + }).format(outputNumber); + } catch (e) {} + + return `${outputNumber} ${outputUnit}`; + } + + c2k(t) { + return t + 273.15; + } + + c2f(t) { + return t * 1.8 + 32; + } + + k2c(t) { + return t - 273.15; + } + + k2f(t) { + return this.c2f(this.k2c(t)); + } + + f2c(t) { + return (t - 32) / 1.8; + } + + f2k(t) { + return this.c2k(this.f2c(t)); + } +} + +/** + * Returns the suitable units for the given two values. + * If could not found suitable unit, returns null. + * + * @param {string} inputUnit + * A set of units to convert, mapped to the `inputUnit` value on the return + * @param {string} outputUnit + * A set of units to convert, mapped to the `outputUnit` value on the return + * @returns {{ inputUnit: string, outputUnit: string }} The suitable units. + */ +function findUnits(inputUnit, outputUnit) { + inputUnit = inputUnit.toLowerCase(); + outputUnit = outputUnit.toLowerCase(); + + if (!UNITS.includes(inputUnit) || !UNITS.includes(outputUnit)) { + return null; + } + + return { + inputUnit: toAbsoluteUnit(inputUnit), + outputUnit: toAbsoluteUnit(outputUnit), + }; +} + +function toAbsoluteUnit(unit) { + if (unit.length !== 1) { + return unit; + } + + return ABSOLUTE.find(a => a.startsWith(unit)); +} |