diff --git a/lib/parsers.js b/lib/parsers.js index 9f25fca5..4704a22a 100644 --- a/lib/parsers.js +++ b/lib/parsers.js @@ -61,7 +61,6 @@ const SYS_COLORS = new Set([ ]); // AST node types -// TODO: Export and use in properties/*.js in the future const AST_TYPES = Object.freeze({ CALC: "Calc", DIMENSION: "Dimension", @@ -483,38 +482,6 @@ const parsePercentage = (val, opt = {}) => { return `${num}%`; }; -/** - * Parses a value. - * - * @param {Array} val - The AST value. - * @param {object} [opt={}] - The options for parsing. - * @returns {string|undefined} The parsed length-percentage. - */ -const parseLengthPercentage = (val, opt = {}) => { - const res = parseNumericValue( - val, - opt, - (type, value) => - type === AST_TYPES.DIMENSION || - type === AST_TYPES.PERCENTAGE || - (type === AST_TYPES.NUMBER && value === "0") - ); - if (!res) { - return; - } - const { num, unit, type } = res; - if (unit) { - if (/deg|g?rad|turn/i.test(unit)) { - return; - } - return `${num}${unit}`; - } else if (type === AST_TYPES.PERCENTAGE) { - return `${num}%`; - } else if (num === 0) { - return `${num}px`; - } -}; - /** * Parses an value. * @@ -638,23 +605,250 @@ const parseGradient = (val) => { } }; +/** + * Resolves a keyword value. + * + * @param {Array} value - The AST node array containing the keyword value. + * @param {object} [opt={}] - The options for parsing. + * @returns {string|undefined} The resolved keyword or undefined. + */ +const resolveKeywordValue = (value, opt = {}) => { + const [{ name, type }] = value; + const { length } = opt; + switch (type) { + case AST_TYPES.GLOBAL_KEYWORD: { + if (length > 1) { + return; + } + return name; + } + case AST_TYPES.IDENTIFIER: { + return name; + } + default: + } +}; + +/** + * Resolves a function value. + * + * @param {Array} value - The AST node array containing the function value. + * @param {object} [opt={}] - The options for parsing. + * @returns {string|undefined} The resolved function or undefined. + */ +const resolveFunctionValue = (value, opt = {}) => { + const [{ name, type, value: itemValue }] = value; + const { length } = opt; + switch (type) { + case AST_TYPES.FUNCTION: { + return `${name}(${itemValue})`; + } + case AST_TYPES.GLOBAL_KEYWORD: { + if (length > 1) { + return; + } + return name; + } + case AST_TYPES.IDENTIFIER: { + return name; + } + default: + } +}; + +/** + * Resolves a length or percentage or number value. + * + * @param {Array} value - The AST node array containing the value. + * @param {object} [opt={}] - The options for parsing. + * @returns {string|undefined} The resolved length/percentage/number or undefined. + */ +const resolveNumericValue = (value, opt = {}) => { + const [{ name, type: itemType, value: itemValue }] = value; + const { length, type } = opt; + switch (itemType) { + case AST_TYPES.CALC: { + return `${name}(${itemValue})`; + } + case AST_TYPES.DIMENSION: { + if (type === "angle") { + return parseAngle(value, opt); + } + return parseLength(value, opt); + } + case AST_TYPES.GLOBAL_KEYWORD: { + if (length > 1) { + return; + } + return name; + } + case AST_TYPES.IDENTIFIER: { + return name; + } + case AST_TYPES.NUMBER: { + switch (type) { + case "angle": { + return parseAngle(value, opt); + } + case "length": { + return parseLength(value, opt); + } + case "percentage": { + return parsePercentage(value, opt); + } + default: { + return parseNumber(value, opt); + } + } + } + case AST_TYPES.PERCENTAGE: { + return parsePercentage(value, opt); + } + default: + } +}; + +/** + * Resolves a color value. + * + * @param {Array} value - The AST node array containing the color value. + * @param {object} [opt={}] - The options for parsing. + * @returns {string|undefined} The resolved color or undefined. + */ +const resolveColorValue = (value, opt = {}) => { + const [{ name, type }] = value; + const { length } = opt; + switch (type) { + case AST_TYPES.GLOBAL_KEYWORD: { + if (length > 1) { + return; + } + return name; + } + default: { + return parseColor(value, opt); + } + } +}; + +/** + * Resolves a gradient or URL value. + * + * @param {Array} value - The AST node array containing the color value. + * @param {object} [opt={}] - The options for parsing. + * @returns {string|undefined} The resolved gradient/url or undefined. + */ +const resolveGradientUrlValue = (value, opt = {}) => { + const [{ name, type }] = value; + const { length } = opt; + switch (type) { + case AST_TYPES.GLOBAL_KEYWORD: { + if (length > 1) { + return; + } + return name; + } + case AST_TYPES.IDENTIFIER: { + return name; + } + case AST_TYPES.URL: { + return parseUrl(value, opt); + } + default: { + return parseGradient(value, opt); + } + } +}; + +/** + * Resolves a border shorthand value. + * + * @param {Array} value - The AST node array containing the shorthand value. + * @param {object} subProps - The sub properties object. + * @param {Map} parsedValues - The Map of parsed values. + * @returns {Array|string|undefined} - The resolved [prop, value] pair, keyword or undefined. + */ +const resolveBorderShorthandValue = (value, subProps, parsedValues) => { + const [{ isNumber, name, type, value: itemValue }] = value; + const { color: colorProp, style: styleProp, width: widthProp } = subProps; + switch (type) { + case AST_TYPES.CALC: { + if (isNumber || parsedValues.has(widthProp)) { + return; + } + return [widthProp, `${name}(${itemValue}`]; + } + case AST_TYPES.DIMENSION: + case AST_TYPES.NUMBER: { + if (parsedValues.has(widthProp)) { + return; + } + const parsedValue = parseLength(value, { min: 0 }); + if (!parsedValue) { + return; + } + return [widthProp, parsedValue]; + } + case AST_TYPES.FUNCTION: + case AST_TYPES.HASH: { + if (parsedValues.has(colorProp)) { + return; + } + const parsedValue = parseColor(value); + if (!parsedValue) { + return; + } + return [colorProp, parsedValue]; + } + case AST_TYPES.GLOBAL_KEYWORD: { + return name; + } + case AST_TYPES.IDENTIFIER: { + if (isValidPropertyValue(widthProp, name)) { + if (parsedValues.has(widthProp)) { + return; + } + return [widthProp, name]; + } else if (isValidPropertyValue(styleProp, name)) { + if (parsedValues.has(styleProp)) { + return; + } + return [styleProp, name]; + } else if (isValidPropertyValue(colorProp, name)) { + if (parsedValues.has(colorProp)) { + return; + } + return [colorProp, name]; + } + break; + } + default: + } +}; + module.exports = { - prepareValue, - isGlobalKeyword, - hasVarFunc, + AST_TYPES, hasCalcFunc, - splitValue, - parseCSS, + hasVarFunc, + isGlobalKeyword, isValidPropertyValue, - resolveCalc, - parsePropertyValue, - parseNumber, + parseAngle, + parseCSS, + parseColor, + parseGradient, parseLength, + parseNumber, parsePercentage, - parseLengthPercentage, - parseAngle, - parseUrl, + parsePropertyValue, parseString, - parseColor, - parseGradient + parseUrl, + prepareValue, + resolveBorderShorthandValue, + resolveCalc, + resolveColorValue, + resolveFunctionValue, + resolveGradientUrlValue, + resolveKeywordValue, + resolveNumericValue, + splitValue }; diff --git a/lib/properties/background.js b/lib/properties/background.js index c94327bf..be5c22be 100644 --- a/lib/properties/background.js +++ b/lib/properties/background.js @@ -11,29 +11,30 @@ const backgroundAttachment = require("./backgroundAttachment"); const backgroundColor = require("./backgroundColor"); const property = "background"; -const initialValues = new Map([ - ["background-image", "none"], - ["background-position", "0% 0%"], - ["background-size", "auto"], - ["background-repeat", "repeat"], - ["background-origin", "padding-box"], - ["background-clip", "border-box"], - ["background-attachment", "scroll"], - ["background-color", "transparent"] + +module.exports.initialValues = new Map([ + [backgroundImage.property, "none"], + [backgroundPosition.property, "0% 0%"], + [backgroundSize.property, "auto"], + [backgroundRepeat.property, "repeat"], + [backgroundOrigin.property, "padding-box"], + [backgroundClip.property, "border-box"], + [backgroundAttachment.property, "scroll"], + [backgroundColor.property, "transparent"] ]); module.exports.shorthandFor = new Map([ - ["background-image", backgroundImage], - ["background-position", backgroundPosition], - ["background-size", backgroundSize], - ["background-repeat", backgroundRepeat], - ["background-origin", backgroundOrigin], - ["background-clip", backgroundClip], - ["background-attachment", backgroundAttachment], - ["background-color", backgroundColor] + [backgroundImage.property, backgroundImage], + [backgroundPosition.property, backgroundPosition], + [backgroundSize.property, backgroundSize], + [backgroundRepeat.property, backgroundRepeat], + [backgroundOrigin.property, backgroundOrigin], + [backgroundClip.property, backgroundClip], + [backgroundAttachment.property, backgroundAttachment], + [backgroundColor.property, backgroundColor] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -50,24 +51,30 @@ module.exports.parse = function parse(v, opt = {}) { const l = values.length; for (let i = 0; i < l; i++) { let bg = { - "background-image": initialValues.get("background-image"), - "background-position": initialValues.get("background-position"), - "background-size": initialValues.get("background-size"), - "background-repeat": initialValues.get("background-repeat"), - "background-origin": initialValues.get("background-origin"), - "background-clip": initialValues.get("background-clip"), - "background-attachment": initialValues.get("background-attachment"), - "background-color": initialValues.get("background-color") + [backgroundImage.property]: module.exports.initialValues.get(backgroundImage.property), + [backgroundPosition.property]: module.exports.initialValues.get(backgroundPosition.property), + [backgroundSize.property]: module.exports.initialValues.get(backgroundSize.property), + [backgroundRepeat.property]: module.exports.initialValues.get(backgroundRepeat.property), + [backgroundOrigin.property]: module.exports.initialValues.get(backgroundOrigin.property), + [backgroundClip.property]: module.exports.initialValues.get(backgroundClip.property), + [backgroundAttachment.property]: module.exports.initialValues.get( + backgroundAttachment.property + ), + [backgroundColor.property]: module.exports.initialValues.get(backgroundColor.property) }; if (l > 1 && i !== l - 1) { bg = { - "background-image": initialValues.get("background-image"), - "background-position": initialValues.get("background-position"), - "background-size": initialValues.get("background-size"), - "background-repeat": initialValues.get("background-repeat"), - "background-origin": initialValues.get("background-origin"), - "background-clip": initialValues.get("background-clip"), - "background-attachment": initialValues.get("background-attachment") + [backgroundImage.property]: module.exports.initialValues.get(backgroundImage.property), + [backgroundPosition.property]: module.exports.initialValues.get( + backgroundPosition.property + ), + [backgroundSize.property]: module.exports.initialValues.get(backgroundSize.property), + [backgroundRepeat.property]: module.exports.initialValues.get(backgroundRepeat.property), + [backgroundOrigin.property]: module.exports.initialValues.get(backgroundOrigin.property), + [backgroundClip.property]: module.exports.initialValues.get(backgroundClip.property), + [backgroundAttachment.property]: module.exports.initialValues.get( + backgroundAttachment.property + ) }; } const bgPosition = []; @@ -88,15 +95,15 @@ module.exports.parse = function parse(v, opt = {}) { if (parsers.isValidPropertyValue(longhand, part)) { partValid = true; switch (longhand) { - case "background-clip": - case "background-origin": { + case backgroundClip.property: + case backgroundOrigin.property: { const parsedValue = value.parse(part, { globalObject }); if (parsedValue) { bgBox.push(parsedValue); } break; } - case "background-color": { + case backgroundColor.property: { if (i !== values.length - 1) { return; } @@ -106,21 +113,21 @@ module.exports.parse = function parse(v, opt = {}) { } break; } - case "background-position": { + case backgroundPosition.property: { const parsedValue = value.parse(part, { globalObject }); if (parsedValue) { bgPosition.push(parsedValue); } break; } - case "background-repeat": { + case backgroundRepeat.property: { const parsedValue = value.parse(part, { globalObject }); if (parsedValue) { bgRepeat.push(parsedValue); } break; } - case "background-size": { + case backgroundSize.property: { break; } default: { @@ -144,15 +151,15 @@ module.exports.parse = function parse(v, opt = {}) { if (parsers.isValidPropertyValue(longhand, part)) { partValid = true; switch (longhand) { - case "background-clip": - case "background-origin": { + case backgroundClip.property: + case backgroundOrigin.property: { const parsedValue = value.parse(part, { globalObject }); if (parsedValue) { bgBox.push(parsedValue); } break; } - case "background-color": { + case backgroundColor.property: { if (i !== l - 1) { return; } @@ -162,17 +169,17 @@ module.exports.parse = function parse(v, opt = {}) { } break; } - case "background-position": { + case backgroundPosition.property: { break; } - case "background-repeat": { + case backgroundRepeat.property: { const parsedValue = value.parse(part, { globalObject }); if (parsedValue) { bgRepeat.push(parsedValue); } break; } - case "background-size": { + case backgroundSize.property: { const parsedValue = value.parse(part, { globalObject }); if (parsedValue) { bgSize.push(parsedValue); @@ -194,38 +201,38 @@ module.exports.parse = function parse(v, opt = {}) { } } if (bgPosition.length) { - const { parse: parser } = module.exports.shorthandFor.get("background-position"); + const { parse: parser } = module.exports.shorthandFor.get(backgroundPosition.property); const value = parser(bgPosition.join(" "), { globalObject }); if (value) { - bg["background-position"] = value; + bg[backgroundPosition.property] = value; } } if (bgSize.length) { - const { parse: parser } = module.exports.shorthandFor.get("background-size"); + const { parse: parser } = module.exports.shorthandFor.get(backgroundSize.property); const value = parser(bgSize.join(" "), { globalObject }); if (value) { - bg["background-size"] = value; + bg[backgroundSize.property] = value; } } if (bgRepeat.length) { - const { parse: parser } = module.exports.shorthandFor.get("background-repeat"); + const { parse: parser } = module.exports.shorthandFor.get(backgroundRepeat.property); const value = parser(bgRepeat.join(" "), { globalObject }); if (value) { - bg["background-repeat"] = value; + bg[backgroundRepeat.property] = value; } } if (bgBox.length) { switch (bgBox.length) { case 1: { const [value] = bgBox; - bg["background-origin"] = value; - bg["background-clip"] = value; + bg[backgroundOrigin.property] = value; + bg[backgroundClip.property] = value; break; } case 2: { const [value1, value2] = bgBox; - bg["background-origin"] = value1; - bg["background-clip"] = value2; + bg[backgroundOrigin.property] = value1; + bg[backgroundClip.property] = value2; break; } default: { @@ -254,14 +261,14 @@ module.exports.definition = { return; } const bgMap = new Map([ - ["background-image", []], - ["background-position", []], - ["background-size", []], - ["background-repeat", []], - ["background-origin", []], - ["background-clip", []], - ["background-attachment", []], - ["background-color", []] + [backgroundImage.property, []], + [backgroundPosition.property, []], + [backgroundSize.property, []], + [backgroundRepeat.property, []], + [backgroundOrigin.property, []], + [backgroundClip.property, []], + [backgroundAttachment.property, []], + [backgroundColor.property, []] ]); const backgrounds = []; for (const bgValue of bgValues) { @@ -271,17 +278,17 @@ module.exports.definition = { const arr = bgMap.get(longhand); arr.push(value); bgMap.set(longhand, arr); - if (value !== initialValues.get(longhand)) { - if (longhand === "background-size") { + if (value !== module.exports.initialValues.get(longhand)) { + if (longhand === backgroundSize.property) { bg.push(`/ ${value}`); } else { bg.push(value); } - } else if (longhand === "background-image") { + } else if (longhand === backgroundImage.property) { if (v === "none") { bg.push(value); } - } else if (longhand === "background-color") { + } else if (longhand === backgroundColor.property) { if (v === "transparent") { bg.push(value); } @@ -306,26 +313,26 @@ module.exports.definition = { let l = 0; for (const [longhand] of module.exports.shorthandFor) { const val = this.getPropertyValue(longhand); - if (longhand === "background-image") { + if (longhand === backgroundImage.property) { if ( val === "none" && v === "none" && - this.getPropertyValue("background-color") === "transparent" + this.getPropertyValue(backgroundColor.property) === "transparent" ) { return val; } - if (val !== initialValues.get(longhand)) { + if (val !== module.exports.initialValues.get(longhand)) { const imgValues = parsers.splitValue(val, { delimiter: "," }); l = imgValues.length; bgMap.set(longhand, imgValues); } - } else if (longhand === "background-color") { - if (val !== initialValues.get(longhand) || v.includes(val)) { + } else if (longhand === backgroundColor.property) { + if (val !== module.exports.initialValues.get(longhand) || v.includes(val)) { bgMap.set(longhand, [val]); } - } else if (val !== initialValues.get(longhand)) { + } else if (val !== module.exports.initialValues.get(longhand)) { bgMap.set( longhand, parsers.splitValue(val, { @@ -335,7 +342,8 @@ module.exports.definition = { } } if (l === 0) { - const [background] = bgMap.get("background-color"); + const bgColArr = bgMap.get(backgroundColor.property); + const background = bgColArr ? bgColArr[0] : null; if (background) { return background; } @@ -348,25 +356,25 @@ module.exports.definition = { for (const [longhand, values] of bgMap) { for (let i = 0; i < l; i++) { switch (longhand) { - case "background-color": { + case backgroundColor.property: { if (i === l - 1) { const value = values[0]; if (parsers.hasVarFunc(value)) { return ""; } - if (value && value !== initialValues.get(longhand)) { + if (value && value !== module.exports.initialValues.get(longhand)) { const bgValue = bgValues[i]; bgValue.push(value); } } break; } - case "background-size": { + case backgroundSize.property: { const value = values[i]; if (parsers.hasVarFunc(value)) { return ""; } - if (value && value !== initialValues.get(longhand)) { + if (value && value !== module.exports.initialValues.get(longhand)) { const bgValue = bgValues[i]; bgValue.push(`/ ${value}`); } @@ -377,7 +385,7 @@ module.exports.definition = { if (parsers.hasVarFunc(value)) { return ""; } - if (value && value !== initialValues.get(longhand)) { + if (value && value !== module.exports.initialValues.get(longhand)) { const bgValue = bgValues[i]; bgValue.push(value); } @@ -394,3 +402,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundAttachment.js b/lib/properties/backgroundAttachment.js index e8ee4565..edb5bbde 100644 --- a/lib/properties/backgroundAttachment.js +++ b/lib/properties/backgroundAttachment.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "background-attachment"; const shorthand = "background"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -18,17 +18,11 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - parsedValues.push(name); - break; - } - default: { - return; - } + const parsedValue = parsers.resolveKeywordValue(value); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } else if (typeof value === "string") { parsedValues.push(value); } @@ -49,9 +43,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -62,3 +57,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundClip.js b/lib/properties/backgroundClip.js index 5eb2fe20..bb31abaf 100644 --- a/lib/properties/backgroundClip.js +++ b/lib/properties/backgroundClip.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "background-clip"; const shorthand = "background"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -18,17 +18,11 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - parsedValues.push(name); - break; - } - default: { - return; - } + const parsedValue = parsers.resolveKeywordValue(value); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } else if (typeof value === "string") { parsedValues.push(value); } @@ -49,9 +43,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -62,3 +57,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundColor.js b/lib/properties/backgroundColor.js index 8dfe76fb..8be2ec98 100644 --- a/lib/properties/backgroundColor.js +++ b/lib/properties/backgroundColor.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "background-color"; const shorthand = "background"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -15,15 +15,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -40,9 +32,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -53,3 +46,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundImage.js b/lib/properties/backgroundImage.js index 07a4e9d9..badd805a 100644 --- a/lib/properties/backgroundImage.js +++ b/lib/properties/backgroundImage.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "background-image"; const shorthand = "background"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -18,29 +18,11 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - parsedValues.push(name); - break; - } - case "Url": { - const parsedValue = parsers.parseUrl(value); - if (!parsedValue) { - return; - } - parsedValues.push(parsedValue); - break; - } - default: { - const parsedValue = parsers.parseGradient(value); - if (!parsedValue) { - return; - } - parsedValues.push(parsedValue); - } + const parsedValue = parsers.resolveGradientUrlValue(value); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } else if (typeof value === "string") { parsedValues.push(value); } else { @@ -63,9 +45,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -76,3 +59,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundOrigin.js b/lib/properties/backgroundOrigin.js index 6c3cd4bd..5a37ced6 100644 --- a/lib/properties/backgroundOrigin.js +++ b/lib/properties/backgroundOrigin.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "background-origin"; const shorthand = "background"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -18,17 +18,11 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - parsedValues.push(name); - break; - } - default: { - return; - } + const parsedValue = parsers.resolveKeywordValue(value); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } else if (typeof value === "string") { parsedValues.push(value); } @@ -49,9 +43,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -62,3 +57,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundPosition.js b/lib/properties/backgroundPosition.js index f99b9bc2..473547a1 100644 --- a/lib/properties/backgroundPosition.js +++ b/lib/properties/backgroundPosition.js @@ -10,11 +10,12 @@ const keywordsX = ["center", ...keyX]; const keywordsY = ["center", ...keyY]; const keywords = ["center", ...keyX, ...keyY]; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const values = parsers.splitValue(v, { delimiter: "," }); @@ -25,12 +26,14 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length) { + const [part1, part2, part3, part4] = value; let parsedValue = ""; switch (value.length) { case 1: { - const [part1] = value; const val1 = - part1.type === "Identifier" ? part1.name : parsers.parseLengthPercentage([part1]); + part1.type === AST_TYPES.IDENTIFIER + ? part1.name + : parsers.resolveNumericValue([part1], { type: "length" }); if (val1) { if (val1 === "center") { parsedValue = `${val1} ${val1}`; @@ -43,11 +46,14 @@ module.exports.parse = function parse(v, opt = {}) { break; } case 2: { - const [part1, part2] = value; const val1 = - part1.type === "Identifier" ? part1.name : parsers.parseLengthPercentage([part1]); + part1.type === AST_TYPES.IDENTIFIER + ? part1.name + : parsers.resolveNumericValue([part1], { type: "length" }); const val2 = - part2.type === "Identifier" ? part2.name : parsers.parseLengthPercentage([part2]); + part2.type === AST_TYPES.IDENTIFIER + ? part2.name + : parsers.resolveNumericValue([part2], { type: "length" }); if (val1 && val2) { if (keywordsX.includes(val1) && keywordsY.includes(val2)) { parsedValue = `${val1} ${val2}`; @@ -68,12 +74,15 @@ module.exports.parse = function parse(v, opt = {}) { break; } case 3: { - const [part1, part2, part3] = value; - const val1 = part1.type === "Identifier" && part1.name; + const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name; const val2 = - part2.type === "Identifier" ? part2.name : parsers.parseLengthPercentage([part2]); + part2.type === AST_TYPES.IDENTIFIER + ? part2.name + : parsers.resolveNumericValue([part2], { type: "length" }); const val3 = - part3.type === "Identifier" ? part3.name : parsers.parseLengthPercentage([part3]); + part3.type === AST_TYPES.IDENTIFIER + ? part3.name + : parsers.resolveNumericValue([part3], { type: "length" }); if (val1 && val2 && val3) { let posX = ""; let offX = ""; @@ -119,11 +128,10 @@ module.exports.parse = function parse(v, opt = {}) { break; } case 4: { - const [part1, part2, part3, part4] = value; - const val1 = part1.type === "Identifier" && part1.name; - const val2 = parsers.parseLengthPercentage([part2]); - const val3 = part3.type === "Identifier" && part3.name; - const val4 = parsers.parseLengthPercentage([part4]); + const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name; + const val2 = parsers.resolveNumericValue([part2], { type: "length" }); + const val3 = part3.type === AST_TYPES.IDENTIFIER && part3.name; + const val4 = parsers.resolveNumericValue([part4], { type: "length" }); if (val1 && val2 && val3 && val4) { let posX = ""; let offX = ""; @@ -178,9 +186,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -191,3 +200,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundRepeat.js b/lib/properties/backgroundRepeat.js index 30fca2a8..bd3f40e7 100644 --- a/lib/properties/backgroundRepeat.js +++ b/lib/properties/backgroundRepeat.js @@ -5,11 +5,12 @@ const parsers = require("../parsers"); const property = "background-repeat"; const shorthand = "background"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const values = parsers.splitValue(v, { delimiter: "," }); @@ -24,7 +25,7 @@ module.exports.parse = function parse(v, opt = {}) { switch (value.length) { case 1: { const [part1] = value; - const val1 = part1.type === "Identifier" && part1.name; + const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name; if (val1) { parsedValue = val1; } @@ -32,8 +33,8 @@ module.exports.parse = function parse(v, opt = {}) { } case 2: { const [part1, part2] = value; - const val1 = part1.type === "Identifier" && part1.name; - const val2 = part2.type === "Identifier" && part2.name; + const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name; + const val2 = part2.type === AST_TYPES.IDENTIFIER && part2.name; if (val1 && val2) { if (val1 === "repeat" && val2 === "no-repeat") { parsedValue = "repeat-x"; @@ -74,9 +75,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -87,3 +89,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/backgroundSize.js b/lib/properties/backgroundSize.js index bd59a1b7..64b83885 100644 --- a/lib/properties/backgroundSize.js +++ b/lib/properties/backgroundSize.js @@ -5,11 +5,12 @@ const parsers = require("../parsers"); const property = "background-size"; const shorthand = "background"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const values = parsers.splitValue(v, { delimiter: "," }); @@ -23,20 +24,22 @@ module.exports.parse = function parse(v, opt = {}) { if (value.length === 1) { const [{ isNumber, name, type, value: itemValue }] = value; switch (type) { - case "Calc": { + case AST_TYPES.CALC: { if (isNumber) { return; } parsedValues.push(`${name}(${itemValue})`); break; } - case "GlobalKeyword": - case "Identifier": { + case AST_TYPES.GLOBAL_KEYWORD: + case AST_TYPES.IDENTIFIER: { parsedValues.push(name); break; } default: { - const parsedValue = parsers.parseLengthPercentage(value); + const parsedValue = parsers.resolveNumericValue(value, { + type: "length" + }); if (!parsedValue) { return; } @@ -46,36 +49,36 @@ module.exports.parse = function parse(v, opt = {}) { } else { const [val1, val2] = value; const parts = []; - if (val1.type === "Calc" && !val1.isNumber) { + if (val1.type === AST_TYPES.CALC && !val1.isNumber) { parts.push(`${val1.name}(${val1.value})`); - } else if (val1.type === "Identifier") { + } else if (val1.type === AST_TYPES.IDENTIFIER) { parts.push(val1.name); - } else if (val1.type === "Dimension") { + } else if (val1.type === AST_TYPES.DIMENSION) { parts.push(`${val1.value}${val1.unit}`); - } else if (val1.type === "Percentage") { + } else if (val1.type === AST_TYPES.PERCENTAGE) { parts.push(`${val1.value}%`); } else { return; } switch (val2.type) { - case "Calc": { + case AST_TYPES.CALC: { if (val2.isNumber) { return; } parts.push(`${val2.name}(${val2.value})`); break; } - case "Dimension": { + case AST_TYPES.DIMENSION: { parts.push(`${val2.value}${val2.unit}`); break; } - case "Identifier": { + case AST_TYPES.IDENTIFIER: { if (val2.name !== "auto") { parts.push(val2.name); } break; } - case "Percentage": { + case AST_TYPES.PERCENTAGE: { parts.push(`${val2.value}%`); break; } @@ -105,9 +108,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -118,3 +122,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/border.js b/lib/properties/border.js index c39f28c3..3f7569cc 100644 --- a/lib/properties/border.js +++ b/lib/properties/border.js @@ -11,26 +11,32 @@ const borderLeft = require("./borderLeft"); const property = "border"; +const subProps = { + width: borderWidth.property, + style: borderStyle.property, + color: borderColor.property +}; + module.exports.initialValues = new Map([ - ["border-width", "medium"], - ["border-style", "none"], - ["border-color", "currentcolor"] + [borderWidth.property, "medium"], + [borderStyle.property, "none"], + [borderColor.property, "currentcolor"] ]); module.exports.shorthandFor = new Map([ - ["border-width", borderWidth], - ["border-style", borderStyle], - ["border-color", borderColor] + [borderWidth.property, borderWidth], + [borderStyle.property, borderStyle], + [borderColor.property, borderColor] ]); module.exports.positionShorthandFor = new Map([ - ["border-top", borderTop], - ["border-right", borderRight], - ["border-bottom", borderBottom], - ["border-left", borderLeft] + [borderTop.property, borderTop], + [borderRight.property, borderRight], + [borderBottom.property, borderBottom], + [borderLeft.property, borderLeft] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "" || parsers.hasVarFunc(v)) { return v; @@ -43,79 +49,14 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber || parsedValues.has("border-width")) { - return; - } - parsedValues.set("border-width", `${name}(${itemValue})`); - break; - } - case "Dimension": - case "Number": { - if (parsedValues.has("border-width")) { - return; - } - const parsedValue = parsers.parseLength(value, { - min: 0 - }); - if (!parsedValue) { - return; - } - parsedValues.set("border-width", parsedValue); - break; - } - case "Function": { - if (parsedValues.has("border-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-color", parsedValue); - break; - } - case "GlobalKeyword": { - return name; - } - case "Hash": { - if (parsedValues.has("border-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-color", parsedValue); - break; - } - case "Identifier": { - if (parsers.isValidPropertyValue("border-width", name)) { - if (parsedValues.has("border-width")) { - return; - } - parsedValues.set("border-width", name); - break; - } else if (parsers.isValidPropertyValue("border-style", name)) { - if (parsedValues.has("border-style")) { - return; - } - parsedValues.set("border-style", name); - break; - } else if (parsers.isValidPropertyValue("border-color", name)) { - if (parsedValues.has("border-color")) { - return; - } - parsedValues.set("border-color", name); - break; - } - return; - } - default: { - return; - } + const parsedValue = parsers.resolveBorderShorthandValue(value, subProps, parsedValues); + if (typeof parsedValue === "string") { + return parsedValue; + } else if (Array.isArray(parsedValue)) { + const [key, resolvedVal] = parsedValue; + parsedValues.set(key, resolvedVal); + } else { + return; } } else { return; @@ -124,15 +65,15 @@ module.exports.parse = function parse(v, opt = {}) { if (parsedValues.size) { const keys = module.exports.shorthandFor.keys(); const obj = { - "border-width": "medium" + [borderWidth.property]: "medium" }; for (const key of keys) { if (parsedValues.has(key)) { const parsedValue = parsedValues.get(key); if (parsedValue !== module.exports.initialValues.get(key)) { obj[key] = parsedValues.get(key); - if (obj["border-width"] && obj["border-width"] === "medium") { - delete obj["border-width"]; + if (obj[borderWidth.property] && obj[borderWidth.property] === "medium") { + delete obj[borderWidth.property]; } } } @@ -162,3 +103,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderBottom.js b/lib/properties/borderBottom.js index d624988b..29b8651f 100644 --- a/lib/properties/borderBottom.js +++ b/lib/properties/borderBottom.js @@ -8,19 +8,25 @@ const borderBottomColor = require("./borderBottomColor"); const property = "border-bottom"; const shorthand = "border"; +const subProps = { + width: borderBottomWidth.property, + style: borderBottomStyle.property, + color: borderBottomColor.property +}; + module.exports.initialValues = new Map([ - ["border-bottom-width", "medium"], - ["border-bottom-style", "none"], - ["border-bottom-color", "currentcolor"] + [borderBottomWidth.property, "medium"], + [borderBottomStyle.property, "none"], + [borderBottomColor.property, "currentcolor"] ]); module.exports.shorthandFor = new Map([ - ["border-bottom-width", borderBottomWidth], - ["border-bottom-style", borderBottomStyle], - ["border-bottom-color", borderBottomColor] + [borderBottomWidth.property, borderBottomWidth], + [borderBottomStyle.property, borderBottomStyle], + [borderBottomColor.property, borderBottomColor] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -33,79 +39,14 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber || parsedValues.has("border-bottom-width")) { - return; - } - parsedValues.set("border-bottom-width", `${name}(${itemValue})`); - break; - } - case "Dimension": - case "Number": { - if (parsedValues.has("border-bottom-width")) { - return; - } - const parsedValue = parsers.parseLength(value, { - min: 0 - }); - if (!parsedValue) { - return; - } - parsedValues.set("border-bottom-width", parsedValue); - break; - } - case "Function": { - if (parsedValues.has("border-bottom-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-bottom-color", parsedValue); - break; - } - case "GlobalKeyword": { - return name; - } - case "Hash": { - if (parsedValues.has("border-bottom-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-bottom-color", parsedValue); - break; - } - case "Identifier": { - if (parsers.isValidPropertyValue("border-bottom-width", name)) { - if (parsedValues.has("border-bottom-width")) { - return; - } - parsedValues.set("border-bottom-width", name); - break; - } else if (parsers.isValidPropertyValue("border-bottom-style", name)) { - if (parsedValues.has("border-bottom-style")) { - return; - } - parsedValues.set("border-bottom-style", name); - break; - } else if (parsers.isValidPropertyValue("border-bottom-color", name)) { - if (parsedValues.has("border-bottom-color")) { - return; - } - parsedValues.set("border-bottom-color", name); - break; - } - return; - } - default: { - return; - } + const parsedValue = parsers.resolveBorderShorthandValue(value, subProps, parsedValues); + if (typeof parsedValue === "string") { + return parsedValue; + } else if (Array.isArray(parsedValue)) { + const [key, resolvedVal] = parsedValue; + parsedValues.set(key, resolvedVal); + } else { + return; } } else { return; @@ -114,15 +55,15 @@ module.exports.parse = function parse(v, opt = {}) { if (parsedValues.size) { const keys = module.exports.shorthandFor.keys(); const obj = { - "border-bottom-width": "medium" + [borderBottomWidth.property]: "medium" }; for (const key of keys) { if (parsedValues.has(key)) { const parsedValue = parsedValues.get(key); if (parsedValue !== module.exports.initialValues.get(key)) { obj[key] = parsedValues.get(key); - if (obj["border-bottom-width"] && obj["border-bottom-width"] === "medium") { - delete obj["border-bottom-width"]; + if (obj[borderBottomWidth.property] && obj[borderBottomWidth.property] === "medium") { + delete obj[borderBottomWidth.property]; } } } @@ -141,9 +82,10 @@ module.exports.definition = { globalObject: this._global }); if (val || typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -154,3 +96,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderBottomColor.js b/lib/properties/borderBottomColor.js index 015a60fd..ed4555e2 100644 --- a/lib/properties/borderBottomColor.js +++ b/lib/properties/borderBottomColor.js @@ -7,7 +7,7 @@ const lineShorthand = "border-color"; const positionShorthand = "border-bottom"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,15 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -44,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -58,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderBottomStyle.js b/lib/properties/borderBottomStyle.js index fc865b66..2c9201e0 100644 --- a/lib/properties/borderBottomStyle.js +++ b/lib/properties/borderBottomStyle.js @@ -7,7 +7,7 @@ const lineShorthand = "border-style"; const positionShorthand = "border-bottom"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,14 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: - } + return parsers.resolveKeywordValue(value); } else if (typeof value === "string") { return value; } @@ -43,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -57,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderBottomWidth.js b/lib/properties/borderBottomWidth.js index 5e6b682a..b0aefc83 100644 --- a/lib/properties/borderBottomWidth.js +++ b/lib/properties/borderBottomWidth.js @@ -7,7 +7,7 @@ const lineShorthand = "border-width"; const positionShorthand = "border-bottom"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,24 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLength(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -53,10 +39,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -67,3 +53,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderCollapse.js b/lib/properties/borderCollapse.js index 55e56866..d973ba2c 100644 --- a/lib/properties/borderCollapse.js +++ b/lib/properties/borderCollapse.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "border-collapse"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,14 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: - } + return parsers.resolveKeywordValue(value); } else if (typeof value === "string") { return value; } @@ -48,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderColor.js b/lib/properties/borderColor.js index 156bdd9e..46d05107 100644 --- a/lib/properties/borderColor.js +++ b/lib/properties/borderColor.js @@ -10,13 +10,13 @@ const property = "border-color"; const shorthand = "border"; module.exports.shorthandFor = new Map([ - ["border-top-color", borderTopColor], - ["border-right-color", borderRightColor], - ["border-bottom-color", borderBottomColor], - ["border-left-color", borderLeftColor] + [borderTopColor.property, borderTopColor], + [borderRightColor.property, borderRightColor], + [borderBottomColor.property, borderBottomColor], + [borderLeftColor.property, borderLeftColor] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -31,22 +31,13 @@ module.exports.parse = function parse(v, opt = {}) { return; } for (const value of values) { - const { name, type } = value; - switch (type) { - case "GlobalKeyword": { - if (values.length !== 1) { - return; - } - return name; - } - default: { - const parsedValue = parsers.parseColor([value]); - if (!parsedValue) { - return; - } - parsedValues.push(parsedValue); - } + const parsedValue = parsers.resolveColorValue([value], { + length: values.length + }); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } } else if (typeof values === "string") { parsedValues.push(values); @@ -101,9 +92,10 @@ module.exports.definition = { globalObject: this._global }); if (Array.isArray(val) || typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -114,3 +106,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderLeft.js b/lib/properties/borderLeft.js index aaf0e28e..5902fc9e 100644 --- a/lib/properties/borderLeft.js +++ b/lib/properties/borderLeft.js @@ -8,19 +8,25 @@ const borderLeftColor = require("./borderLeftColor"); const property = "border-left"; const shorthand = "border"; +const subProps = { + width: borderLeftWidth.property, + style: borderLeftStyle.property, + color: borderLeftColor.property +}; + module.exports.initialValues = new Map([ - ["border-left-width", "medium"], - ["border-left-style", "none"], - ["border-left-color", "currentcolor"] + [borderLeftWidth.property, "medium"], + [borderLeftStyle.property, "none"], + [borderLeftColor.property, "currentcolor"] ]); module.exports.shorthandFor = new Map([ - ["border-left-width", borderLeftWidth], - ["border-left-style", borderLeftStyle], - ["border-left-color", borderLeftColor] + [borderLeftWidth.property, borderLeftWidth], + [borderLeftStyle.property, borderLeftStyle], + [borderLeftColor.property, borderLeftColor] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -33,79 +39,14 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber || parsedValues.has("border-left-width")) { - return; - } - parsedValues.set("border-left-width", `${name}(${itemValue})`); - break; - } - case "Dimension": - case "Number": { - if (parsedValues.has("border-left-width")) { - return; - } - const parsedValue = parsers.parseLength(value, { - min: 0 - }); - if (!parsedValue) { - return; - } - parsedValues.set("border-left-width", parsedValue); - break; - } - case "Function": { - if (parsedValues.has("border-left-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-left-color", parsedValue); - break; - } - case "GlobalKeyword": { - return name; - } - case "Hash": { - if (parsedValues.has("border-left-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-left-color", parsedValue); - break; - } - case "Identifier": { - if (parsers.isValidPropertyValue("border-left-width", name)) { - if (parsedValues.has("border-left-width")) { - return; - } - parsedValues.set("border-left-width", name); - break; - } else if (parsers.isValidPropertyValue("border-left-style", name)) { - if (parsedValues.has("border-left-style")) { - return; - } - parsedValues.set("border-left-style", name); - break; - } else if (parsers.isValidPropertyValue("border-left-color", name)) { - if (parsedValues.has("border-left-color")) { - return; - } - parsedValues.set("border-left-color", name); - break; - } - return; - } - default: { - return; - } + const parsedValue = parsers.resolveBorderShorthandValue(value, subProps, parsedValues); + if (typeof parsedValue === "string") { + return parsedValue; + } else if (Array.isArray(parsedValue)) { + const [key, resolvedVal] = parsedValue; + parsedValues.set(key, resolvedVal); + } else { + return; } } else { return; @@ -114,15 +55,15 @@ module.exports.parse = function parse(v, opt = {}) { if (parsedValues.size) { const keys = module.exports.shorthandFor.keys(); const obj = { - "border-left-width": "medium" + [borderLeftWidth.property]: "medium" }; for (const key of keys) { if (parsedValues.has(key)) { const parsedValue = parsedValues.get(key); if (parsedValue !== module.exports.initialValues.get(key)) { obj[key] = parsedValues.get(key); - if (obj["border-left-width"] && obj["border-left-width"] === "medium") { - delete obj["border-left-width"]; + if (obj[borderLeftWidth.property] && obj[borderLeftWidth.property] === "medium") { + delete obj[borderLeftWidth.property]; } } } @@ -141,9 +82,10 @@ module.exports.definition = { globalObject: this._global }); if (val || typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -154,3 +96,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderLeftColor.js b/lib/properties/borderLeftColor.js index d9c6b498..cd380c2d 100644 --- a/lib/properties/borderLeftColor.js +++ b/lib/properties/borderLeftColor.js @@ -7,7 +7,7 @@ const lineShorthand = "border-color"; const positionShorthand = "border-left"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,15 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -44,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -58,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderLeftStyle.js b/lib/properties/borderLeftStyle.js index 115106a1..ee1af4ef 100644 --- a/lib/properties/borderLeftStyle.js +++ b/lib/properties/borderLeftStyle.js @@ -7,7 +7,7 @@ const lineShorthand = "border-style"; const positionShorthand = "border-left"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,14 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: - } + return parsers.resolveKeywordValue(value); } else if (typeof value === "string") { return value; } @@ -43,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -57,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderLeftWidth.js b/lib/properties/borderLeftWidth.js index 51e20652..b1f3b37b 100644 --- a/lib/properties/borderLeftWidth.js +++ b/lib/properties/borderLeftWidth.js @@ -7,7 +7,7 @@ const lineShorthand = "border-width"; const positionShorthand = "border-left"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,24 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLength(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -53,10 +39,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -67,3 +53,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderRight.js b/lib/properties/borderRight.js index cf1507e9..0b8305c9 100644 --- a/lib/properties/borderRight.js +++ b/lib/properties/borderRight.js @@ -8,19 +8,25 @@ const borderRightColor = require("./borderRightColor"); const property = "border-right"; const shorthand = "border"; +const subProps = { + width: borderRightWidth.property, + style: borderRightStyle.property, + color: borderRightColor.property +}; + module.exports.initialValues = new Map([ - ["border-right-width", "medium"], - ["border-right-style", "none"], - ["border-right-color", "currentcolor"] + [borderRightWidth.property, "medium"], + [borderRightStyle.property, "none"], + [borderRightColor.property, "currentcolor"] ]); module.exports.shorthandFor = new Map([ - ["border-right-width", borderRightWidth], - ["border-right-style", borderRightStyle], - ["border-right-color", borderRightColor] + [borderRightWidth.property, borderRightWidth], + [borderRightStyle.property, borderRightStyle], + [borderRightColor.property, borderRightColor] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -33,79 +39,14 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber || parsedValues.has("border-right-width")) { - return; - } - parsedValues.set("border-right-width", `${name}(${itemValue})`); - break; - } - case "Dimension": - case "Number": { - if (parsedValues.has("border-right-width")) { - return; - } - const parsedValue = parsers.parseLength(value, { - min: 0 - }); - if (!parsedValue) { - return; - } - parsedValues.set("border-right-width", parsedValue); - break; - } - case "Function": { - if (parsedValues.has("border-right-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-right-color", parsedValue); - break; - } - case "GlobalKeyword": { - return name; - } - case "Hash": { - if (parsedValues.has("border-right-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-right-color", parsedValue); - break; - } - case "Identifier": { - if (parsers.isValidPropertyValue("border-right-width", name)) { - if (parsedValues.has("border-right-width")) { - return; - } - parsedValues.set("border-right-width", name); - break; - } else if (parsers.isValidPropertyValue("border-right-style", name)) { - if (parsedValues.has("border-right-style")) { - return; - } - parsedValues.set("border-right-style", name); - break; - } else if (parsers.isValidPropertyValue("border-right-color", name)) { - if (parsedValues.has("border-right-color")) { - return; - } - parsedValues.set("border-right-color", name); - break; - } - return; - } - default: { - return; - } + const parsedValue = parsers.resolveBorderShorthandValue(value, subProps, parsedValues); + if (typeof parsedValue === "string") { + return parsedValue; + } else if (Array.isArray(parsedValue)) { + const [key, resolvedVal] = parsedValue; + parsedValues.set(key, resolvedVal); + } else { + return; } } else { return; @@ -114,15 +55,15 @@ module.exports.parse = function parse(v, opt = {}) { if (parsedValues.size) { const keys = module.exports.shorthandFor.keys(); const obj = { - "border-right-width": "medium" + [borderRightWidth.property]: "medium" }; for (const key of keys) { if (parsedValues.has(key)) { const parsedValue = parsedValues.get(key); if (parsedValue !== module.exports.initialValues.get(key)) { obj[key] = parsedValues.get(key); - if (obj["border-right-width"] && obj["border-right-width"] === "medium") { - delete obj["border-right-width"]; + if (obj[borderRightWidth.property] && obj[borderRightWidth.property] === "medium") { + delete obj[borderRightWidth.property]; } } } @@ -141,9 +82,10 @@ module.exports.definition = { globalObject: this._global }); if (val || typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -154,3 +96,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderRightColor.js b/lib/properties/borderRightColor.js index 807b6df4..3ecf9e47 100644 --- a/lib/properties/borderRightColor.js +++ b/lib/properties/borderRightColor.js @@ -7,7 +7,7 @@ const lineShorthand = "border-color"; const positionShorthand = "border-right"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,15 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -44,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -58,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderRightStyle.js b/lib/properties/borderRightStyle.js index 0d343c3b..a4923671 100644 --- a/lib/properties/borderRightStyle.js +++ b/lib/properties/borderRightStyle.js @@ -7,7 +7,7 @@ const lineShorthand = "border-style"; const positionShorthand = "border-right"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,14 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: - } + return parsers.resolveKeywordValue(value); } else if (typeof value === "string") { return value; } @@ -43,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -57,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderRightWidth.js b/lib/properties/borderRightWidth.js index f4c5147d..a8d783a2 100644 --- a/lib/properties/borderRightWidth.js +++ b/lib/properties/borderRightWidth.js @@ -7,7 +7,7 @@ const lineShorthand = "border-width"; const positionShorthand = "border-right"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,24 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLength(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -53,10 +39,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -67,3 +53,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderSpacing.js b/lib/properties/borderSpacing.js index d33df5a3..c39e89b2 100644 --- a/lib/properties/borderSpacing.js +++ b/lib/properties/borderSpacing.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "border-spacing"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -16,17 +16,18 @@ module.exports.parse = function parse(v, opt = {}) { if (Array.isArray(value) && value.length) { switch (value.length) { case 1: { - const [part1] = value; - const val1 = parsers.parseLength([part1]); - if (val1) { - return val1; - } - break; + return parsers.resolveNumericValue(value, { + type: "length" + }); } case 2: { const [part1, part2] = value; - const val1 = parsers.parseLength([part1]); - const val2 = parsers.parseLength([part2]); + const val1 = parsers.resolveNumericValue([part1], { + type: "length" + }); + const val2 = parsers.resolveNumericValue([part2], { + type: "length" + }); if (val1 && val2) { return `${val1} ${val2}`; } @@ -60,3 +61,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderStyle.js b/lib/properties/borderStyle.js index ebeddbeb..7cac5ab5 100644 --- a/lib/properties/borderStyle.js +++ b/lib/properties/borderStyle.js @@ -10,13 +10,13 @@ const property = "border-style"; const shorthand = "border"; module.exports.shorthandFor = new Map([ - ["border-top-style", borderTopStyle], - ["border-right-style", borderRightStyle], - ["border-bottom-style", borderBottomStyle], - ["border-left-style", borderLeftStyle] + [borderTopStyle.property, borderTopStyle], + [borderRightStyle.property, borderRightStyle], + [borderBottomStyle.property, borderBottomStyle], + [borderLeftStyle.property, borderLeftStyle] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -31,22 +31,13 @@ module.exports.parse = function parse(v, opt = {}) { return; } for (const value of values) { - const { name, type } = value; - switch (type) { - case "GlobalKeyword": { - if (values.length !== 1) { - return; - } - return name; - } - case "Identifier": { - parsedValues.push(name); - break; - } - default: { - return; - } + const parsedValue = parsers.resolveKeywordValue([value], { + length: values.length + }); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } } else if (typeof values === "string") { parsedValues.push(values); @@ -101,9 +92,10 @@ module.exports.definition = { globalObject: this._global }); if (Array.isArray(val) || typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -114,3 +106,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderTop.js b/lib/properties/borderTop.js index 80dec4f0..cf156815 100644 --- a/lib/properties/borderTop.js +++ b/lib/properties/borderTop.js @@ -8,19 +8,25 @@ const borderTopColor = require("./borderTopColor"); const property = "border-top"; const shorthand = "border"; +const subProps = { + width: borderTopWidth.property, + style: borderTopStyle.property, + color: borderTopColor.property +}; + module.exports.initialValues = new Map([ - ["border-top-width", "medium"], - ["border-top-style", "none"], - ["border-top-color", "currentcolor"] + [borderTopWidth.property, "medium"], + [borderTopStyle.property, "none"], + [borderTopColor.property, "currentcolor"] ]); module.exports.shorthandFor = new Map([ - ["border-top-width", borderTopWidth], - ["border-top-style", borderTopStyle], - ["border-top-color", borderTopColor] + [borderTopWidth.property, borderTopWidth], + [borderTopStyle.property, borderTopStyle], + [borderTopColor.property, borderTopColor] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -33,79 +39,14 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber || parsedValues.has("border-top-width")) { - return; - } - parsedValues.set("border-top-width", `${name}(${itemValue})`); - break; - } - case "Dimension": - case "Number": { - if (parsedValues.has("border-top-width")) { - return; - } - const parsedValue = parsers.parseLength(value, { - min: 0 - }); - if (!parsedValue) { - return; - } - parsedValues.set("border-top-width", parsedValue); - break; - } - case "Function": { - if (parsedValues.has("border-top-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-top-color", parsedValue); - break; - } - case "GlobalKeyword": { - return name; - } - case "Hash": { - if (parsedValues.has("border-top-color")) { - return; - } - const parsedValue = parsers.parseColor(value); - if (!parsedValue) { - return; - } - parsedValues.set("border-top-color", parsedValue); - break; - } - case "Identifier": { - if (parsers.isValidPropertyValue("border-top-width", name)) { - if (parsedValues.has("border-top-width")) { - return; - } - parsedValues.set("border-top-width", name); - break; - } else if (parsers.isValidPropertyValue("border-top-style", name)) { - if (parsedValues.has("border-top-style")) { - return; - } - parsedValues.set("border-top-style", name); - break; - } else if (parsers.isValidPropertyValue("border-top-color", name)) { - if (parsedValues.has("border-top-color")) { - return; - } - parsedValues.set("border-top-color", name); - break; - } - return; - } - default: { - return; - } + const parsedValue = parsers.resolveBorderShorthandValue(value, subProps, parsedValues); + if (typeof parsedValue === "string") { + return parsedValue; + } else if (Array.isArray(parsedValue)) { + const [key, resolvedVal] = parsedValue; + parsedValues.set(key, resolvedVal); + } else { + return; } } else { return; @@ -114,15 +55,15 @@ module.exports.parse = function parse(v, opt = {}) { if (parsedValues.size) { const keys = module.exports.shorthandFor.keys(); const obj = { - "border-top-width": "medium" + [borderTopWidth.property]: "medium" }; for (const key of keys) { if (parsedValues.has(key)) { const parsedValue = parsedValues.get(key); if (parsedValue !== module.exports.initialValues.get(key)) { obj[key] = parsedValues.get(key); - if (obj["border-top-width"] && obj["border-top-width"] === "medium") { - delete obj["border-top-width"]; + if (obj[borderTopWidth.property] && obj[borderTopWidth.property] === "medium") { + delete obj[borderTopWidth.property]; } } } @@ -141,9 +82,10 @@ module.exports.definition = { globalObject: this._global }); if (val || typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -154,3 +96,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderTopColor.js b/lib/properties/borderTopColor.js index 8acfa672..8f4df3f7 100644 --- a/lib/properties/borderTopColor.js +++ b/lib/properties/borderTopColor.js @@ -7,7 +7,7 @@ const lineShorthand = "border-color"; const positionShorthand = "border-top"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,15 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -44,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -58,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderTopStyle.js b/lib/properties/borderTopStyle.js index a90c2f68..42e81e5a 100644 --- a/lib/properties/borderTopStyle.js +++ b/lib/properties/borderTopStyle.js @@ -7,7 +7,7 @@ const lineShorthand = "border-style"; const positionShorthand = "border-top"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,14 +17,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: - } + return parsers.resolveKeywordValue(value); } else if (typeof value === "string") { return value; } @@ -43,10 +36,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -57,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderTopWidth.js b/lib/properties/borderTopWidth.js index f97d124c..15684454 100644 --- a/lib/properties/borderTopWidth.js +++ b/lib/properties/borderTopWidth.js @@ -7,7 +7,7 @@ const lineShorthand = "border-width"; const positionShorthand = "border-top"; const shorthand = "border"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,24 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLength(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -53,10 +39,10 @@ module.exports.definition = { const shorthandPriority = this._priorities.get(shorthand); const linePriority = this._priorities.get(lineShorthand); const positionPriority = this._priorities.get(positionShorthand); - let priority = this._priorities.get(property) ?? ""; - if ((shorthandPriority || linePriority || positionPriority) && priority) { - priority = ""; - } + const priority = + !(shorthandPriority || linePriority || positionPriority) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -67,3 +53,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/borderWidth.js b/lib/properties/borderWidth.js index b34496fa..45257763 100644 --- a/lib/properties/borderWidth.js +++ b/lib/properties/borderWidth.js @@ -10,13 +10,13 @@ const property = "border-width"; const shorthand = "border"; module.exports.shorthandFor = new Map([ - ["border-top-width", borderTopWidth], - ["border-right-width", borderRightWidth], - ["border-bottom-width", borderBottomWidth], - ["border-left-width", borderLeftWidth] + [borderTopWidth.property, borderTopWidth], + [borderRightWidth.property, borderRightWidth], + [borderBottomWidth.property, borderBottomWidth], + [borderLeftWidth.property, borderLeftWidth] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -31,35 +31,14 @@ module.exports.parse = function parse(v, opt = {}) { return; } for (const value of values) { - const { isNumber, name, type, value: itemValue } = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - parsedValues.push(`${name}(${itemValue})`); - break; - } - case "GlobalKeyword": { - if (values.length !== 1) { - return; - } - return name; - } - case "Identifier": { - parsedValues.push(name); - break; - } - default: { - const parsedValue = parsers.parseLength([value], { - min: 0 - }); - if (!parsedValue) { - return; - } - parsedValues.push(parsedValue); - } + const parsedValue = parsers.resolveNumericValue([value], { + length: values.length, + type: "length" + }); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } } else if (typeof values === "string") { parsedValues.push(values); @@ -114,9 +93,10 @@ module.exports.definition = { globalObject: this._global }); if (Array.isArray(val) || typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._borderSetter(property, val, priority); } } @@ -127,3 +107,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/bottom.js b/lib/properties/bottom.js index 0e1902d1..360dfed1 100644 --- a/lib/properties/bottom.js +++ b/lib/properties/bottom.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "bottom"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,22 +14,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, raw, type }] = value; - switch (type) { - case "Calc": { - if (!isNumber) { - return raw; - } - break; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -56,3 +43,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/clear.js b/lib/properties/clear.js index cfd39c36..3274cbbf 100644 --- a/lib/properties/clear.js +++ b/lib/properties/clear.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "clear"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,14 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: - } + return parsers.resolveKeywordValue(value); } else if (typeof value === "string") { return value; } @@ -48,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/clip.js b/lib/properties/clip.js index 7670a77c..b100be24 100644 --- a/lib/properties/clip.js +++ b/lib/properties/clip.js @@ -6,11 +6,12 @@ const parsers = require("../parsers"); const property = "clip"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const value = parsers.parsePropertyValue(property, v, { globalObject, inArray: true @@ -18,14 +19,16 @@ module.exports.parse = function parse(v, opt = {}) { if (Array.isArray(value) && value.length === 1) { const [{ name, type, value: itemValue }] = value; switch (type) { - case "Function": { + case AST_TYPES.FUNCTION: { const values = parsers.splitValue(itemValue, { delimiter: "," }); const parsedValues = []; for (const item of values) { const parsedValue = parsers.parseCSS(item, { context: "value" }, true); - const val = parsers.parseLength(parsedValue.children); + const val = parsers.resolveNumericValue(parsedValue.children, { + type: "length" + }); if (val) { parsedValues.push(val); } else { @@ -34,8 +37,8 @@ module.exports.parse = function parse(v, opt = {}) { } return `${name}(${parsedValues.join(", ")})`; } - case "GlobalKeyword": - case "Identifier": { + case AST_TYPES.GLOBAL_KEYWORD: + case AST_TYPES.IDENTIFIER: { return name; } default: @@ -66,3 +69,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/color.js b/lib/properties/color.js index 74e398d0..80f8c8ca 100644 --- a/lib/properties/color.js +++ b/lib/properties/color.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/display.js b/lib/properties/display.js index fb45c479..c6cff918 100644 --- a/lib/properties/display.js +++ b/lib/properties/display.js @@ -8,11 +8,12 @@ const property = "display"; const displayOutside = ["block", "inline", "run-in"]; const displayFlow = ["flow", "flow-root"]; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const value = parsers.parsePropertyValue(property, v, { globalObject, inArray: true @@ -22,10 +23,10 @@ module.exports.parse = function parse(v, opt = {}) { case 1: { const [{ name, type }] = value; switch (type) { - case "GlobalKeyword": { + case AST_TYPES.GLOBAL_KEYWORD: { return name; } - case "Identifier": { + case AST_TYPES.IDENTIFIER: { if (name === "flow") { return "block"; } @@ -37,8 +38,8 @@ module.exports.parse = function parse(v, opt = {}) { } case 2: { const [part1, part2] = value; - const val1 = part1.type === "Identifier" && part1.name; - const val2 = part2.type === "Identifier" && part2.name; + const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name; + const val2 = part2.type === AST_TYPES.IDENTIFIER && part2.name; if (val1 && val2) { let outerValue = ""; let innerValue = ""; @@ -122,9 +123,9 @@ module.exports.parse = function parse(v, opt = {}) { } case 3: { const [part1, part2, part3] = value; - const val1 = part1.type === "Identifier" && part1.name; - const val2 = part2.type === "Identifier" && part2.name; - const val3 = part3.type === "Identifier" && part3.name; + const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name; + const val2 = part2.type === AST_TYPES.IDENTIFIER && part2.name; + const val3 = part3.type === AST_TYPES.IDENTIFIER && part3.name; if (val1 && val2 && part3) { let outerValue = ""; let flowValue = ""; @@ -205,3 +206,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/flex.js b/lib/properties/flex.js index a319060e..94bff221 100644 --- a/lib/properties/flex.js +++ b/lib/properties/flex.js @@ -8,123 +8,124 @@ const flexBasis = require("./flexBasis"); const property = "flex"; module.exports.initialValues = new Map([ - ["flex-grow", "0"], - ["flex-shrink", "1"], - ["flex-basis", "auto"] + [flexGrow.property, "0"], + [flexShrink.property, "1"], + [flexBasis.property, "auto"] ]); module.exports.shorthandFor = new Map([ - ["flex-grow", flexGrow], - ["flex-shrink", flexShrink], - ["flex-basis", flexBasis] + [flexGrow.property, flexGrow], + [flexShrink.property, flexShrink], + [flexBasis.property, flexBasis] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const value = parsers.parsePropertyValue(property, v, { globalObject, inArray: true }); if (Array.isArray(value) && value.length) { const flex = { - "flex-grow": "1", - "flex-shrink": "1", - "flex-basis": "0%" + [flexGrow.property]: "1", + [flexShrink.property]: "1", + [flexBasis.property]: "0%" }; if (value.length === 1) { const [{ isNumber, name, type, unit, value: itemValue }] = value; switch (type) { - case "Calc": { + case AST_TYPES.CALC: { if (isNumber) { - flex["flex-grow"] = `${name}(${itemValue})`; + flex[flexGrow.property] = `${name}(${itemValue})`; return flex; } - flex["flex-basis"] = `${name}(${itemValue})`; + flex[flexBasis.property] = `${name}(${itemValue})`; return flex; } - case "Dimension": { - flex["flex-basis"] = `${itemValue}${unit}`; + case AST_TYPES.DIMENSION: { + flex[flexBasis.property] = `${itemValue}${unit}`; return flex; } - case "GlobalKeyword": { + case AST_TYPES.GLOBAL_KEYWORD: { return name; } - case "Identifier": { + case AST_TYPES.IDENTIFIER: { if (name === "none") { return { - "flex-grow": "0", - "flex-shrink": "0", - "flex-basis": "auto" + [flexGrow.property]: "0", + [flexShrink.property]: "0", + [flexBasis.property]: "auto" }; } - flex["flex-basis"] = name; + flex[flexBasis.property] = name; return flex; } - case "Number": { - flex["flex-grow"] = itemValue; + case AST_TYPES.NUMBER: { + flex[flexGrow.property] = itemValue; return flex; } - case "Percentage": { - flex["flex-basis"] = `${itemValue}%`; + case AST_TYPES.PERCENTAGE: { + flex[flexBasis.property] = `${itemValue}%`; return flex; } default: } } else { const [val1, val2, val3] = value; - if (val1.type === "Calc" && val1.isNumber) { - flex["flex-grow"] = `${val1.name}(${val1.value})`; - } else if (val1.type === "Number") { - flex["flex-grow"] = val1.value; + if (val1.type === AST_TYPES.CALC && val1.isNumber) { + flex[flexGrow.property] = `${val1.name}(${val1.value})`; + } else if (val1.type === AST_TYPES.NUMBER) { + flex[flexGrow.property] = val1.value; } else { return; } if (val3) { - if (val2.type === "Calc" && val2.isNumber) { - flex["flex-shrink"] = `${val2.name}(${val2.value})`; - } else if (val2.type === "Number") { - flex["flex-shrink"] = val2.value; + if (val2.type === AST_TYPES.CALC && val2.isNumber) { + flex[flexShrink.property] = `${val2.name}(${val2.value})`; + } else if (val2.type === AST_TYPES.NUMBER) { + flex[flexShrink.property] = val2.value; } else { return; } - if (val3.type === "GlobalKeyword" || val3.type === "Identifier") { - flex["flex-basis"] = val3.name; - } else if (val3.type === "Calc" && !val3.isNumber) { - flex["flex-basis"] = `${val3.name}(${val3.value})`; - } else if (val3.type === "Dimension") { - flex["flex-basis"] = `${val3.value}${val3.unit}`; - } else if (val3.type === "Percentage") { - flex["flex-basis"] = `${val3.value}%`; + if (val3.type === AST_TYPES.GLOBAL_KEYWORD || val3.type === AST_TYPES.IDENTIFIER) { + flex[flexBasis.property] = val3.name; + } else if (val3.type === AST_TYPES.CALC && !val3.isNumber) { + flex[flexBasis.property] = `${val3.name}(${val3.value})`; + } else if (val3.type === AST_TYPES.DIMENSION) { + flex[flexBasis.property] = `${val3.value}${val3.unit}`; + } else if (val3.type === AST_TYPES.PERCENTAGE) { + flex[flexBasis.property] = `${val3.value}%`; } else { return; } } else { switch (val2.type) { - case "Calc": { + case AST_TYPES.CALC: { if (val2.isNumber) { - flex["flex-shrink"] = `${val2.name}(${val2.value})`; + flex[flexShrink.property] = `${val2.name}(${val2.value})`; } else { - flex["flex-basis"] = `${val2.name}(${val2.value})`; + flex[flexBasis.property] = `${val2.name}(${val2.value})`; } break; } - case "Dimension": { - flex["flex-basis"] = `${val2.value}${val2.unit}`; + case AST_TYPES.DIMENSION: { + flex[flexBasis.property] = `${val2.value}${val2.unit}`; break; } - case "Number": { - flex["flex-shrink"] = val2.value; + case AST_TYPES.NUMBER: { + flex[flexShrink.property] = val2.value; break; } - case "Percentage": { - flex["flex-basis"] = `${val2.value}%`; + case AST_TYPES.PERCENTAGE: { + flex[flexBasis.property] = `${val2.value}%`; break; } - case "Identifier": { - flex["flex-basis"] = val2.name; + case AST_TYPES.IDENTIFIER: { + flex[flexBasis.property] = val2.name; break; } default: { @@ -133,7 +134,6 @@ module.exports.parse = function parse(v, opt = {}) { } } return flex; - // return [...Object.values(flex)].join(" "); } } else if (typeof value === "string") { return value; @@ -174,3 +174,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/flexBasis.js b/lib/properties/flexBasis.js index 194ba579..4f9a0016 100644 --- a/lib/properties/flexBasis.js +++ b/lib/properties/flexBasis.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "flex-basis"; const shorthand = "flex"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -15,22 +15,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -47,9 +34,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._flexBoxSetter(property, val, priority, shorthand); } } @@ -60,3 +48,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/flexGrow.js b/lib/properties/flexGrow.js index 89537d09..c43c755d 100644 --- a/lib/properties/flexGrow.js +++ b/lib/properties/flexGrow.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "flex-grow"; const shorthand = "flex"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -15,21 +15,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return `${name}(${itemValue})`; - } - break; - } - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseNumber(value); - } - } + return parsers.resolveNumericValue(value, { + min: 0 + }); } else if (typeof value === "string") { return value; } @@ -46,9 +34,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._flexBoxSetter(property, val, priority, shorthand); } } @@ -59,3 +48,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/flexShrink.js b/lib/properties/flexShrink.js index 7b205a4b..5483b3b3 100644 --- a/lib/properties/flexShrink.js +++ b/lib/properties/flexShrink.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "flex-shrink"; const shorthand = "flex"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -15,21 +15,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return `${name}(${itemValue})`; - } - break; - } - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseNumber(value); - } - } + return parsers.resolveNumericValue(value, { + min: 0 + }); } else if (typeof value === "string") { return value; } @@ -46,9 +34,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._flexBoxSetter(property, val, priority, shorthand); } } @@ -59,3 +48,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/float.js b/lib/properties/float.js index 3e256318..607f861b 100644 --- a/lib/properties/float.js +++ b/lib/properties/float.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "float"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,14 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: - } + return parsers.resolveKeywordValue(value); } else if (typeof value === "string") { return value; } @@ -48,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/floodColor.js b/lib/properties/floodColor.js index 280bb112..6ebd5788 100644 --- a/lib/properties/floodColor.js +++ b/lib/properties/floodColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "flood-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/font.js b/lib/properties/font.js index 4cbcf553..4b22af44 100644 --- a/lib/properties/font.js +++ b/lib/properties/font.js @@ -11,15 +11,15 @@ const fontFamily = require("./fontFamily"); const property = "font"; module.exports.shorthandFor = new Map([ - ["font-style", fontStyle], - ["font-variant", fontVariant], - ["font-weight", fontWeight], - ["font-size", fontSize], - ["line-height", lineHeight], - ["font-family", fontFamily] + [fontStyle.property, fontStyle], + [fontVariant.property, fontVariant], + [fontWeight.property, fontWeight], + [fontSize.property, fontSize], + [lineHeight.property, lineHeight], + [fontFamily.property, fontFamily] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -29,6 +29,7 @@ module.exports.parse = function parse(v, opt = {}) { if (!parsers.isValidPropertyValue(property, v)) { return; } + const { AST_TYPES } = parsers; const [fontBlock, ...families] = parsers.splitValue(v, { delimiter: "," }); @@ -36,9 +37,9 @@ module.exports.parse = function parse(v, opt = {}) { delimiter: "/" }); const font = { - "font-style": "normal", - "font-variant": "normal", - "font-weight": "normal" + [fontStyle.property]: "normal", + [fontVariant.property]: "normal", + [fontWeight.property]: "normal" }; const fontFamilies = new Set(); if (fontBlockB) { @@ -62,14 +63,19 @@ module.exports.parse = function parse(v, opt = {}) { return; } const parts = parsers.splitValue(fontBlockA.trim()); - const properties = ["font-style", "font-variant", "font-weight", "font-size"]; + const properties = [ + fontStyle.property, + fontVariant.property, + fontWeight.property, + fontSize.property + ]; for (const part of parts) { if (part === "normal") { continue; } else { for (const longhand of properties) { switch (longhand) { - case "font-size": { + case fontSize.property: { const parsedValue = fontSize.parse(part, { globalObject }); @@ -78,8 +84,8 @@ module.exports.parse = function parse(v, opt = {}) { } break; } - case "font-style": - case "font-weight": { + case fontStyle.property: + case fontWeight.property: { if (font[longhand] === "normal") { const longhandItem = module.exports.shorthandFor.get(longhand); const parsedValue = longhandItem.parse(part, { @@ -91,7 +97,7 @@ module.exports.parse = function parse(v, opt = {}) { } break; } - case "font-variant": { + case fontVariant.property: { if (font[longhand] === "normal") { const parsedValue = fontVariant.parse(part, { globalObject @@ -111,8 +117,8 @@ module.exports.parse = function parse(v, opt = {}) { } } } - if (Object.hasOwn(font, "font-size")) { - font["line-height"] = lineHeightB; + if (Object.hasOwn(font, fontSize.property)) { + font[lineHeight.property] = lineHeightB; } else { return; } @@ -126,20 +132,25 @@ module.exports.parse = function parse(v, opt = {}) { }); if (Array.isArray(value) && value.length === 1) { const [{ name, type }] = value; - if (type === "GlobalKeyword") { + if (type === AST_TYPES.GLOBAL_KEYWORD) { return { - "font-style": name, - "font-variant": name, - "font-weight": name, - "font-size": name, - "line-height": name, - "font-family": name + [fontStyle.property]: name, + [fontVariant.property]: name, + [fontWeight.property]: name, + [fontSize.property]: name, + [lineHeight.property]: name, + [fontFamily.property]: name }; } } return; } - const properties = ["font-style", "font-variant", "font-weight", "line-height"]; + const properties = [ + fontStyle.property, + fontVariant.property, + fontWeight.property, + lineHeight.property + ]; for (const longhand of properties) { font[longhand] = "normal"; } @@ -152,9 +163,9 @@ module.exports.parse = function parse(v, opt = {}) { } else { for (const longhand of properties) { switch (longhand) { - case "font-style": - case "font-weight": - case "line-height": { + case fontStyle.property: + case fontWeight.property: + case lineHeight.property: { if (font[longhand] === "normal") { const longhandItem = module.exports.shorthandFor.get(longhand); const parsedValue = longhandItem.parse(part, { @@ -166,7 +177,7 @@ module.exports.parse = function parse(v, opt = {}) { } break; } - case "font-variant": { + case fontVariant.property: { if (font[longhand] === "normal") { const parsedValue = fontVariant.parse(part, { globalObject @@ -209,7 +220,7 @@ module.exports.parse = function parse(v, opt = {}) { caseSensitive: true }); if (fontSizeA && family) { - font["font-size"] = fontSizeA; + font[fontSize.property] = fontSizeA; fontFamilies.add(fontFamily.parse(family)); } else { return; @@ -226,7 +237,7 @@ module.exports.parse = function parse(v, opt = {}) { return; } } - font["font-family"] = [...fontFamilies].join(", "); + font[fontFamily.property] = [...fontFamilies].join(", "); return font; }; @@ -252,7 +263,7 @@ module.exports.definition = { if (typeof val === "string") { this._setProperty(key, val, priority); if (val && val !== "normal" && !str.has(val)) { - if (key === "line-height") { + if (key === lineHeight.property) { str.add(`/ ${val}`); } else { str.add(val); @@ -275,7 +286,7 @@ module.exports.definition = { return ""; } if (v && v !== "normal" && !str.has(v)) { - if (key === "line-height") { + if (key === lineHeight.property) { str.add(`/ ${v}`); } else { str.add(`${v}`); @@ -287,3 +298,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/fontFamily.js b/lib/properties/fontFamily.js index db57001d..8c4dd9d8 100644 --- a/lib/properties/fontFamily.js +++ b/lib/properties/fontFamily.js @@ -5,11 +5,12 @@ const parsers = require("../parsers"); const property = "font-family"; const shorthand = "font"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const values = parsers.splitValue(v, { delimiter: "," }); @@ -24,15 +25,16 @@ module.exports.parse = function parse(v, opt = {}) { if (value.length === 1) { const [{ name, type, value: itemValue }] = value; switch (type) { - case "Function": { + case AST_TYPES.FUNCTION: { parsedValues.push(`${name}(${itemValue})`); break; } - case "GlobalKeyword": - case "Identifier": { - if (name !== "undefined") { - parsedValues.push(name); + case AST_TYPES.GLOBAL_KEYWORD: + case AST_TYPES.IDENTIFIER: { + if (name === "undefined") { + return; } + parsedValues.push(name); break; } case "String": { @@ -48,11 +50,10 @@ module.exports.parse = function parse(v, opt = {}) { const parts = []; for (const item of value) { const { name, type } = item; - if (type === "Identifier") { - parts.push(name); - } else { + if (type !== AST_TYPES.IDENTIFIER) { return; } + parts.push(name); } const parsedValue = parts.join(" ").replaceAll("\\", "").replaceAll('"', '\\"'); parsedValues.push(`"${parsedValue}"`); @@ -79,9 +80,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -92,3 +94,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/fontSize.js b/lib/properties/fontSize.js index cdffa8e7..efed0088 100644 --- a/lib/properties/fontSize.js +++ b/lib/properties/fontSize.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "font-size"; const shorthand = "font"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -15,24 +15,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -49,9 +35,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -62,3 +49,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/fontStyle.js b/lib/properties/fontStyle.js index b296798d..7b7c45ca 100644 --- a/lib/properties/fontStyle.js +++ b/lib/properties/fontStyle.js @@ -5,11 +5,12 @@ const parsers = require("../parsers"); const property = "font-style"; const shorthand = "font"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; } + const { AST_TYPES } = parsers; const value = parsers.parsePropertyValue(property, v, { globalObject, inArray: true @@ -18,16 +19,18 @@ module.exports.parse = function parse(v, opt = {}) { if (value.length === 1) { const [{ name, type }] = value; switch (type) { - case "GlobalKeyword": - case "Identifier": { + case AST_TYPES.GLOBAL_KEYWORD: + case AST_TYPES.IDENTIFIER: { return name; } default: } } else if (value.length === 2) { const [part1, part2] = value; - const val1 = part1.type === "Identifier" && part1.name; - const val2 = parsers.parseAngle([part2]); + const val1 = part1.type === AST_TYPES.IDENTIFIER && part1.name; + const val2 = parsers.resolveNumericValue([part2], { + type: "angle" + }); if (val1 && val1 === "oblique" && val2) { return `${val1} ${val2}`; } @@ -48,9 +51,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -61,3 +65,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/fontVariant.js b/lib/properties/fontVariant.js index b0d7749d..06a93bd5 100644 --- a/lib/properties/fontVariant.js +++ b/lib/properties/fontVariant.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "font-variant"; const shorthand = "font"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -18,21 +18,11 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type, value: itemValue }] = value; - switch (type) { - case "Function": { - parsedValues.push(`${name}(${itemValue})`); - break; - } - case "GlobalKeyword": - case "Identifier": { - parsedValues.push(name); - break; - } - default: { - return; - } + const parsedValue = parsers.resolveFunctionValue(value); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } else if (typeof value === "string") { parsedValues.push(value); } @@ -58,9 +48,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -71,3 +62,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/fontWeight.js b/lib/properties/fontWeight.js index d115a9dd..2eb48c64 100644 --- a/lib/properties/fontWeight.js +++ b/lib/properties/fontWeight.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "font-weight"; const shorthand = "font"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -15,28 +15,14 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return `${name}(${itemValue})`; - } - break; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - const parsedValue = parsers.parseNumber(value, { - min: 1, - max: 1000 - }); - if (parsedValue) { - return parsedValue; - } - } + const parsedValue = parsers.resolveNumericValue(value, { + min: 1, + max: 1000 + }); + if (!parsedValue) { + return; } + return parsedValue; } else if (typeof value === "string") { return value; } @@ -53,9 +39,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -66,3 +53,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/height.js b/lib/properties/height.js index 977d05f7..a2b47d55 100644 --- a/lib/properties/height.js +++ b/lib/properties/height.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "height"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,22 +14,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -56,3 +44,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/left.js b/lib/properties/left.js index 8b8b8d01..888f6c6a 100644 --- a/lib/properties/left.js +++ b/lib/properties/left.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "left"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,22 +14,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -56,3 +43,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/lightingColor.js b/lib/properties/lightingColor.js index e1e321d4..3cb4c72b 100644 --- a/lib/properties/lightingColor.js +++ b/lib/properties/lightingColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "lighting-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/lineHeight.js b/lib/properties/lineHeight.js index f7eb7598..dcc56a55 100644 --- a/lib/properties/lineHeight.js +++ b/lib/properties/lineHeight.js @@ -5,7 +5,7 @@ const parsers = require("../parsers"); const property = "line-height"; const shorthand = "font"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -15,26 +15,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - case "Number": { - return parsers.parseNumber(value, { - min: 0 - }); - } - default: { - return parsers.parseLengthPercentage(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0 + }); } else if (typeof value === "string") { return value; } @@ -51,9 +34,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._setProperty(property, val, priority); } } @@ -64,3 +48,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/margin.js b/lib/properties/margin.js index df68cc04..bc715400 100644 --- a/lib/properties/margin.js +++ b/lib/properties/margin.js @@ -11,13 +11,13 @@ const property = "margin"; module.exports.position = "edges"; module.exports.shorthandFor = new Map([ - ["margin-top", marginTop], - ["margin-right", marginRight], - ["margin-bottom", marginBottom], - ["margin-left", marginLeft] + [marginTop.property, marginTop], + [marginRight.property, marginRight], + [marginBottom.property, marginBottom], + [marginLeft.property, marginLeft] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -32,34 +32,14 @@ module.exports.parse = function parse(v, opt = {}) { return; } for (const value of values) { - const { isNumber, name, type, value: itemValue } = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - parsedValues.push(`${name}(${itemValue})`); - break; - } - case "GlobalKeyword": { - if (values.length !== 1) { - return; - } - parsedValues.push(name); - break; - } - case "Identifier": { - parsedValues.push(name); - break; - } - default: { - const parsedValue = parsers.parseLengthPercentage([value]); - if (!parsedValue) { - return; - } - parsedValues.push(parsedValue); - } + const parsedValue = parsers.resolveNumericValue([value], { + length: values.length, + type: "length" + }); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } } else if (typeof values === "string") { parsedValues.push(values); @@ -93,3 +73,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/marginBottom.js b/lib/properties/marginBottom.js index 26aa15c0..0ecbaecf 100644 --- a/lib/properties/marginBottom.js +++ b/lib/properties/marginBottom.js @@ -7,7 +7,7 @@ const shorthand = "margin"; module.exports.position = "bottom"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,22 +17,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -49,9 +36,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -62,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/marginLeft.js b/lib/properties/marginLeft.js index ae7ad63f..6a7ca004 100644 --- a/lib/properties/marginLeft.js +++ b/lib/properties/marginLeft.js @@ -7,7 +7,7 @@ const shorthand = "margin"; module.exports.position = "left"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,22 +17,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -49,9 +36,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -62,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/marginRight.js b/lib/properties/marginRight.js index 41aca507..bc895b9c 100644 --- a/lib/properties/marginRight.js +++ b/lib/properties/marginRight.js @@ -7,7 +7,7 @@ const shorthand = "margin"; module.exports.position = "right"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,22 +17,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -49,9 +36,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -62,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/marginTop.js b/lib/properties/marginTop.js index e33edf71..17dc8093 100644 --- a/lib/properties/marginTop.js +++ b/lib/properties/marginTop.js @@ -7,7 +7,7 @@ const shorthand = "margin"; module.exports.position = "top"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,22 +17,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -49,9 +36,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -62,3 +50,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/opacity.js b/lib/properties/opacity.js index 467a349c..14e83930 100644 --- a/lib/properties/opacity.js +++ b/lib/properties/opacity.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "opacity"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,23 +14,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - case "Number": { - return parsers.parseNumber(value); - } - case "Percentage": { - return parsers.parsePercentage(value); - } - default: - } + return parsers.resolveNumericValue(value, { + clamp: true + }); } else if (typeof value === "string") { return value; } @@ -57,3 +43,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/outlineColor.js b/lib/properties/outlineColor.js index be62e661..0c9a70af 100644 --- a/lib/properties/outlineColor.js +++ b/lib/properties/outlineColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "outline-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/padding.js b/lib/properties/padding.js index b574762f..8162d198 100644 --- a/lib/properties/padding.js +++ b/lib/properties/padding.js @@ -11,13 +11,13 @@ const property = "padding"; module.exports.position = "edges"; module.exports.shorthandFor = new Map([ - ["padding-top", paddingTop], - ["padding-right", paddingRight], - ["padding-bottom", paddingBottom], - ["padding-left", paddingLeft] + [paddingTop.property, paddingTop], + [paddingRight.property, paddingRight], + [paddingBottom.property, paddingBottom], + [paddingLeft.property, paddingLeft] ]); -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -32,32 +32,15 @@ module.exports.parse = function parse(v, opt = {}) { return; } for (const value of values) { - const { isNumber, name, type, value: itemValue } = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - parsedValues.push(`${name}(${itemValue})`); - break; - } - case "GlobalKeyword": { - if (values.length !== 1) { - return; - } - parsedValues.push(name); - break; - } - default: { - const parsedValue = parsers.parseLengthPercentage([value], { - min: 0 - }); - if (!parsedValue) { - return; - } - parsedValues.push(parsedValue); - } + const parsedValue = parsers.resolveNumericValue([value], { + length: values.length, + min: 0, + type: "length" + }); + if (!parsedValue) { + return; } + parsedValues.push(parsedValue); } } else if (typeof values === "string") { parsedValues.push(values); @@ -91,3 +74,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/paddingBottom.js b/lib/properties/paddingBottom.js index a2ec94da..16b29d2a 100644 --- a/lib/properties/paddingBottom.js +++ b/lib/properties/paddingBottom.js @@ -7,7 +7,7 @@ const shorthand = "padding"; module.exports.position = "bottom"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,23 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseLengthPercentage(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -50,9 +37,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -63,3 +51,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/paddingLeft.js b/lib/properties/paddingLeft.js index fc67fd41..1a74316a 100644 --- a/lib/properties/paddingLeft.js +++ b/lib/properties/paddingLeft.js @@ -7,7 +7,7 @@ const shorthand = "padding"; module.exports.position = "left"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,23 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseLengthPercentage(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -50,9 +37,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -63,3 +51,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/paddingRight.js b/lib/properties/paddingRight.js index d6eb1ec7..8cacfe22 100644 --- a/lib/properties/paddingRight.js +++ b/lib/properties/paddingRight.js @@ -7,7 +7,7 @@ const shorthand = "padding"; module.exports.position = "right"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,23 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseLengthPercentage(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -50,9 +37,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -63,3 +51,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/paddingTop.js b/lib/properties/paddingTop.js index 59c84b86..1fd08501 100644 --- a/lib/properties/paddingTop.js +++ b/lib/properties/paddingTop.js @@ -7,7 +7,7 @@ const shorthand = "padding"; module.exports.position = "top"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -17,23 +17,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseLengthPercentage(value, { - min: 0 - }); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -50,9 +37,10 @@ module.exports.definition = { globalObject: this._global }); if (typeof val === "string") { - const shorthandPriority = this._priorities.get(shorthand); - const prior = this._priorities.get(property) ?? ""; - const priority = shorthandPriority && prior ? "" : prior; + const priority = + !this._priorities.get(shorthand) && this._priorities.has(property) + ? this._priorities.get(property) + : ""; this._positionLonghandSetter(property, val, priority, shorthand); } } @@ -63,3 +51,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/right.js b/lib/properties/right.js index 46906797..3284a4f0 100644 --- a/lib/properties/right.js +++ b/lib/properties/right.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "right"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,22 +14,9 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -56,3 +43,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/stopColor.js b/lib/properties/stopColor.js index 65c605c4..fc5241cd 100644 --- a/lib/properties/stopColor.js +++ b/lib/properties/stopColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "stop-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/top.js b/lib/properties/top.js index 6da042ed..6e3219cf 100644 --- a/lib/properties/top.js +++ b/lib/properties/top.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "top"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,22 +14,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -56,3 +44,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitBorderAfterColor.js b/lib/properties/webkitBorderAfterColor.js index d9d7411d..3a6fc2ee 100644 --- a/lib/properties/webkitBorderAfterColor.js +++ b/lib/properties/webkitBorderAfterColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-border-after-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitBorderBeforeColor.js b/lib/properties/webkitBorderBeforeColor.js index 6d61e5a7..5d2e2cae 100644 --- a/lib/properties/webkitBorderBeforeColor.js +++ b/lib/properties/webkitBorderBeforeColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-border-before-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitBorderEndColor.js b/lib/properties/webkitBorderEndColor.js index b8c6debf..9c71b369 100644 --- a/lib/properties/webkitBorderEndColor.js +++ b/lib/properties/webkitBorderEndColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-border-end-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitBorderStartColor.js b/lib/properties/webkitBorderStartColor.js index e60d1df4..949e8d52 100644 --- a/lib/properties/webkitBorderStartColor.js +++ b/lib/properties/webkitBorderStartColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-border-start-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitColumnRuleColor.js b/lib/properties/webkitColumnRuleColor.js index 0db57961..2d5597c1 100644 --- a/lib/properties/webkitColumnRuleColor.js +++ b/lib/properties/webkitColumnRuleColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-column-rule-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitTapHighlightColor.js b/lib/properties/webkitTapHighlightColor.js index 06596563..c513f3b0 100644 --- a/lib/properties/webkitTapHighlightColor.js +++ b/lib/properties/webkitTapHighlightColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-tap-highlight-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitTextEmphasisColor.js b/lib/properties/webkitTextEmphasisColor.js index 84dac5ec..30efbe69 100644 --- a/lib/properties/webkitTextEmphasisColor.js +++ b/lib/properties/webkitTextEmphasisColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-text-emphasis-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitTextFillColor.js b/lib/properties/webkitTextFillColor.js index f13dc649..bf86c956 100644 --- a/lib/properties/webkitTextFillColor.js +++ b/lib/properties/webkitTextFillColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-text-fill-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/webkitTextStrokeColor.js b/lib/properties/webkitTextStrokeColor.js index 2339702d..ba7f859e 100644 --- a/lib/properties/webkitTextStrokeColor.js +++ b/lib/properties/webkitTextStrokeColor.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "-webkit-text-stroke-color"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,15 +14,7 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ name, type }] = value; - switch (type) { - case "GlobalKeyword": { - return name; - } - default: { - return parsers.parseColor(value); - } - } + return parsers.resolveColorValue(value); } else if (typeof value === "string") { return value; } @@ -49,3 +41,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/properties/width.js b/lib/properties/width.js index 6c60911f..70d5115d 100644 --- a/lib/properties/width.js +++ b/lib/properties/width.js @@ -4,7 +4,7 @@ const parsers = require("../parsers"); const property = "width"; -module.exports.parse = function parse(v, opt = {}) { +module.exports.parse = (v, opt = {}) => { const { globalObject } = opt; if (v === "") { return v; @@ -14,22 +14,10 @@ module.exports.parse = function parse(v, opt = {}) { inArray: true }); if (Array.isArray(value) && value.length === 1) { - const [{ isNumber, name, type, value: itemValue }] = value; - switch (type) { - case "Calc": { - if (isNumber) { - return; - } - return `${name}(${itemValue})`; - } - case "GlobalKeyword": - case "Identifier": { - return name; - } - default: { - return parsers.parseLengthPercentage(value); - } - } + return parsers.resolveNumericValue(value, { + min: 0, + type: "length" + }); } else if (typeof value === "string") { return value; } @@ -56,3 +44,5 @@ module.exports.definition = { enumerable: true, configurable: true }; + +module.exports.property = property; diff --git a/lib/utils/propertyDescriptors.js b/lib/utils/propertyDescriptors.js index b0053db8..275d5708 100644 --- a/lib/utils/propertyDescriptors.js +++ b/lib/utils/propertyDescriptors.js @@ -2,18 +2,54 @@ const parsers = require("../parsers"); -exports.getPropertyDescriptor = function getPropertyDescriptor(property) { - return { - set(v) { - v = parsers.parsePropertyValue(property, v, { - globalObject: this._global +const { AST_TYPES } = parsers; + +const getPropertyDescriptor = (property) => ({ + set(v) { + const value = parsers.prepareValue(v, this._global); + if (parsers.hasVarFunc(value)) { + this._setProperty(property, value); + } else { + const parsedValue = parsers.parsePropertyValue(property, v, { + globalObject: this._global, + inArray: true }); - this._setProperty(property, v); - }, - get() { - return this.getPropertyValue(property); - }, - enumerable: true, - configurable: true - }; + if (Array.isArray(parsedValue)) { + if (parsedValue.length === 1) { + const [{ name, type, value: itemValue }] = parsedValue; + switch (type) { + case AST_TYPES.CALC: { + this._setProperty(property, `${name}(${itemValue})`); + break; + } + case AST_TYPES.GLOBAL_KEYWORD: + case AST_TYPES.IDENTIFIER: { + // Set the normalized name for keywords or identifiers. + this._setProperty(property, name); + break; + } + default: { + // Set the prepared value for Dimension, Function, etc. + this._setProperty(property, value); + } + } + } else { + // Set the prepared value for lists containing multiple values. + this._setProperty(property, value); + } + } else if (typeof parsedValue === "string") { + // Empty string. + this._setProperty(property, parsedValue); + } + } + }, + get() { + return this.getPropertyValue(property); + }, + enumerable: true, + configurable: true +}); + +module.exports = { + getPropertyDescriptor }; diff --git a/test/parsers.test.js b/test/parsers.test.js index 2964102a..76a37702 100644 --- a/test/parsers.test.js +++ b/test/parsers.test.js @@ -641,162 +641,6 @@ describe("parsePercentage", () => { }); }); -describe("parseLengthPercentage", () => { - it("should return undefined", () => { - const input = ""; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, undefined); - }); - - it("should return undefined", () => { - const input = []; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, undefined); - }); - - it("should return undefined", () => { - const input = [ - { - type: "Number", - value: "100" - } - ]; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, undefined); - }); - - it("should return undefined", () => { - const input = [ - { - type: "Number", - value: "100" - } - ]; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, undefined); - }); - - it("should return undefined", () => { - const input = [ - { - type: "Dimension", - unit: "deg", - value: "180" - } - ]; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, undefined); - }); - - it("should return value with em unit", () => { - const input = [ - { - type: "Dimension", - unit: "em", - value: "1" - } - ]; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, "1em"); - }); - - it("should return value with percent", () => { - const input = [ - { - type: "Percentage", - value: "100" - } - ]; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, "100%"); - }); - - it("should return 0px for 0", () => { - const input = [ - { - type: "Number", - value: "0" - } - ]; - const output = parsers.parseLengthPercentage(input); - - assert.strictEqual(output, "0px"); - }); - - it("should return undefined", () => { - const input = [ - { - type: "Dimension", - unit: "em", - value: "-1" - } - ]; - const output = parsers.parseLengthPercentage(input, { - min: 0, - max: 1 - }); - - assert.strictEqual(output, undefined); - }); - - it("should return undefined", () => { - const input = [ - { - type: "Dimension", - unit: "em", - value: "1.1" - } - ]; - const output = parsers.parseLengthPercentage(input, { - min: 0, - max: 1 - }); - - assert.strictEqual(output, undefined); - }); - - it("should return clamped value", () => { - const input = [ - { - type: "Dimension", - unit: "em", - value: "-1" - } - ]; - const output = parsers.parseLengthPercentage(input, { - min: 0, - max: 1, - clamp: true - }); - - assert.strictEqual(output, "0em"); - }); - - it("should return clamped value", () => { - const input = [ - { - type: "Dimension", - unit: "em", - value: "1.1" - } - ]; - const output = parsers.parseLengthPercentage(input, { - min: 0, - max: 1, - clamp: true - }); - - assert.strictEqual(output, "1em"); - }); -}); - describe("parseAngle", () => { it("should return undefined", () => { const input = "";