diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-21 11:44:51 +0000 |
commit | 9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /browser/components/urlbar/unitconverters/UnitConverterSimple.sys.mjs | |
parent | Initial commit. (diff) | |
download | thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'browser/components/urlbar/unitconverters/UnitConverterSimple.sys.mjs')
-rw-r--r-- | browser/components/urlbar/unitconverters/UnitConverterSimple.sys.mjs | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/browser/components/urlbar/unitconverters/UnitConverterSimple.sys.mjs b/browser/components/urlbar/unitconverters/UnitConverterSimple.sys.mjs new file mode 100644 index 0000000000..47ba0cc856 --- /dev/null +++ b/browser/components/urlbar/unitconverters/UnitConverterSimple.sys.mjs @@ -0,0 +1,243 @@ +/* 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/. */ + +// NOTE: This units table need to be localized upon supporting multi locales +// since it supports en-US only. +// e.g. Should support plugada or funty as well for pound. +const UNITS_GROUPS = [ + { + // Angle + degree: 1, + deg: "degree", + d: "degree", + radian: Math.PI / 180.0, + rad: "radian", + r: "radian", + gradian: 1 / 0.9, + grad: "gradian", + g: "gradian", + minute: 60, + min: "minute", + m: "minute", + second: 3600, + sec: "second", + s: "second", + sign: 1 / 30.0, + mil: 1 / 0.05625, + revolution: 1 / 360.0, + circle: 1 / 360.0, + turn: 1 / 360.0, + quadrant: 1 / 90.0, + rightangle: 1 / 90.0, + sextant: 1 / 60.0, + }, + { + // Force + newton: 1, + n: "newton", + kilonewton: 0.001, + kn: "kilonewton", + "gram-force": 101.9716213, + gf: "gram-force", + "kilogram-force": 0.1019716213, + kgf: "kilogram-force", + "ton-force": 0.0001019716213, + tf: "ton-force", + exanewton: 1.0e-18, + en: "exanewton", + petanewton: 1.0e-15, + PN: "petanewton", + Pn: "petanewton", + teranewton: 1.0e-12, + tn: "teranewton", + giganewton: 1.0e-9, + gn: "giganewton", + meganewton: 0.000001, + MN: "meganewton", + Mn: "meganewton", + hectonewton: 0.01, + hn: "hectonewton", + dekanewton: 0.1, + dan: "dekanewton", + decinewton: 10, + dn: "decinewton", + centinewton: 100, + cn: "centinewton", + millinewton: 1000, + mn: "millinewton", + micronewton: 1000000, + µn: "micronewton", + nanonewton: 1000000000, + nn: "nanonewton", + piconewton: 1000000000000, + pn: "piconewton", + femtonewton: 1000000000000000, + fn: "femtonewton", + attonewton: 1000000000000000000, + an: "attonewton", + dyne: 100000, + dyn: "dyne", + "joule/meter": 1, + "j/m": "joule/meter", + "joule/centimeter": 100, + "j/cm": "joule/centimeter", + "ton-force-short": 0.0001124045, + short: "ton-force-short", + "ton-force-long": 0.0001003611, + tonf: "ton-force-long", + "kip-force": 0.0002248089, + kipf: "kip-force", + "pound-force": 0.2248089431, + lbf: "pound-force", + "ounce-force": 3.5969430896, + ozf: "ounce-force", + poundal: 7.2330138512, + pdl: "poundal", + pond: 101.9716213, + p: "pond", + kilopond: 0.1019716213, + kp: "kilopond", + }, + { + // Length + meter: 1, + m: "meter", + nanometer: 1000000000, + micrometer: 1000000, + millimeter: 1000, + mm: "millimeter", + centimeter: 100, + cm: "centimeter", + kilometer: 0.001, + km: "kilometer", + mile: 0.0006213689, + mi: "mile", + yard: 1.0936132983, + yd: "yard", + foot: 3.280839895, + feet: "foot", + ft: "foot", + inch: 39.37007874, + inches: "inch", + in: "inch", + }, + { + // Mass + kilogram: 1, + kg: "kilogram", + gram: 1000, + g: "gram", + milligram: 1000000, + mg: "milligram", + ton: 0.001, + t: "ton", + longton: 0.0009842073, + "l.t.": "longton", + "l/t": "longton", + shortton: 0.0011023122, + "s.t.": "shortton", + "s/t": "shortton", + pound: 2.2046244202, + lbs: "pound", + lb: "pound", + ounce: 35.273990723, + oz: "ounce", + carat: 5000, + ffd: 5000, + }, +]; + +// There are some units that will be same in lower case in same unit group. +// e.g. Mn: meganewton and mn: millinewton on force group. +// Handle them as case-sensitive. +const CASE_SENSITIVE_UNITS = ["PN", "Pn", "MN", "Mn"]; + +const NUMBER_REGEX = "-?\\d+(?:\\.\\d+)?\\s*"; +const UNIT_REGEX = "[A-Za-zµ0-9_./-]+"; + +// 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 simple unit such as angle and length. + */ +export class UnitConverterSimple { + /** + * 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 = findUnitGroup(regexResult[2], regexResult[3]); + + if (!target) { + return null; + } + + const { group, inputUnit, outputUnit } = target; + const inputNumber = Number(regexResult[1]); + const outputNumber = parseFloat( + ((inputNumber / group[inputUnit]) * group[outputUnit]).toPrecision( + DECIMAL_PRECISION + ) + ); + + try { + return new Intl.NumberFormat("en-US", { + style: "unit", + unit: outputUnit, + maximumFractionDigits: DECIMAL_PRECISION, + }).format(outputNumber); + } catch (e) {} + + return `${outputNumber} ${outputUnit}`; + } +} + +/** + * 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 findUnitGroup(inputUnit, outputUnit) { + inputUnit = toSuitableUnit(inputUnit); + outputUnit = toSuitableUnit(outputUnit); + + const group = UNITS_GROUPS.find(ug => ug[inputUnit] && ug[outputUnit]); + + if (!group) { + return null; + } + + const inputValue = group[inputUnit]; + const outputValue = group[outputUnit]; + + return { + group, + inputUnit: typeof inputValue === "string" ? inputValue : inputUnit, + outputUnit: typeof outputValue === "string" ? outputValue : outputUnit, + }; +} + +function toSuitableUnit(unit) { + return CASE_SENSITIVE_UNITS.includes(unit) ? unit : unit.toLowerCase(); +} |