diff options
Diffstat (limited to 'devtools/client/inspector/fonts/utils/font-utils.js')
-rw-r--r-- | devtools/client/inspector/fonts/utils/font-utils.js | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/devtools/client/inspector/fonts/utils/font-utils.js b/devtools/client/inspector/fonts/utils/font-utils.js new file mode 100644 index 0000000000..9a86acad49 --- /dev/null +++ b/devtools/client/inspector/fonts/utils/font-utils.js @@ -0,0 +1,111 @@ +/* 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/. */ + +"use strict"; + +module.exports = { + /** + * Given a CSS unit type, get the amount by which to increment a numeric value. + * Used as the step attribute in inputs of type "range" or "number". + * + * @param {String} unit + * CSS unit type (px, %, em, rem, vh, vw, ...) + * @return {Number} + * Amount by which to increment. + */ + getStepForUnit(unit) { + let step; + switch (unit) { + case "": + case "em": + case "rem": + case "vw": + case "vh": + case "vmin": + case "vmax": + step = 0.1; + break; + default: + step = 1; + } + + return step; + }, + + /** + * Get the unit type from the end of a CSS value string. + * Returns null for non-string input or unitless values. + * + * @param {String} value + * CSS value string. + * @return {String|null} + * CSS unit type, like "px", "em", "rem", etc or null. + */ + getUnitFromValue(value) { + if (typeof value !== "string" || isNaN(parseFloat(value))) { + return null; + } + + const match = value.match(/\D+?$/); + return match?.length ? match[0] : null; + }, + + /** + * Parse the string value of CSS font-variation-settings into an object with + * axis tag names and corresponding values. If the string is a keyword or does not + * contain axes, return an empty object. + * + * @param {String} string + * Value of font-variation-settings property coming from node's computed style. + * Its contents are expected to be stable having been already parsed by the + * browser. + * @return {Object} + */ + parseFontVariationAxes(string) { + let axes = {}; + const keywords = ["initial", "normal", "inherit", "unset"]; + + if (!string || keywords.includes(string.trim())) { + return axes; + } + + // Parse font-variation-settings CSS declaration into an object + // with axis tags as keys and axis values as values. + axes = string.split(",").reduce((acc, pair) => { + // Tags are always in quotes. Split by quote and filter excessive whitespace. + pair = pair.split(/["']/).filter(part => part.trim() !== ""); + // Guard against malformed input that may have slipped through. + if (pair.length === 0) { + return acc; + } + + const tag = pair[0]; + const value = pair[1].trim(); + // Axis tags shorter or longer than 4 characters are invalid. Whitespace is valid. + if (tag.length === 4) { + acc[tag] = parseFloat(value); + } + return acc; + }, {}); + + return axes; + }, + + /** + * Limit the decimal count of a number. Used instead of Number.toFixed() which pads + * integers with zeroes. If the input is not a number, it is returned as is. + * + * @param {Number} number + * @param {Number} decimals + * Decimal count in the output number. Default to one decimal. + * @return {Number} + */ + toFixed(number, decimals = 1) { + if (typeof number !== "number") { + return number; + } + + return Math.floor(number * Math.pow(10, decimals)) / Math.pow(10, decimals); + }, +}; |