cssstyle 5.3.5 → 5.3.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/CSSStyleDeclaration.js +6 -5
- package/lib/generated/implementedProperties.js +1 -1
- package/lib/generated/properties.js +2034 -2348
- package/lib/generated/propertyDefinitions.js +13033 -0
- package/lib/normalize.js +1252 -1095
- package/lib/parsers.js +589 -253
- package/lib/properties/background.js +90 -80
- package/lib/properties/backgroundAttachment.js +12 -15
- package/lib/properties/backgroundClip.js +12 -15
- package/lib/properties/backgroundColor.js +9 -14
- package/lib/properties/backgroundImage.js +12 -27
- package/lib/properties/backgroundOrigin.js +12 -15
- package/lib/properties/backgroundPosition.js +30 -19
- package/lib/properties/backgroundRepeat.js +12 -8
- package/lib/properties/backgroundSize.js +23 -17
- package/lib/properties/border.js +31 -88
- package/lib/properties/borderBottom.js +31 -87
- package/lib/properties/borderBottomColor.js +9 -15
- package/lib/properties/borderBottomStyle.js +9 -14
- package/lib/properties/borderBottomWidth.js +12 -24
- package/lib/properties/borderCollapse.js +5 -10
- package/lib/properties/borderColor.js +18 -24
- package/lib/properties/borderLeft.js +31 -87
- package/lib/properties/borderLeftColor.js +9 -15
- package/lib/properties/borderLeftStyle.js +9 -14
- package/lib/properties/borderLeftWidth.js +12 -24
- package/lib/properties/borderRight.js +31 -87
- package/lib/properties/borderRightColor.js +9 -15
- package/lib/properties/borderRightStyle.js +9 -14
- package/lib/properties/borderRightWidth.js +12 -24
- package/lib/properties/borderSpacing.js +13 -10
- package/lib/properties/borderStyle.js +18 -24
- package/lib/properties/borderTop.js +31 -87
- package/lib/properties/borderTopColor.js +9 -15
- package/lib/properties/borderTopStyle.js +9 -14
- package/lib/properties/borderTopWidth.js +12 -24
- package/lib/properties/borderWidth.js +19 -37
- package/lib/properties/bottom.js +7 -18
- package/lib/properties/clear.js +5 -10
- package/lib/properties/clip.js +11 -6
- package/lib/properties/color.js +5 -11
- package/lib/properties/display.js +12 -9
- package/lib/properties/flex.js +56 -54
- package/lib/properties/flexBasis.js +11 -21
- package/lib/properties/flexGrow.js +11 -20
- package/lib/properties/flexShrink.js +11 -20
- package/lib/properties/float.js +5 -10
- package/lib/properties/floodColor.js +5 -11
- package/lib/properties/font.js +47 -34
- package/lib/properties/fontFamily.js +17 -13
- package/lib/properties/fontSize.js +12 -23
- package/lib/properties/fontStyle.js +15 -9
- package/lib/properties/fontVariant.js +12 -19
- package/lib/properties/fontWeight.js +15 -26
- package/lib/properties/height.js +8 -18
- package/lib/properties/left.js +7 -18
- package/lib/properties/lightingColor.js +5 -11
- package/lib/properties/lineHeight.js +11 -25
- package/lib/properties/margin.js +15 -33
- package/lib/properties/marginBottom.js +11 -21
- package/lib/properties/marginLeft.js +11 -21
- package/lib/properties/marginRight.js +11 -21
- package/lib/properties/marginTop.js +11 -21
- package/lib/properties/opacity.js +7 -19
- package/lib/properties/outlineColor.js +5 -11
- package/lib/properties/padding.js +16 -31
- package/lib/properties/paddingBottom.js +12 -22
- package/lib/properties/paddingLeft.js +12 -22
- package/lib/properties/paddingRight.js +12 -22
- package/lib/properties/paddingTop.js +12 -22
- package/lib/properties/right.js +7 -18
- package/lib/properties/stopColor.js +5 -11
- package/lib/properties/top.js +7 -18
- package/lib/properties/webkitBorderAfterColor.js +5 -11
- package/lib/properties/webkitBorderBeforeColor.js +5 -11
- package/lib/properties/webkitBorderEndColor.js +5 -11
- package/lib/properties/webkitBorderStartColor.js +5 -11
- package/lib/properties/webkitColumnRuleColor.js +5 -11
- package/lib/properties/webkitTapHighlightColor.js +5 -11
- package/lib/properties/webkitTextEmphasisColor.js +5 -11
- package/lib/properties/webkitTextFillColor.js +5 -11
- package/lib/properties/webkitTextStrokeColor.js +5 -11
- package/lib/properties/width.js +8 -18
- package/lib/utils/propertyDescriptors.js +49 -13
- package/lib/utils/strings.js +6 -0
- package/package.json +8 -27
package/lib/parsers.js
CHANGED
|
@@ -6,16 +6,17 @@ const {
|
|
|
6
6
|
} = require("@asamuzakjp/css-color");
|
|
7
7
|
const { next: syntaxes } = require("@csstools/css-syntax-patches-for-csstree");
|
|
8
8
|
const csstree = require("css-tree");
|
|
9
|
+
const { LRUCache } = require("lru-cache");
|
|
9
10
|
const { asciiLowercase } = require("./utils/strings");
|
|
10
11
|
|
|
11
12
|
// CSS global keywords
|
|
12
13
|
// @see https://drafts.csswg.org/css-cascade-5/#defaulting-keywords
|
|
13
|
-
const
|
|
14
|
+
const GLOBAL_KEYS = new Set(["initial", "inherit", "unset", "revert", "revert-layer"]);
|
|
14
15
|
|
|
15
16
|
// System colors
|
|
16
17
|
// @see https://drafts.csswg.org/css-color/#css-system-colors
|
|
17
18
|
// @see https://drafts.csswg.org/css-color/#deprecated-system-colors
|
|
18
|
-
const
|
|
19
|
+
const SYS_COLORS = new Set([
|
|
19
20
|
"accentcolor",
|
|
20
21
|
"accentcolortext",
|
|
21
22
|
"activeborder",
|
|
@@ -60,6 +61,20 @@ const SYS_COLOR = Object.freeze([
|
|
|
60
61
|
"windowtext"
|
|
61
62
|
]);
|
|
62
63
|
|
|
64
|
+
// AST node types
|
|
65
|
+
const AST_TYPES = Object.freeze({
|
|
66
|
+
CALC: "Calc",
|
|
67
|
+
DIMENSION: "Dimension",
|
|
68
|
+
FUNCTION: "Function",
|
|
69
|
+
GLOBAL_KEYWORD: "GlobalKeyword",
|
|
70
|
+
HASH: "Hash",
|
|
71
|
+
IDENTIFIER: "Identifier",
|
|
72
|
+
NUMBER: "Number",
|
|
73
|
+
PERCENTAGE: "Percentage",
|
|
74
|
+
STRING: "String",
|
|
75
|
+
URL: "Url"
|
|
76
|
+
});
|
|
77
|
+
|
|
63
78
|
// Regular expressions
|
|
64
79
|
const CALC_FUNC_NAMES =
|
|
65
80
|
"(?:a?(?:cos|sin|tan)|abs|atan2|calc|clamp|exp|hypot|log|max|min|mod|pow|rem|round|sign|sqrt)";
|
|
@@ -72,57 +87,66 @@ const varContainedRegEx = /(?<=[*/\s(])var\(/;
|
|
|
72
87
|
// Patched css-tree
|
|
73
88
|
const cssTree = csstree.fork(syntaxes);
|
|
74
89
|
|
|
75
|
-
//
|
|
76
|
-
|
|
90
|
+
// Instance of the LRU Cache. Stores up to 4096 items.
|
|
91
|
+
const lruCache = new LRUCache({
|
|
92
|
+
max: 4096
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Prepares a stringified value.
|
|
97
|
+
*
|
|
98
|
+
* @param {string|number|null|undefined} value - The value to prepare.
|
|
99
|
+
* @returns {string} The prepared value.
|
|
100
|
+
*/
|
|
101
|
+
const prepareValue = (value) => {
|
|
77
102
|
// `null` is converted to an empty string.
|
|
78
103
|
// @see https://webidl.spec.whatwg.org/#LegacyNullToEmptyString
|
|
79
104
|
if (value === null) {
|
|
80
105
|
return "";
|
|
81
106
|
}
|
|
82
|
-
|
|
83
|
-
switch (type) {
|
|
84
|
-
case "string":
|
|
85
|
-
return value.trim();
|
|
86
|
-
case "number":
|
|
87
|
-
return value.toString();
|
|
88
|
-
case "undefined":
|
|
89
|
-
return "undefined";
|
|
90
|
-
case "symbol":
|
|
91
|
-
throw new globalObject.TypeError("Can not convert symbol to string.");
|
|
92
|
-
default: {
|
|
93
|
-
const str = value.toString();
|
|
94
|
-
if (typeof str === "string") {
|
|
95
|
-
return str.trim();
|
|
96
|
-
}
|
|
97
|
-
throw new globalObject.TypeError(`Can not convert ${type} to string.`);
|
|
98
|
-
}
|
|
99
|
-
}
|
|
107
|
+
return `${value}`.trim();
|
|
100
108
|
};
|
|
101
109
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Checks if the value is a global keyword.
|
|
112
|
+
*
|
|
113
|
+
* @param {string} val - The value to check.
|
|
114
|
+
* @returns {boolean} True if the value is a global keyword, false otherwise.
|
|
115
|
+
*/
|
|
116
|
+
const isGlobalKeyword = (val) => {
|
|
117
|
+
return GLOBAL_KEYS.has(asciiLowercase(val));
|
|
105
118
|
};
|
|
106
119
|
|
|
107
|
-
|
|
108
|
-
|
|
120
|
+
/**
|
|
121
|
+
* Checks if the value starts with or contains a CSS var() function.
|
|
122
|
+
*
|
|
123
|
+
* @param {string} val - The value to check.
|
|
124
|
+
* @returns {boolean} True if the value contains a var() function, false otherwise.
|
|
125
|
+
*/
|
|
126
|
+
const hasVarFunc = (val) => {
|
|
109
127
|
return varRegEx.test(val) || varContainedRegEx.test(val);
|
|
110
128
|
};
|
|
111
129
|
|
|
112
|
-
|
|
113
|
-
|
|
130
|
+
/**
|
|
131
|
+
* Checks if the value starts with or contains CSS calc() or math functions.
|
|
132
|
+
*
|
|
133
|
+
* @param {string} val - The value to check.
|
|
134
|
+
* @returns {boolean} True if the value contains calc() or math functions, false otherwise.
|
|
135
|
+
*/
|
|
136
|
+
const hasCalcFunc = (val) => {
|
|
114
137
|
return calcRegEx.test(val) || calcContainedRegEx.test(val);
|
|
115
138
|
};
|
|
116
139
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Parses a CSS string into an AST.
|
|
142
|
+
*
|
|
143
|
+
* @param {string} val - The CSS string to parse.
|
|
144
|
+
* @param {object} opt - The options for parsing.
|
|
145
|
+
* @param {boolean} [toObject=false] - Whether to return a plain object.
|
|
146
|
+
* @returns {object} The AST or a plain object.
|
|
147
|
+
*/
|
|
148
|
+
const parseCSS = (val, opt, toObject = false) => {
|
|
149
|
+
val = prepareValue(val);
|
|
126
150
|
const ast = cssTree.parse(val, opt);
|
|
127
151
|
if (toObject) {
|
|
128
152
|
return cssTree.toPlainObject(ast);
|
|
@@ -130,45 +154,65 @@ exports.parseCSS = (val, opt, toObject = false) => {
|
|
|
130
154
|
return ast;
|
|
131
155
|
};
|
|
132
156
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
157
|
+
/**
|
|
158
|
+
* Checks if the value is a valid property value.
|
|
159
|
+
* Returns false for custom properties or values containing var().
|
|
160
|
+
*
|
|
161
|
+
* @param {string} prop - The property name.
|
|
162
|
+
* @param {string} val - The property value.
|
|
163
|
+
* @returns {boolean} True if the value is valid, false otherwise.
|
|
164
|
+
*/
|
|
165
|
+
const isValidPropertyValue = (prop, val) => {
|
|
166
|
+
val = prepareValue(val);
|
|
139
167
|
if (val === "") {
|
|
140
168
|
return true;
|
|
141
169
|
}
|
|
142
170
|
// cssTree.lexer does not support deprecated system colors
|
|
143
171
|
// @see https://github.com/w3c/webref/issues/1519#issuecomment-3120290261
|
|
144
172
|
// @see https://github.com/w3c/webref/issues/1647
|
|
145
|
-
if (
|
|
173
|
+
if (SYS_COLORS.has(asciiLowercase(val))) {
|
|
146
174
|
if (/^(?:-webkit-)?(?:[a-z][a-z\d]*-)*color$/i.test(prop)) {
|
|
147
175
|
return true;
|
|
148
176
|
}
|
|
149
177
|
return false;
|
|
150
178
|
}
|
|
151
|
-
|
|
179
|
+
const cacheKey = `isValidPropertyValue_${prop}_${val}`;
|
|
180
|
+
const cachedValue = lruCache.get(cacheKey);
|
|
181
|
+
if (typeof cachedValue === "boolean") {
|
|
182
|
+
return cachedValue;
|
|
183
|
+
}
|
|
184
|
+
let result;
|
|
152
185
|
try {
|
|
153
|
-
ast =
|
|
186
|
+
const ast = parseCSS(val, {
|
|
154
187
|
context: "value"
|
|
155
188
|
});
|
|
189
|
+
const { error, matched } = cssTree.lexer.matchProperty(prop, ast);
|
|
190
|
+
result = error === null && matched !== null;
|
|
156
191
|
} catch {
|
|
157
|
-
|
|
192
|
+
result = false;
|
|
158
193
|
}
|
|
159
|
-
|
|
160
|
-
return
|
|
194
|
+
lruCache.set(cacheKey, result);
|
|
195
|
+
return result;
|
|
161
196
|
};
|
|
162
197
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Resolves CSS math functions.
|
|
200
|
+
*
|
|
201
|
+
* @param {string} val - The value to resolve.
|
|
202
|
+
* @param {object} [opt={ format: "specifiedValue" }] - The options for resolving.
|
|
203
|
+
* @returns {string|undefined} The resolved value.
|
|
204
|
+
*/
|
|
205
|
+
const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
206
|
+
val = prepareValue(val);
|
|
207
|
+
if (val === "" || hasVarFunc(val) || !hasCalcFunc(val)) {
|
|
169
208
|
return val;
|
|
170
209
|
}
|
|
171
|
-
const
|
|
210
|
+
const cacheKey = `resolveCalc_${val}`;
|
|
211
|
+
const cachedValue = lruCache.get(cacheKey);
|
|
212
|
+
if (typeof cachedValue === "string") {
|
|
213
|
+
return cachedValue;
|
|
214
|
+
}
|
|
215
|
+
const obj = parseCSS(val, { context: "value" }, true);
|
|
172
216
|
if (!obj?.children) {
|
|
173
217
|
return;
|
|
174
218
|
}
|
|
@@ -176,7 +220,7 @@ exports.resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
176
220
|
const values = [];
|
|
177
221
|
for (const item of items) {
|
|
178
222
|
const { type: itemType, name: itemName, value: itemValue } = item;
|
|
179
|
-
if (itemType ===
|
|
223
|
+
if (itemType === AST_TYPES.FUNCTION) {
|
|
180
224
|
const value = cssTree
|
|
181
225
|
.generate(item)
|
|
182
226
|
.replace(/\)(?!\)|\s|,)/g, ") ")
|
|
@@ -187,23 +231,33 @@ exports.resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
187
231
|
} else {
|
|
188
232
|
values.push(value);
|
|
189
233
|
}
|
|
190
|
-
} else if (itemType ===
|
|
234
|
+
} else if (itemType === AST_TYPES.STRING) {
|
|
191
235
|
values.push(`"${itemValue}"`);
|
|
192
236
|
} else {
|
|
193
237
|
values.push(itemName ?? itemValue);
|
|
194
238
|
}
|
|
195
239
|
}
|
|
196
|
-
|
|
240
|
+
const resolvedValue = values.join(" ");
|
|
241
|
+
lruCache.set(cacheKey, resolvedValue);
|
|
242
|
+
return resolvedValue;
|
|
197
243
|
};
|
|
198
244
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
245
|
+
/**
|
|
246
|
+
* Parses a property value.
|
|
247
|
+
* Returns a string or an array of parsed objects.
|
|
248
|
+
*
|
|
249
|
+
* @param {string} prop - The property name.
|
|
250
|
+
* @param {string} val - The property value.
|
|
251
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
252
|
+
* @returns {string|Array<object>|undefined} The parsed value.
|
|
253
|
+
*/
|
|
254
|
+
const parsePropertyValue = (prop, val, opt = {}) => {
|
|
255
|
+
const { caseSensitive, inArray } = opt;
|
|
256
|
+
val = prepareValue(val);
|
|
257
|
+
if (val === "" || hasVarFunc(val)) {
|
|
204
258
|
return val;
|
|
205
|
-
} else if (
|
|
206
|
-
const calculatedValue =
|
|
259
|
+
} else if (hasCalcFunc(val)) {
|
|
260
|
+
const calculatedValue = resolveCalc(val, {
|
|
207
261
|
format: "specifiedValue"
|
|
208
262
|
});
|
|
209
263
|
if (typeof calculatedValue !== "string") {
|
|
@@ -211,137 +265,164 @@ exports.parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
211
265
|
}
|
|
212
266
|
val = calculatedValue;
|
|
213
267
|
}
|
|
268
|
+
const cacheKey = `parsePropertyValue_${prop}_${val}_${caseSensitive}`;
|
|
269
|
+
const cachedValue = lruCache.get(cacheKey);
|
|
270
|
+
if (cachedValue === false) {
|
|
271
|
+
return;
|
|
272
|
+
} else if (inArray) {
|
|
273
|
+
if (Array.isArray(cachedValue)) {
|
|
274
|
+
return cachedValue;
|
|
275
|
+
}
|
|
276
|
+
} else if (typeof cachedValue === "string") {
|
|
277
|
+
return cachedValue;
|
|
278
|
+
}
|
|
279
|
+
let parsedValue;
|
|
214
280
|
const lowerCasedValue = asciiLowercase(val);
|
|
215
|
-
if (
|
|
281
|
+
if (GLOBAL_KEYS.has(lowerCasedValue)) {
|
|
216
282
|
if (inArray) {
|
|
217
|
-
|
|
283
|
+
parsedValue = [
|
|
218
284
|
{
|
|
219
|
-
type:
|
|
285
|
+
type: AST_TYPES.GLOBAL_KEYWORD,
|
|
220
286
|
name: lowerCasedValue
|
|
221
287
|
}
|
|
222
288
|
];
|
|
289
|
+
} else {
|
|
290
|
+
parsedValue = lowerCasedValue;
|
|
223
291
|
}
|
|
224
|
-
|
|
225
|
-
} else if (SYS_COLOR.includes(lowerCasedValue)) {
|
|
292
|
+
} else if (SYS_COLORS.has(lowerCasedValue)) {
|
|
226
293
|
if (/^(?:(?:-webkit-)?(?:[a-z][a-z\d]*-)*color|border)$/i.test(prop)) {
|
|
227
294
|
if (inArray) {
|
|
228
|
-
|
|
295
|
+
parsedValue = [
|
|
229
296
|
{
|
|
230
|
-
type:
|
|
297
|
+
type: AST_TYPES.IDENTIFIER,
|
|
231
298
|
name: lowerCasedValue
|
|
232
299
|
}
|
|
233
300
|
];
|
|
301
|
+
} else {
|
|
302
|
+
parsedValue = lowerCasedValue;
|
|
234
303
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return;
|
|
238
|
-
}
|
|
239
|
-
try {
|
|
240
|
-
const ast = exports.parseCSS(val, {
|
|
241
|
-
context: "value"
|
|
242
|
-
});
|
|
243
|
-
const { error, matched } = cssTree.lexer.matchProperty(prop, ast);
|
|
244
|
-
if (error || !matched) {
|
|
245
|
-
return;
|
|
304
|
+
} else {
|
|
305
|
+
parsedValue = false;
|
|
246
306
|
}
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
307
|
+
} else {
|
|
308
|
+
try {
|
|
309
|
+
const ast = parseCSS(val, {
|
|
310
|
+
context: "value"
|
|
311
|
+
});
|
|
312
|
+
const { error, matched } = cssTree.lexer.matchProperty(prop, ast);
|
|
313
|
+
if (error || !matched) {
|
|
314
|
+
parsedValue = false;
|
|
315
|
+
} else if (inArray) {
|
|
316
|
+
const obj = cssTree.toPlainObject(ast);
|
|
317
|
+
const items = obj.children;
|
|
318
|
+
const values = [];
|
|
319
|
+
for (const item of items) {
|
|
320
|
+
const { children, name, type, value, unit } = item;
|
|
321
|
+
switch (type) {
|
|
322
|
+
case AST_TYPES.DIMENSION: {
|
|
323
|
+
values.push({
|
|
324
|
+
type,
|
|
325
|
+
value,
|
|
326
|
+
unit: asciiLowercase(unit)
|
|
327
|
+
});
|
|
328
|
+
break;
|
|
329
|
+
}
|
|
330
|
+
case AST_TYPES.FUNCTION: {
|
|
331
|
+
const css = cssTree
|
|
332
|
+
.generate(item)
|
|
333
|
+
.replace(/\)(?!\)|\s|,)/g, ") ")
|
|
334
|
+
.trim();
|
|
335
|
+
const raw = items.length === 1 ? val : css;
|
|
336
|
+
// Remove "${name}(" from the start and ")" from the end
|
|
337
|
+
const itemValue = raw.slice(name.length + 1, -1).trim();
|
|
338
|
+
if (name === "calc") {
|
|
339
|
+
if (children.length === 1) {
|
|
340
|
+
const [child] = children;
|
|
341
|
+
if (child.type === AST_TYPES.NUMBER) {
|
|
342
|
+
values.push({
|
|
343
|
+
type: AST_TYPES.CALC,
|
|
344
|
+
isNumber: true,
|
|
345
|
+
value: `${parseFloat(child.value)}`,
|
|
346
|
+
name,
|
|
347
|
+
raw
|
|
348
|
+
});
|
|
349
|
+
} else {
|
|
350
|
+
values.push({
|
|
351
|
+
type: AST_TYPES.CALC,
|
|
352
|
+
isNumber: false,
|
|
353
|
+
value: `${asciiLowercase(itemValue)}`,
|
|
354
|
+
name,
|
|
355
|
+
raw
|
|
356
|
+
});
|
|
357
|
+
}
|
|
283
358
|
} else {
|
|
284
|
-
|
|
285
|
-
type:
|
|
286
|
-
name: "calc",
|
|
359
|
+
values.push({
|
|
360
|
+
type: AST_TYPES.CALC,
|
|
287
361
|
isNumber: false,
|
|
288
|
-
value:
|
|
362
|
+
value: asciiLowercase(itemValue),
|
|
363
|
+
name,
|
|
289
364
|
raw
|
|
290
365
|
});
|
|
291
366
|
}
|
|
292
367
|
} else {
|
|
293
|
-
|
|
294
|
-
type
|
|
295
|
-
name
|
|
296
|
-
isNumber: false,
|
|
368
|
+
values.push({
|
|
369
|
+
type,
|
|
370
|
+
name,
|
|
297
371
|
value: asciiLowercase(itemValue),
|
|
298
372
|
raw
|
|
299
373
|
});
|
|
300
374
|
}
|
|
301
|
-
|
|
302
|
-
parsedValues.push({
|
|
303
|
-
type,
|
|
304
|
-
name,
|
|
305
|
-
value: asciiLowercase(itemValue),
|
|
306
|
-
raw
|
|
307
|
-
});
|
|
375
|
+
break;
|
|
308
376
|
}
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
377
|
+
case AST_TYPES.IDENTIFIER: {
|
|
378
|
+
if (caseSensitive) {
|
|
379
|
+
values.push(item);
|
|
380
|
+
} else {
|
|
381
|
+
values.push({
|
|
382
|
+
type,
|
|
383
|
+
name: asciiLowercase(name)
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
break;
|
|
387
|
+
}
|
|
388
|
+
default: {
|
|
389
|
+
values.push(item);
|
|
319
390
|
}
|
|
320
|
-
break;
|
|
321
|
-
}
|
|
322
|
-
default: {
|
|
323
|
-
parsedValues.push(item);
|
|
324
391
|
}
|
|
325
392
|
}
|
|
393
|
+
parsedValue = values;
|
|
394
|
+
} else {
|
|
395
|
+
parsedValue = val;
|
|
326
396
|
}
|
|
327
|
-
|
|
397
|
+
} catch {
|
|
398
|
+
parsedValue = false;
|
|
328
399
|
}
|
|
329
|
-
}
|
|
400
|
+
}
|
|
401
|
+
lruCache.set(cacheKey, parsedValue);
|
|
402
|
+
if (parsedValue === false) {
|
|
330
403
|
return;
|
|
331
404
|
}
|
|
332
|
-
return
|
|
405
|
+
return parsedValue;
|
|
333
406
|
};
|
|
334
407
|
|
|
335
|
-
|
|
336
|
-
|
|
408
|
+
/**
|
|
409
|
+
* Parses a numeric value (number, dimension, percentage).
|
|
410
|
+
* Helper function for parseNumber, parseLength, etc.
|
|
411
|
+
*
|
|
412
|
+
* @param {Array<object>} val - The AST value.
|
|
413
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
414
|
+
* @param {Function} validateType - Function to validate the node type.
|
|
415
|
+
* @returns {object|undefined} The parsed result containing num and unit, or undefined.
|
|
416
|
+
*/
|
|
417
|
+
const parseNumericValue = (val, opt, validateType) => {
|
|
337
418
|
const [item] = val;
|
|
338
|
-
const { type, value } = item ?? {};
|
|
339
|
-
if (type
|
|
419
|
+
const { type, value, unit } = item ?? {};
|
|
420
|
+
if (!validateType(type, value, unit)) {
|
|
340
421
|
return;
|
|
341
422
|
}
|
|
342
|
-
const { clamp } = opt;
|
|
343
|
-
const max = opt
|
|
344
|
-
const min = opt
|
|
423
|
+
const { clamp } = opt || {};
|
|
424
|
+
const max = opt?.max ?? Number.INFINITY;
|
|
425
|
+
const min = opt?.min ?? Number.NEGATIVE_INFINITY;
|
|
345
426
|
let num = parseFloat(value);
|
|
346
427
|
if (clamp) {
|
|
347
428
|
if (num > max) {
|
|
@@ -352,140 +433,142 @@ exports.parseNumber = (val, opt = {}) => {
|
|
|
352
433
|
} else if (num > max || num < min) {
|
|
353
434
|
return;
|
|
354
435
|
}
|
|
355
|
-
return
|
|
436
|
+
return {
|
|
437
|
+
num,
|
|
438
|
+
unit: unit ? asciiLowercase(unit) : null,
|
|
439
|
+
type
|
|
440
|
+
};
|
|
356
441
|
};
|
|
357
442
|
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
443
|
+
/**
|
|
444
|
+
* Parses a <number> value.
|
|
445
|
+
*
|
|
446
|
+
* @param {Array<object>} val - The AST value.
|
|
447
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
448
|
+
* @returns {string|undefined} The parsed number.
|
|
449
|
+
*/
|
|
450
|
+
const parseNumber = (val, opt = {}) => {
|
|
451
|
+
const res = parseNumericValue(val, opt, (type) => type === AST_TYPES.NUMBER);
|
|
452
|
+
if (!res) {
|
|
363
453
|
return;
|
|
364
454
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
455
|
+
return `${res.num}`;
|
|
456
|
+
};
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Parses a <length> value.
|
|
460
|
+
*
|
|
461
|
+
* @param {Array<object>} val - The AST value.
|
|
462
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
463
|
+
* @returns {string|undefined} The parsed length.
|
|
464
|
+
*/
|
|
465
|
+
const parseLength = (val, opt = {}) => {
|
|
466
|
+
const res = parseNumericValue(
|
|
467
|
+
val,
|
|
468
|
+
opt,
|
|
469
|
+
(type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
|
|
470
|
+
);
|
|
471
|
+
if (!res) {
|
|
376
472
|
return;
|
|
377
473
|
}
|
|
474
|
+
const { num, unit } = res;
|
|
378
475
|
if (num === 0 && !unit) {
|
|
379
476
|
return `${num}px`;
|
|
380
477
|
} else if (unit) {
|
|
381
|
-
return `${num}${
|
|
478
|
+
return `${num}${unit}`;
|
|
382
479
|
}
|
|
383
480
|
};
|
|
384
481
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
482
|
+
/**
|
|
483
|
+
* Parses a <percentage> value.
|
|
484
|
+
*
|
|
485
|
+
* @param {Array<object>} val - The AST value.
|
|
486
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
487
|
+
* @returns {string|undefined} The parsed percentage.
|
|
488
|
+
*/
|
|
489
|
+
const parsePercentage = (val, opt = {}) => {
|
|
490
|
+
const res = parseNumericValue(
|
|
491
|
+
val,
|
|
492
|
+
opt,
|
|
493
|
+
(type, value) => type === AST_TYPES.PERCENTAGE || (type === AST_TYPES.NUMBER && value === "0")
|
|
494
|
+
);
|
|
495
|
+
if (!res) {
|
|
390
496
|
return;
|
|
391
497
|
}
|
|
392
|
-
const {
|
|
393
|
-
const max = opt.max ?? Number.INFINITY;
|
|
394
|
-
const min = opt.min ?? Number.NEGATIVE_INFINITY;
|
|
395
|
-
let num = parseFloat(value);
|
|
396
|
-
if (clamp) {
|
|
397
|
-
if (num > max) {
|
|
398
|
-
num = max;
|
|
399
|
-
} else if (num < min) {
|
|
400
|
-
num = min;
|
|
401
|
-
}
|
|
402
|
-
} else if (num > max || num < min) {
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
if (num === 0) {
|
|
406
|
-
return `${num}%`;
|
|
407
|
-
}
|
|
498
|
+
const { num } = res;
|
|
408
499
|
return `${num}%`;
|
|
409
500
|
};
|
|
410
501
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
502
|
+
/**
|
|
503
|
+
* Parses an <angle> value.
|
|
504
|
+
*
|
|
505
|
+
* @param {Array<object>} val - The AST value.
|
|
506
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
507
|
+
* @returns {string|undefined} The parsed angle.
|
|
508
|
+
*/
|
|
509
|
+
const parseAngle = (val, opt = {}) => {
|
|
510
|
+
const res = parseNumericValue(
|
|
511
|
+
val,
|
|
512
|
+
opt,
|
|
513
|
+
(type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
|
|
514
|
+
);
|
|
515
|
+
if (!res) {
|
|
416
516
|
return;
|
|
417
517
|
}
|
|
418
|
-
const {
|
|
419
|
-
const max = opt.max ?? Number.INFINITY;
|
|
420
|
-
const min = opt.min ?? Number.NEGATIVE_INFINITY;
|
|
421
|
-
let num = parseFloat(value);
|
|
422
|
-
if (clamp) {
|
|
423
|
-
if (num > max) {
|
|
424
|
-
num = max;
|
|
425
|
-
} else if (num < min) {
|
|
426
|
-
num = min;
|
|
427
|
-
}
|
|
428
|
-
} else if (num > max || num < min) {
|
|
429
|
-
return;
|
|
430
|
-
}
|
|
431
|
-
if (unit) {
|
|
432
|
-
if (/deg|g?rad|turn/i.test(unit)) {
|
|
433
|
-
return;
|
|
434
|
-
}
|
|
435
|
-
return `${num}${asciiLowercase(unit)}`;
|
|
436
|
-
} else if (type === "Percentage") {
|
|
437
|
-
return `${num}%`;
|
|
438
|
-
} else if (num === 0) {
|
|
439
|
-
return `${num}px`;
|
|
440
|
-
}
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
// Parse <angle>.
|
|
444
|
-
exports.parseAngle = (val) => {
|
|
445
|
-
const [item] = val;
|
|
446
|
-
const { type, value, unit } = item ?? {};
|
|
447
|
-
if (type !== "Dimension" && !(type === "Number" && value === "0")) {
|
|
448
|
-
return;
|
|
449
|
-
}
|
|
450
|
-
const num = parseFloat(value);
|
|
518
|
+
const { num, unit } = res;
|
|
451
519
|
if (unit) {
|
|
452
520
|
if (!/^(?:deg|g?rad|turn)$/i.test(unit)) {
|
|
453
521
|
return;
|
|
454
522
|
}
|
|
455
|
-
return `${num}${
|
|
523
|
+
return `${num}${unit}`;
|
|
456
524
|
} else if (num === 0) {
|
|
457
525
|
return `${num}deg`;
|
|
458
526
|
}
|
|
459
527
|
};
|
|
460
528
|
|
|
461
|
-
|
|
462
|
-
|
|
529
|
+
/**
|
|
530
|
+
* Parses a <url> value.
|
|
531
|
+
*
|
|
532
|
+
* @param {Array<object>} val - The AST value.
|
|
533
|
+
* @returns {string|undefined} The parsed url.
|
|
534
|
+
*/
|
|
535
|
+
const parseUrl = (val) => {
|
|
463
536
|
const [item] = val;
|
|
464
537
|
const { type, value } = item ?? {};
|
|
465
|
-
if (type !==
|
|
538
|
+
if (type !== AST_TYPES.URL) {
|
|
466
539
|
return;
|
|
467
540
|
}
|
|
468
541
|
const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
|
|
469
542
|
return `url("${str}")`;
|
|
470
543
|
};
|
|
471
544
|
|
|
472
|
-
|
|
473
|
-
|
|
545
|
+
/**
|
|
546
|
+
* Parses a <string> value.
|
|
547
|
+
*
|
|
548
|
+
* @param {Array<object>} val - The AST value.
|
|
549
|
+
* @returns {string|undefined} The parsed string.
|
|
550
|
+
*/
|
|
551
|
+
const parseString = (val) => {
|
|
474
552
|
const [item] = val;
|
|
475
553
|
const { type, value } = item ?? {};
|
|
476
|
-
if (type !==
|
|
554
|
+
if (type !== AST_TYPES.STRING) {
|
|
477
555
|
return;
|
|
478
556
|
}
|
|
479
557
|
const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
|
|
480
558
|
return `"${str}"`;
|
|
481
559
|
};
|
|
482
560
|
|
|
483
|
-
|
|
484
|
-
|
|
561
|
+
/**
|
|
562
|
+
* Parses a <color> value.
|
|
563
|
+
*
|
|
564
|
+
* @param {Array<object>} val - The AST value.
|
|
565
|
+
* @returns {string|undefined} The parsed color.
|
|
566
|
+
*/
|
|
567
|
+
const parseColor = (val) => {
|
|
485
568
|
const [item] = val;
|
|
486
569
|
const { name, type, value } = item ?? {};
|
|
487
570
|
switch (type) {
|
|
488
|
-
case
|
|
571
|
+
case AST_TYPES.FUNCTION: {
|
|
489
572
|
const res = resolveColor(`${name}(${value})`, {
|
|
490
573
|
format: "specifiedValue"
|
|
491
574
|
});
|
|
@@ -494,7 +577,7 @@ exports.parseColor = (val) => {
|
|
|
494
577
|
}
|
|
495
578
|
break;
|
|
496
579
|
}
|
|
497
|
-
case
|
|
580
|
+
case AST_TYPES.HASH: {
|
|
498
581
|
const res = resolveColor(`#${value}`, {
|
|
499
582
|
format: "specifiedValue"
|
|
500
583
|
});
|
|
@@ -503,8 +586,8 @@ exports.parseColor = (val) => {
|
|
|
503
586
|
}
|
|
504
587
|
break;
|
|
505
588
|
}
|
|
506
|
-
case
|
|
507
|
-
if (
|
|
589
|
+
case AST_TYPES.IDENTIFIER: {
|
|
590
|
+
if (SYS_COLORS.has(name)) {
|
|
508
591
|
return name;
|
|
509
592
|
}
|
|
510
593
|
const res = resolveColor(name, {
|
|
@@ -519,11 +602,16 @@ exports.parseColor = (val) => {
|
|
|
519
602
|
}
|
|
520
603
|
};
|
|
521
604
|
|
|
522
|
-
|
|
523
|
-
|
|
605
|
+
/**
|
|
606
|
+
* Parses a <gradient> value.
|
|
607
|
+
*
|
|
608
|
+
* @param {Array<object>} val - The AST value.
|
|
609
|
+
* @returns {string|undefined} The parsed gradient.
|
|
610
|
+
*/
|
|
611
|
+
const parseGradient = (val) => {
|
|
524
612
|
const [item] = val;
|
|
525
613
|
const { name, type, value } = item ?? {};
|
|
526
|
-
if (type !==
|
|
614
|
+
if (type !== AST_TYPES.FUNCTION) {
|
|
527
615
|
return;
|
|
528
616
|
}
|
|
529
617
|
const res = resolveGradient(`${name}(${value})`, {
|
|
@@ -533,3 +621,251 @@ exports.parseGradient = (val) => {
|
|
|
533
621
|
return res;
|
|
534
622
|
}
|
|
535
623
|
};
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Resolves a keyword value.
|
|
627
|
+
*
|
|
628
|
+
* @param {Array<object>} value - The AST node array containing the keyword value.
|
|
629
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
630
|
+
* @returns {string|undefined} The resolved keyword or undefined.
|
|
631
|
+
*/
|
|
632
|
+
const resolveKeywordValue = (value, opt = {}) => {
|
|
633
|
+
const [{ name, type }] = value;
|
|
634
|
+
const { length } = opt;
|
|
635
|
+
switch (type) {
|
|
636
|
+
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
637
|
+
if (length > 1) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
return name;
|
|
641
|
+
}
|
|
642
|
+
case AST_TYPES.IDENTIFIER: {
|
|
643
|
+
return name;
|
|
644
|
+
}
|
|
645
|
+
default:
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
|
|
649
|
+
/**
|
|
650
|
+
* Resolves a function value.
|
|
651
|
+
*
|
|
652
|
+
* @param {Array<object>} value - The AST node array containing the function value.
|
|
653
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
654
|
+
* @returns {string|undefined} The resolved function or undefined.
|
|
655
|
+
*/
|
|
656
|
+
const resolveFunctionValue = (value, opt = {}) => {
|
|
657
|
+
const [{ name, type, value: itemValue }] = value;
|
|
658
|
+
const { length } = opt;
|
|
659
|
+
switch (type) {
|
|
660
|
+
case AST_TYPES.FUNCTION: {
|
|
661
|
+
return `${name}(${itemValue})`;
|
|
662
|
+
}
|
|
663
|
+
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
664
|
+
if (length > 1) {
|
|
665
|
+
return;
|
|
666
|
+
}
|
|
667
|
+
return name;
|
|
668
|
+
}
|
|
669
|
+
case AST_TYPES.IDENTIFIER: {
|
|
670
|
+
return name;
|
|
671
|
+
}
|
|
672
|
+
default:
|
|
673
|
+
}
|
|
674
|
+
};
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Resolves a length or percentage or number value.
|
|
678
|
+
*
|
|
679
|
+
* @param {Array<object>} value - The AST node array containing the value.
|
|
680
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
681
|
+
* @returns {string|undefined} The resolved length/percentage/number or undefined.
|
|
682
|
+
*/
|
|
683
|
+
const resolveNumericValue = (value, opt = {}) => {
|
|
684
|
+
const [{ name, type: itemType, value: itemValue }] = value;
|
|
685
|
+
const { length, type } = opt;
|
|
686
|
+
switch (itemType) {
|
|
687
|
+
case AST_TYPES.CALC: {
|
|
688
|
+
return `${name}(${itemValue})`;
|
|
689
|
+
}
|
|
690
|
+
case AST_TYPES.DIMENSION: {
|
|
691
|
+
if (type === "angle") {
|
|
692
|
+
return parseAngle(value, opt);
|
|
693
|
+
}
|
|
694
|
+
return parseLength(value, opt);
|
|
695
|
+
}
|
|
696
|
+
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
697
|
+
if (length > 1) {
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
return name;
|
|
701
|
+
}
|
|
702
|
+
case AST_TYPES.IDENTIFIER: {
|
|
703
|
+
return name;
|
|
704
|
+
}
|
|
705
|
+
case AST_TYPES.NUMBER: {
|
|
706
|
+
switch (type) {
|
|
707
|
+
case "angle": {
|
|
708
|
+
return parseAngle(value, opt);
|
|
709
|
+
}
|
|
710
|
+
case "length": {
|
|
711
|
+
return parseLength(value, opt);
|
|
712
|
+
}
|
|
713
|
+
case "percentage": {
|
|
714
|
+
return parsePercentage(value, opt);
|
|
715
|
+
}
|
|
716
|
+
default: {
|
|
717
|
+
return parseNumber(value, opt);
|
|
718
|
+
}
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
case AST_TYPES.PERCENTAGE: {
|
|
722
|
+
return parsePercentage(value, opt);
|
|
723
|
+
}
|
|
724
|
+
default:
|
|
725
|
+
}
|
|
726
|
+
};
|
|
727
|
+
|
|
728
|
+
/**
|
|
729
|
+
* Resolves a color value.
|
|
730
|
+
*
|
|
731
|
+
* @param {Array<object>} value - The AST node array containing the color value.
|
|
732
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
733
|
+
* @returns {string|undefined} The resolved color or undefined.
|
|
734
|
+
*/
|
|
735
|
+
const resolveColorValue = (value, opt = {}) => {
|
|
736
|
+
const [{ name, type }] = value;
|
|
737
|
+
const { length } = opt;
|
|
738
|
+
switch (type) {
|
|
739
|
+
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
740
|
+
if (length > 1) {
|
|
741
|
+
return;
|
|
742
|
+
}
|
|
743
|
+
return name;
|
|
744
|
+
}
|
|
745
|
+
default: {
|
|
746
|
+
return parseColor(value, opt);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Resolves a gradient or URL value.
|
|
753
|
+
*
|
|
754
|
+
* @param {Array<object>} value - The AST node array containing the color value.
|
|
755
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
756
|
+
* @returns {string|undefined} The resolved gradient/url or undefined.
|
|
757
|
+
*/
|
|
758
|
+
const resolveGradientUrlValue = (value, opt = {}) => {
|
|
759
|
+
const [{ name, type }] = value;
|
|
760
|
+
const { length } = opt;
|
|
761
|
+
switch (type) {
|
|
762
|
+
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
763
|
+
if (length > 1) {
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
return name;
|
|
767
|
+
}
|
|
768
|
+
case AST_TYPES.IDENTIFIER: {
|
|
769
|
+
return name;
|
|
770
|
+
}
|
|
771
|
+
case AST_TYPES.URL: {
|
|
772
|
+
return parseUrl(value, opt);
|
|
773
|
+
}
|
|
774
|
+
default: {
|
|
775
|
+
return parseGradient(value, opt);
|
|
776
|
+
}
|
|
777
|
+
}
|
|
778
|
+
};
|
|
779
|
+
|
|
780
|
+
/**
|
|
781
|
+
* Resolves a border shorthand value.
|
|
782
|
+
*
|
|
783
|
+
* @param {Array<object>} value - The AST node array containing the shorthand value.
|
|
784
|
+
* @param {object} subProps - The sub properties object.
|
|
785
|
+
* @param {Map} parsedValues - The Map of parsed values.
|
|
786
|
+
* @returns {Array|string|undefined} - The resolved [prop, value] pair, keyword or undefined.
|
|
787
|
+
*/
|
|
788
|
+
const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
|
|
789
|
+
const [{ isNumber, name, type, value: itemValue }] = value;
|
|
790
|
+
const { color: colorProp, style: styleProp, width: widthProp } = subProps;
|
|
791
|
+
switch (type) {
|
|
792
|
+
case AST_TYPES.CALC: {
|
|
793
|
+
if (isNumber || parsedValues.has(widthProp)) {
|
|
794
|
+
return;
|
|
795
|
+
}
|
|
796
|
+
return [widthProp, `${name}(${itemValue}`];
|
|
797
|
+
}
|
|
798
|
+
case AST_TYPES.DIMENSION:
|
|
799
|
+
case AST_TYPES.NUMBER: {
|
|
800
|
+
if (parsedValues.has(widthProp)) {
|
|
801
|
+
return;
|
|
802
|
+
}
|
|
803
|
+
const parsedValue = parseLength(value, { min: 0 });
|
|
804
|
+
if (!parsedValue) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
return [widthProp, parsedValue];
|
|
808
|
+
}
|
|
809
|
+
case AST_TYPES.FUNCTION:
|
|
810
|
+
case AST_TYPES.HASH: {
|
|
811
|
+
if (parsedValues.has(colorProp)) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
const parsedValue = parseColor(value);
|
|
815
|
+
if (!parsedValue) {
|
|
816
|
+
return;
|
|
817
|
+
}
|
|
818
|
+
return [colorProp, parsedValue];
|
|
819
|
+
}
|
|
820
|
+
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
821
|
+
return name;
|
|
822
|
+
}
|
|
823
|
+
case AST_TYPES.IDENTIFIER: {
|
|
824
|
+
if (isValidPropertyValue(widthProp, name)) {
|
|
825
|
+
if (parsedValues.has(widthProp)) {
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
828
|
+
return [widthProp, name];
|
|
829
|
+
} else if (isValidPropertyValue(styleProp, name)) {
|
|
830
|
+
if (parsedValues.has(styleProp)) {
|
|
831
|
+
return;
|
|
832
|
+
}
|
|
833
|
+
return [styleProp, name];
|
|
834
|
+
} else if (isValidPropertyValue(colorProp, name)) {
|
|
835
|
+
if (parsedValues.has(colorProp)) {
|
|
836
|
+
return;
|
|
837
|
+
}
|
|
838
|
+
return [colorProp, name];
|
|
839
|
+
}
|
|
840
|
+
break;
|
|
841
|
+
}
|
|
842
|
+
default:
|
|
843
|
+
}
|
|
844
|
+
};
|
|
845
|
+
|
|
846
|
+
module.exports = {
|
|
847
|
+
AST_TYPES,
|
|
848
|
+
hasCalcFunc,
|
|
849
|
+
hasVarFunc,
|
|
850
|
+
isGlobalKeyword,
|
|
851
|
+
isValidPropertyValue,
|
|
852
|
+
parseAngle,
|
|
853
|
+
parseCSS,
|
|
854
|
+
parseColor,
|
|
855
|
+
parseGradient,
|
|
856
|
+
parseLength,
|
|
857
|
+
parseNumber,
|
|
858
|
+
parsePercentage,
|
|
859
|
+
parsePropertyValue,
|
|
860
|
+
parseString,
|
|
861
|
+
parseUrl,
|
|
862
|
+
prepareValue,
|
|
863
|
+
resolveBorderShorthandValue,
|
|
864
|
+
resolveCalc,
|
|
865
|
+
resolveColorValue,
|
|
866
|
+
resolveFunctionValue,
|
|
867
|
+
resolveGradientUrlValue,
|
|
868
|
+
resolveKeywordValue,
|
|
869
|
+
resolveNumericValue,
|
|
870
|
+
splitValue
|
|
871
|
+
};
|