cssstyle 5.3.7 → 6.0.0
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 +359 -395
- package/lib/generated/.gitkeep +0 -0
- package/lib/generated/propertyDefinitions.js +3685 -1498
- package/lib/generated/propertyDescriptors.js +1705 -0
- package/lib/index.js +9 -0
- package/lib/normalize.js +127 -253
- package/lib/parsers.js +152 -164
- package/lib/properties/background.js +201 -202
- package/lib/properties/backgroundAttachment.js +35 -33
- package/lib/properties/backgroundClip.js +35 -33
- package/lib/properties/backgroundColor.js +26 -24
- package/lib/properties/backgroundImage.js +36 -34
- package/lib/properties/backgroundOrigin.js +35 -33
- package/lib/properties/backgroundPosition.js +57 -57
- package/lib/properties/backgroundRepeat.js +40 -37
- package/lib/properties/backgroundSize.js +38 -34
- package/lib/properties/border.js +41 -34
- package/lib/properties/{webkitBorderEndColor.js → borderBlockEndColor.js} +26 -22
- package/lib/properties/{webkitBorderAfterColor.js → borderBlockStartColor.js} +26 -22
- package/lib/properties/borderBottom.js +40 -36
- package/lib/properties/borderBottomColor.js +25 -21
- package/lib/properties/borderBottomStyle.js +25 -21
- package/lib/properties/borderBottomWidth.js +28 -24
- package/lib/properties/borderCollapse.js +25 -21
- package/lib/properties/borderColor.js +36 -33
- package/lib/properties/{webkitBorderStartColor.js → borderInlineEndColor.js} +26 -22
- package/lib/properties/borderInlineStartColor.js +49 -0
- package/lib/properties/borderLeft.js +40 -36
- package/lib/properties/borderLeftColor.js +25 -21
- package/lib/properties/borderLeftStyle.js +25 -21
- package/lib/properties/borderLeftWidth.js +28 -24
- package/lib/properties/borderRight.js +40 -36
- package/lib/properties/borderRightColor.js +25 -21
- package/lib/properties/borderRightStyle.js +25 -21
- package/lib/properties/borderRightWidth.js +28 -24
- package/lib/properties/borderSpacing.js +33 -29
- package/lib/properties/borderStyle.js +36 -33
- package/lib/properties/borderTop.js +40 -36
- package/lib/properties/borderTopColor.js +25 -21
- package/lib/properties/borderTopStyle.js +25 -21
- package/lib/properties/borderTopWidth.js +28 -24
- package/lib/properties/borderWidth.js +36 -33
- package/lib/properties/bottom.js +27 -23
- package/lib/properties/clear.js +25 -21
- package/lib/properties/clip.js +37 -31
- package/lib/properties/color.js +25 -21
- package/lib/properties/display.js +36 -30
- package/lib/properties/flex.js +53 -45
- package/lib/properties/flexBasis.js +28 -26
- package/lib/properties/flexGrow.js +28 -26
- package/lib/properties/flexShrink.js +28 -26
- package/lib/properties/float.js +25 -21
- package/lib/properties/floodColor.js +25 -21
- package/lib/properties/font.js +89 -118
- package/lib/properties/fontFamily.js +38 -33
- package/lib/properties/fontSize.js +29 -27
- package/lib/properties/fontStyle.js +38 -34
- package/lib/properties/fontVariant.js +35 -33
- package/lib/properties/fontWeight.js +33 -31
- package/lib/properties/height.js +28 -24
- package/lib/properties/left.js +27 -23
- package/lib/properties/lightingColor.js +25 -21
- package/lib/properties/lineHeight.js +28 -26
- package/lib/properties/margin.js +40 -34
- package/lib/properties/marginBottom.js +30 -27
- package/lib/properties/marginLeft.js +30 -27
- package/lib/properties/marginRight.js +30 -27
- package/lib/properties/marginTop.js +30 -27
- package/lib/properties/opacity.js +27 -23
- package/lib/properties/outlineColor.js +25 -21
- package/lib/properties/padding.js +40 -34
- package/lib/properties/paddingBottom.js +31 -28
- package/lib/properties/paddingLeft.js +31 -28
- package/lib/properties/paddingRight.js +31 -28
- package/lib/properties/paddingTop.js +31 -28
- package/lib/properties/right.js +27 -23
- package/lib/properties/stopColor.js +25 -21
- package/lib/properties/{webkitBorderBeforeColor.js → textEmphasisColor.js} +26 -22
- package/lib/properties/top.js +27 -23
- package/lib/properties/webkitTextFillColor.js +25 -21
- package/lib/properties/webkitTextStrokeColor.js +25 -21
- package/lib/properties/width.js +28 -24
- package/lib/utils/propertyDescriptors.js +129 -42
- package/lib/utils/strings.js +11 -156
- package/package.json +11 -21
- package/lib/generated/allProperties.js +0 -653
- package/lib/generated/implementedProperties.js +0 -1466
- package/lib/generated/properties.js +0 -6637
- package/lib/properties/webkitColumnRuleColor.js +0 -45
- package/lib/properties/webkitTapHighlightColor.js +0 -45
- package/lib/properties/webkitTextEmphasisColor.js +0 -45
- package/lib/utils/allExtraProperties.js +0 -155
- package/lib/utils/camelize.js +0 -37
package/lib/parsers.js
CHANGED
|
@@ -7,8 +7,12 @@ const {
|
|
|
7
7
|
const { next: syntaxes } = require("@csstools/css-syntax-patches-for-csstree");
|
|
8
8
|
const csstree = require("css-tree");
|
|
9
9
|
const { LRUCache } = require("lru-cache");
|
|
10
|
+
const propertyDefinitions = require("./generated/propertyDefinitions");
|
|
10
11
|
const { asciiLowercase } = require("./utils/strings");
|
|
11
12
|
|
|
13
|
+
// Constants
|
|
14
|
+
const CALC_FUNC_NAMES = "(?:a?(?:cos|sin|tan)|abs|atan2|calc|clamp|exp|hypot|log|max|min|mod|pow|rem|round|sign|sqrt)";
|
|
15
|
+
|
|
12
16
|
// CSS global keywords
|
|
13
17
|
// @see https://drafts.csswg.org/css-cascade-5/#defaulting-keywords
|
|
14
18
|
const GLOBAL_KEYS = new Set(["initial", "inherit", "unset", "revert", "revert-layer"]);
|
|
@@ -76,8 +80,6 @@ const AST_TYPES = Object.freeze({
|
|
|
76
80
|
});
|
|
77
81
|
|
|
78
82
|
// Regular expressions
|
|
79
|
-
const CALC_FUNC_NAMES =
|
|
80
|
-
"(?:a?(?:cos|sin|tan)|abs|atan2|calc|clamp|exp|hypot|log|max|min|mod|pow|rem|round|sign|sqrt)";
|
|
81
83
|
const calcRegEx = new RegExp(`^${CALC_FUNC_NAMES}\\(`);
|
|
82
84
|
const calcContainedRegEx = new RegExp(`(?<=[*/\\s(])${CALC_FUNC_NAMES}\\(`);
|
|
83
85
|
const calcNameRegEx = new RegExp(`^${CALC_FUNC_NAMES}$`);
|
|
@@ -98,14 +100,14 @@ const lruCache = new LRUCache({
|
|
|
98
100
|
* @param {string|number|null|undefined} value - The value to prepare.
|
|
99
101
|
* @returns {string} The prepared value.
|
|
100
102
|
*/
|
|
101
|
-
|
|
103
|
+
function prepareValue(value) {
|
|
102
104
|
// `null` is converted to an empty string.
|
|
103
105
|
// @see https://webidl.spec.whatwg.org/#LegacyNullToEmptyString
|
|
104
106
|
if (value === null) {
|
|
105
107
|
return "";
|
|
106
108
|
}
|
|
107
109
|
return `${value}`.trim();
|
|
108
|
-
}
|
|
110
|
+
}
|
|
109
111
|
|
|
110
112
|
/**
|
|
111
113
|
* Checks if the value is a global keyword.
|
|
@@ -113,9 +115,9 @@ const prepareValue = (value) => {
|
|
|
113
115
|
* @param {string} val - The value to check.
|
|
114
116
|
* @returns {boolean} True if the value is a global keyword, false otherwise.
|
|
115
117
|
*/
|
|
116
|
-
|
|
118
|
+
function isGlobalKeyword(val) {
|
|
117
119
|
return GLOBAL_KEYS.has(asciiLowercase(val));
|
|
118
|
-
}
|
|
120
|
+
}
|
|
119
121
|
|
|
120
122
|
/**
|
|
121
123
|
* Checks if the value starts with or contains a CSS var() function.
|
|
@@ -123,9 +125,9 @@ const isGlobalKeyword = (val) => {
|
|
|
123
125
|
* @param {string} val - The value to check.
|
|
124
126
|
* @returns {boolean} True if the value contains a var() function, false otherwise.
|
|
125
127
|
*/
|
|
126
|
-
|
|
128
|
+
function hasVarFunc(val) {
|
|
127
129
|
return varRegEx.test(val) || varContainedRegEx.test(val);
|
|
128
|
-
}
|
|
130
|
+
}
|
|
129
131
|
|
|
130
132
|
/**
|
|
131
133
|
* Checks if the value starts with or contains CSS calc() or math functions.
|
|
@@ -133,26 +135,20 @@ const hasVarFunc = (val) => {
|
|
|
133
135
|
* @param {string} val - The value to check.
|
|
134
136
|
* @returns {boolean} True if the value contains calc() or math functions, false otherwise.
|
|
135
137
|
*/
|
|
136
|
-
|
|
138
|
+
function hasCalcFunc(val) {
|
|
137
139
|
return calcRegEx.test(val) || calcContainedRegEx.test(val);
|
|
138
|
-
}
|
|
140
|
+
}
|
|
139
141
|
|
|
140
142
|
/**
|
|
141
143
|
* Parses a CSS string into an AST.
|
|
142
144
|
*
|
|
143
145
|
* @param {string} val - The CSS string to parse.
|
|
144
146
|
* @param {object} opt - The options for parsing.
|
|
145
|
-
* @
|
|
146
|
-
* @returns {object} The AST or a plain object.
|
|
147
|
+
* @returns {object} The AST.
|
|
147
148
|
*/
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
if (toObject) {
|
|
152
|
-
return cssTree.toPlainObject(ast);
|
|
153
|
-
}
|
|
154
|
-
return ast;
|
|
155
|
-
};
|
|
149
|
+
function parseCSS(val, opt) {
|
|
150
|
+
return cssTree.parse(prepareValue(val), opt);
|
|
151
|
+
}
|
|
156
152
|
|
|
157
153
|
/**
|
|
158
154
|
* Checks if the value is a valid property value.
|
|
@@ -162,20 +158,14 @@ const parseCSS = (val, opt, toObject = false) => {
|
|
|
162
158
|
* @param {string} val - The property value.
|
|
163
159
|
* @returns {boolean} True if the value is valid, false otherwise.
|
|
164
160
|
*/
|
|
165
|
-
|
|
161
|
+
function isValidPropertyValue(prop, val) {
|
|
162
|
+
if (!propertyDefinitions.has(prop)) {
|
|
163
|
+
return false;
|
|
164
|
+
}
|
|
166
165
|
val = prepareValue(val);
|
|
167
166
|
if (val === "") {
|
|
168
167
|
return true;
|
|
169
168
|
}
|
|
170
|
-
// cssTree.lexer does not support deprecated system colors
|
|
171
|
-
// @see https://github.com/w3c/webref/issues/1519#issuecomment-3120290261
|
|
172
|
-
// @see https://github.com/w3c/webref/issues/1647
|
|
173
|
-
if (SYS_COLORS.has(asciiLowercase(val))) {
|
|
174
|
-
if (/^(?:-webkit-)?(?:[a-z][a-z\d]*-)*color$/i.test(prop)) {
|
|
175
|
-
return true;
|
|
176
|
-
}
|
|
177
|
-
return false;
|
|
178
|
-
}
|
|
179
169
|
const cacheKey = `isValidPropertyValue_${prop}_${val}`;
|
|
180
170
|
const cachedValue = lruCache.get(cacheKey);
|
|
181
171
|
if (typeof cachedValue === "boolean") {
|
|
@@ -193,7 +183,7 @@ const isValidPropertyValue = (prop, val) => {
|
|
|
193
183
|
}
|
|
194
184
|
lruCache.set(cacheKey, result);
|
|
195
185
|
return result;
|
|
196
|
-
}
|
|
186
|
+
}
|
|
197
187
|
|
|
198
188
|
/**
|
|
199
189
|
* Resolves CSS math functions.
|
|
@@ -202,7 +192,7 @@ const isValidPropertyValue = (prop, val) => {
|
|
|
202
192
|
* @param {object} [opt={ format: "specifiedValue" }] - The options for resolving.
|
|
203
193
|
* @returns {string|undefined} The resolved value.
|
|
204
194
|
*/
|
|
205
|
-
|
|
195
|
+
function resolveCalc(val, opt = { format: "specifiedValue" }) {
|
|
206
196
|
val = prepareValue(val);
|
|
207
197
|
if (val === "" || hasVarFunc(val) || !hasCalcFunc(val)) {
|
|
208
198
|
return val;
|
|
@@ -212,13 +202,12 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
212
202
|
if (typeof cachedValue === "string") {
|
|
213
203
|
return cachedValue;
|
|
214
204
|
}
|
|
215
|
-
const
|
|
216
|
-
if (!
|
|
205
|
+
const ast = parseCSS(val, { context: "value" });
|
|
206
|
+
if (!ast?.children) {
|
|
217
207
|
return;
|
|
218
208
|
}
|
|
219
|
-
const { children: items } = obj;
|
|
220
209
|
const values = [];
|
|
221
|
-
for (const item of
|
|
210
|
+
for (const item of ast.children) {
|
|
222
211
|
const { type: itemType, name: itemName, value: itemValue } = item;
|
|
223
212
|
if (itemType === AST_TYPES.FUNCTION) {
|
|
224
213
|
const value = cssTree
|
|
@@ -240,7 +229,7 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
240
229
|
const resolvedValue = values.join(" ");
|
|
241
230
|
lruCache.set(cacheKey, resolvedValue);
|
|
242
231
|
return resolvedValue;
|
|
243
|
-
}
|
|
232
|
+
}
|
|
244
233
|
|
|
245
234
|
/**
|
|
246
235
|
* Parses a property value.
|
|
@@ -251,8 +240,11 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
251
240
|
* @param {object} [opt={}] - The options for parsing.
|
|
252
241
|
* @returns {string|Array<object>|undefined} The parsed value.
|
|
253
242
|
*/
|
|
254
|
-
|
|
255
|
-
|
|
243
|
+
function parsePropertyValue(prop, val, opt = {}) {
|
|
244
|
+
if (!propertyDefinitions.has(prop)) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const { caseSensitive } = opt;
|
|
256
248
|
val = prepareValue(val);
|
|
257
249
|
if (val === "" || hasVarFunc(val)) {
|
|
258
250
|
return val;
|
|
@@ -269,41 +261,18 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
269
261
|
const cachedValue = lruCache.get(cacheKey);
|
|
270
262
|
if (cachedValue === false) {
|
|
271
263
|
return;
|
|
272
|
-
} else if (
|
|
273
|
-
if (Array.isArray(cachedValue)) {
|
|
274
|
-
return cachedValue;
|
|
275
|
-
}
|
|
276
|
-
} else if (typeof cachedValue === "string") {
|
|
264
|
+
} else if (cachedValue !== undefined) {
|
|
277
265
|
return cachedValue;
|
|
278
266
|
}
|
|
279
267
|
let parsedValue;
|
|
280
268
|
const lowerCasedValue = asciiLowercase(val);
|
|
281
269
|
if (GLOBAL_KEYS.has(lowerCasedValue)) {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
name: lowerCasedValue
|
|
287
|
-
}
|
|
288
|
-
];
|
|
289
|
-
} else {
|
|
290
|
-
parsedValue = lowerCasedValue;
|
|
291
|
-
}
|
|
292
|
-
} else if (SYS_COLORS.has(lowerCasedValue)) {
|
|
293
|
-
if (/^(?:(?:-webkit-)?(?:[a-z][a-z\d]*-)*color|border)$/i.test(prop)) {
|
|
294
|
-
if (inArray) {
|
|
295
|
-
parsedValue = [
|
|
296
|
-
{
|
|
297
|
-
type: AST_TYPES.IDENTIFIER,
|
|
298
|
-
name: lowerCasedValue
|
|
299
|
-
}
|
|
300
|
-
];
|
|
301
|
-
} else {
|
|
302
|
-
parsedValue = lowerCasedValue;
|
|
270
|
+
parsedValue = [
|
|
271
|
+
{
|
|
272
|
+
type: AST_TYPES.GLOBAL_KEYWORD,
|
|
273
|
+
name: lowerCasedValue
|
|
303
274
|
}
|
|
304
|
-
|
|
305
|
-
parsedValue = false;
|
|
306
|
-
}
|
|
275
|
+
];
|
|
307
276
|
} else {
|
|
308
277
|
try {
|
|
309
278
|
const ast = parseCSS(val, {
|
|
@@ -312,9 +281,9 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
312
281
|
const { error, matched } = cssTree.lexer.matchProperty(prop, ast);
|
|
313
282
|
if (error || !matched) {
|
|
314
283
|
parsedValue = false;
|
|
315
|
-
} else
|
|
316
|
-
const
|
|
317
|
-
const
|
|
284
|
+
} else {
|
|
285
|
+
const items = ast.children;
|
|
286
|
+
const itemCount = items.size;
|
|
318
287
|
const values = [];
|
|
319
288
|
for (const item of items) {
|
|
320
289
|
const { children, name, type, value, unit } = item;
|
|
@@ -332,12 +301,12 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
332
301
|
.generate(item)
|
|
333
302
|
.replace(/\)(?!\)|\s|,)/g, ") ")
|
|
334
303
|
.trim();
|
|
335
|
-
const raw =
|
|
304
|
+
const raw = itemCount === 1 ? val : css;
|
|
336
305
|
// Remove "${name}(" from the start and ")" from the end
|
|
337
306
|
const itemValue = raw.slice(name.length + 1, -1).trim();
|
|
338
307
|
if (name === "calc") {
|
|
339
|
-
if (children.
|
|
340
|
-
const
|
|
308
|
+
if (children.size === 1) {
|
|
309
|
+
const child = children.first;
|
|
341
310
|
if (child.type === AST_TYPES.NUMBER) {
|
|
342
311
|
values.push({
|
|
343
312
|
type: AST_TYPES.CALC,
|
|
@@ -391,8 +360,6 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
391
360
|
}
|
|
392
361
|
}
|
|
393
362
|
parsedValue = values;
|
|
394
|
-
} else {
|
|
395
|
-
parsedValue = val;
|
|
396
363
|
}
|
|
397
364
|
} catch {
|
|
398
365
|
parsedValue = false;
|
|
@@ -403,18 +370,18 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
403
370
|
return;
|
|
404
371
|
}
|
|
405
372
|
return parsedValue;
|
|
406
|
-
}
|
|
373
|
+
}
|
|
407
374
|
|
|
408
375
|
/**
|
|
409
376
|
* Parses a numeric value (number, dimension, percentage).
|
|
410
|
-
* Helper function for
|
|
377
|
+
* Helper function for serializeNumber, serializeLength, etc.
|
|
411
378
|
*
|
|
412
379
|
* @param {Array<object>} val - The AST value.
|
|
413
380
|
* @param {object} [opt={}] - The options for parsing.
|
|
414
381
|
* @param {Function} validateType - Function to validate the node type.
|
|
415
382
|
* @returns {object|undefined} The parsed result containing num and unit, or undefined.
|
|
416
383
|
*/
|
|
417
|
-
|
|
384
|
+
function parseNumericValue(val, opt, validateType) {
|
|
418
385
|
const [item] = val;
|
|
419
386
|
const { type, value, unit } = item ?? {};
|
|
420
387
|
if (!validateType(type, value, unit)) {
|
|
@@ -438,31 +405,31 @@ const parseNumericValue = (val, opt, validateType) => {
|
|
|
438
405
|
unit: unit ? asciiLowercase(unit) : null,
|
|
439
406
|
type
|
|
440
407
|
};
|
|
441
|
-
}
|
|
408
|
+
}
|
|
442
409
|
|
|
443
410
|
/**
|
|
444
|
-
*
|
|
411
|
+
* Serializes a <number> value.
|
|
445
412
|
*
|
|
446
413
|
* @param {Array<object>} val - The AST value.
|
|
447
414
|
* @param {object} [opt={}] - The options for parsing.
|
|
448
415
|
* @returns {string|undefined} The parsed number.
|
|
449
416
|
*/
|
|
450
|
-
|
|
417
|
+
function serializeNumber(val, opt = {}) {
|
|
451
418
|
const res = parseNumericValue(val, opt, (type) => type === AST_TYPES.NUMBER);
|
|
452
419
|
if (!res) {
|
|
453
420
|
return;
|
|
454
421
|
}
|
|
455
422
|
return `${res.num}`;
|
|
456
|
-
}
|
|
423
|
+
}
|
|
457
424
|
|
|
458
425
|
/**
|
|
459
|
-
*
|
|
426
|
+
* Serializes an <angle> value.
|
|
460
427
|
*
|
|
461
428
|
* @param {Array<object>} val - The AST value.
|
|
462
429
|
* @param {object} [opt={}] - The options for parsing.
|
|
463
|
-
* @returns {string|undefined} The
|
|
430
|
+
* @returns {string|undefined} The serialized angle.
|
|
464
431
|
*/
|
|
465
|
-
|
|
432
|
+
function serializeAngle(val, opt = {}) {
|
|
466
433
|
const res = parseNumericValue(
|
|
467
434
|
val,
|
|
468
435
|
opt,
|
|
@@ -472,67 +439,85 @@ const parseLength = (val, opt = {}) => {
|
|
|
472
439
|
return;
|
|
473
440
|
}
|
|
474
441
|
const { num, unit } = res;
|
|
475
|
-
if (
|
|
476
|
-
|
|
477
|
-
|
|
442
|
+
if (unit) {
|
|
443
|
+
if (!/^(?:deg|g?rad|turn)$/i.test(unit)) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
478
446
|
return `${num}${unit}`;
|
|
447
|
+
} else if (num === 0) {
|
|
448
|
+
return `${num}deg`;
|
|
479
449
|
}
|
|
480
|
-
}
|
|
450
|
+
}
|
|
481
451
|
|
|
482
452
|
/**
|
|
483
|
-
*
|
|
453
|
+
* Serializes a <length> value.
|
|
484
454
|
*
|
|
485
455
|
* @param {Array<object>} val - The AST value.
|
|
486
456
|
* @param {object} [opt={}] - The options for parsing.
|
|
487
|
-
* @returns {string|undefined} The
|
|
457
|
+
* @returns {string|undefined} The serialized length.
|
|
488
458
|
*/
|
|
489
|
-
|
|
459
|
+
function serializeLength(val, opt = {}) {
|
|
490
460
|
const res = parseNumericValue(
|
|
491
461
|
val,
|
|
492
462
|
opt,
|
|
493
|
-
(type, value) => type === AST_TYPES.
|
|
463
|
+
(type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
|
|
494
464
|
);
|
|
495
465
|
if (!res) {
|
|
496
466
|
return;
|
|
497
467
|
}
|
|
498
|
-
const { num } = res;
|
|
499
|
-
|
|
500
|
-
}
|
|
468
|
+
const { num, unit } = res;
|
|
469
|
+
if (num === 0 && !unit) {
|
|
470
|
+
return `${num}px`;
|
|
471
|
+
} else if (unit) {
|
|
472
|
+
return `${num}${unit}`;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
501
475
|
|
|
502
476
|
/**
|
|
503
|
-
*
|
|
477
|
+
* Serializes a <dimension> value, e.g. <frequency>, <time> and <resolution>.
|
|
504
478
|
*
|
|
505
479
|
* @param {Array<object>} val - The AST value.
|
|
506
480
|
* @param {object} [opt={}] - The options for parsing.
|
|
507
|
-
* @returns {string|undefined} The
|
|
481
|
+
* @returns {string|undefined} The serialized dimension.
|
|
508
482
|
*/
|
|
509
|
-
|
|
510
|
-
const res = parseNumericValue(
|
|
511
|
-
val,
|
|
512
|
-
opt,
|
|
513
|
-
(type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
|
|
514
|
-
);
|
|
483
|
+
function serializeDimension(val, opt = {}) {
|
|
484
|
+
const res = parseNumericValue(val, opt, (type) => type === AST_TYPES.DIMENSION);
|
|
515
485
|
if (!res) {
|
|
516
486
|
return;
|
|
517
487
|
}
|
|
518
488
|
const { num, unit } = res;
|
|
519
489
|
if (unit) {
|
|
520
|
-
if (!/^(?:deg|g?rad|turn)$/i.test(unit)) {
|
|
521
|
-
return;
|
|
522
|
-
}
|
|
523
490
|
return `${num}${unit}`;
|
|
524
|
-
} else if (num === 0) {
|
|
525
|
-
return `${num}deg`;
|
|
526
491
|
}
|
|
527
|
-
}
|
|
492
|
+
}
|
|
528
493
|
|
|
529
494
|
/**
|
|
530
|
-
*
|
|
495
|
+
* Serializes a <percentage> value.
|
|
531
496
|
*
|
|
532
497
|
* @param {Array<object>} val - The AST value.
|
|
533
|
-
* @
|
|
498
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
499
|
+
* @returns {string|undefined} The serialized percentage.
|
|
534
500
|
*/
|
|
535
|
-
|
|
501
|
+
function serializePercentage(val, opt = {}) {
|
|
502
|
+
const res = parseNumericValue(
|
|
503
|
+
val,
|
|
504
|
+
opt,
|
|
505
|
+
(type, value) => type === AST_TYPES.PERCENTAGE || (type === AST_TYPES.NUMBER && value === "0")
|
|
506
|
+
);
|
|
507
|
+
if (!res) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
const { num } = res;
|
|
511
|
+
return `${num}%`;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
/**
|
|
515
|
+
* Serializes a <url> value.
|
|
516
|
+
*
|
|
517
|
+
* @param {Array<object>} val - The AST value.
|
|
518
|
+
* @returns {string|undefined} The serialized url.
|
|
519
|
+
*/
|
|
520
|
+
function serializeURL(val) {
|
|
536
521
|
const [item] = val;
|
|
537
522
|
const { type, value } = item ?? {};
|
|
538
523
|
if (type !== AST_TYPES.URL) {
|
|
@@ -540,15 +525,15 @@ const parseUrl = (val) => {
|
|
|
540
525
|
}
|
|
541
526
|
const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
|
|
542
527
|
return `url("${str}")`;
|
|
543
|
-
}
|
|
528
|
+
}
|
|
544
529
|
|
|
545
530
|
/**
|
|
546
|
-
*
|
|
531
|
+
* Serializes a <string> value.
|
|
547
532
|
*
|
|
548
533
|
* @param {Array<object>} val - The AST value.
|
|
549
|
-
* @returns {string|undefined} The
|
|
534
|
+
* @returns {string|undefined} The serialized string.
|
|
550
535
|
*/
|
|
551
|
-
|
|
536
|
+
function serializeString(val) {
|
|
552
537
|
const [item] = val;
|
|
553
538
|
const { type, value } = item ?? {};
|
|
554
539
|
if (type !== AST_TYPES.STRING) {
|
|
@@ -556,15 +541,15 @@ const parseString = (val) => {
|
|
|
556
541
|
}
|
|
557
542
|
const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
|
|
558
543
|
return `"${str}"`;
|
|
559
|
-
}
|
|
544
|
+
}
|
|
560
545
|
|
|
561
546
|
/**
|
|
562
|
-
*
|
|
547
|
+
* Serializes a <color> value.
|
|
563
548
|
*
|
|
564
549
|
* @param {Array<object>} val - The AST value.
|
|
565
|
-
* @returns {string|undefined} The
|
|
550
|
+
* @returns {string|undefined} The serialized color.
|
|
566
551
|
*/
|
|
567
|
-
|
|
552
|
+
function serializeColor(val) {
|
|
568
553
|
const [item] = val;
|
|
569
554
|
const { name, type, value } = item ?? {};
|
|
570
555
|
switch (type) {
|
|
@@ -600,15 +585,15 @@ const parseColor = (val) => {
|
|
|
600
585
|
}
|
|
601
586
|
default:
|
|
602
587
|
}
|
|
603
|
-
}
|
|
588
|
+
}
|
|
604
589
|
|
|
605
590
|
/**
|
|
606
|
-
*
|
|
591
|
+
* Serializes a <gradient> value.
|
|
607
592
|
*
|
|
608
593
|
* @param {Array<object>} val - The AST value.
|
|
609
|
-
* @returns {string|undefined} The
|
|
594
|
+
* @returns {string|undefined} The serialized gradient.
|
|
610
595
|
*/
|
|
611
|
-
|
|
596
|
+
function serializeGradient(val) {
|
|
612
597
|
const [item] = val;
|
|
613
598
|
const { name, type, value } = item ?? {};
|
|
614
599
|
if (type !== AST_TYPES.FUNCTION) {
|
|
@@ -620,7 +605,7 @@ const parseGradient = (val) => {
|
|
|
620
605
|
if (res) {
|
|
621
606
|
return res;
|
|
622
607
|
}
|
|
623
|
-
}
|
|
608
|
+
}
|
|
624
609
|
|
|
625
610
|
/**
|
|
626
611
|
* Resolves a keyword value.
|
|
@@ -629,7 +614,7 @@ const parseGradient = (val) => {
|
|
|
629
614
|
* @param {object} [opt={}] - The options for parsing.
|
|
630
615
|
* @returns {string|undefined} The resolved keyword or undefined.
|
|
631
616
|
*/
|
|
632
|
-
|
|
617
|
+
function resolveKeywordValue(value, opt = {}) {
|
|
633
618
|
const [{ name, type }] = value;
|
|
634
619
|
const { length } = opt;
|
|
635
620
|
switch (type) {
|
|
@@ -644,7 +629,7 @@ const resolveKeywordValue = (value, opt = {}) => {
|
|
|
644
629
|
}
|
|
645
630
|
default:
|
|
646
631
|
}
|
|
647
|
-
}
|
|
632
|
+
}
|
|
648
633
|
|
|
649
634
|
/**
|
|
650
635
|
* Resolves a function value.
|
|
@@ -653,7 +638,7 @@ const resolveKeywordValue = (value, opt = {}) => {
|
|
|
653
638
|
* @param {object} [opt={}] - The options for parsing.
|
|
654
639
|
* @returns {string|undefined} The resolved function or undefined.
|
|
655
640
|
*/
|
|
656
|
-
|
|
641
|
+
function resolveFunctionValue(value, opt = {}) {
|
|
657
642
|
const [{ name, type, value: itemValue }] = value;
|
|
658
643
|
const { length } = opt;
|
|
659
644
|
switch (type) {
|
|
@@ -671,16 +656,16 @@ const resolveFunctionValue = (value, opt = {}) => {
|
|
|
671
656
|
}
|
|
672
657
|
default:
|
|
673
658
|
}
|
|
674
|
-
}
|
|
659
|
+
}
|
|
675
660
|
|
|
676
661
|
/**
|
|
677
|
-
* Resolves a
|
|
662
|
+
* Resolves a numeric value.
|
|
678
663
|
*
|
|
679
|
-
* @param {Array<object>} value - The AST node array containing the value.
|
|
664
|
+
* @param {Array<object>} value - The AST node array containing the numeric value.
|
|
680
665
|
* @param {object} [opt={}] - The options for parsing.
|
|
681
666
|
* @returns {string|undefined} The resolved length/percentage/number or undefined.
|
|
682
667
|
*/
|
|
683
|
-
|
|
668
|
+
function resolveNumericValue(value, opt = {}) {
|
|
684
669
|
const [{ name, type: itemType, value: itemValue }] = value;
|
|
685
670
|
const { length, type } = opt;
|
|
686
671
|
switch (itemType) {
|
|
@@ -689,9 +674,11 @@ const resolveNumericValue = (value, opt = {}) => {
|
|
|
689
674
|
}
|
|
690
675
|
case AST_TYPES.DIMENSION: {
|
|
691
676
|
if (type === "angle") {
|
|
692
|
-
return
|
|
677
|
+
return serializeAngle(value, opt);
|
|
678
|
+
} else if (type === "length") {
|
|
679
|
+
return serializeLength(value, opt);
|
|
693
680
|
}
|
|
694
|
-
return
|
|
681
|
+
return serializeDimension(value, opt);
|
|
695
682
|
}
|
|
696
683
|
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
697
684
|
if (length > 1) {
|
|
@@ -705,25 +692,25 @@ const resolveNumericValue = (value, opt = {}) => {
|
|
|
705
692
|
case AST_TYPES.NUMBER: {
|
|
706
693
|
switch (type) {
|
|
707
694
|
case "angle": {
|
|
708
|
-
return
|
|
695
|
+
return serializeAngle(value, opt);
|
|
709
696
|
}
|
|
710
697
|
case "length": {
|
|
711
|
-
return
|
|
698
|
+
return serializeLength(value, opt);
|
|
712
699
|
}
|
|
713
700
|
case "percentage": {
|
|
714
|
-
return
|
|
701
|
+
return serializePercentage(value, opt);
|
|
715
702
|
}
|
|
716
703
|
default: {
|
|
717
|
-
return
|
|
704
|
+
return serializeNumber(value, opt);
|
|
718
705
|
}
|
|
719
706
|
}
|
|
720
707
|
}
|
|
721
708
|
case AST_TYPES.PERCENTAGE: {
|
|
722
|
-
return
|
|
709
|
+
return serializePercentage(value, opt);
|
|
723
710
|
}
|
|
724
711
|
default:
|
|
725
712
|
}
|
|
726
|
-
}
|
|
713
|
+
}
|
|
727
714
|
|
|
728
715
|
/**
|
|
729
716
|
* Resolves a color value.
|
|
@@ -732,7 +719,7 @@ const resolveNumericValue = (value, opt = {}) => {
|
|
|
732
719
|
* @param {object} [opt={}] - The options for parsing.
|
|
733
720
|
* @returns {string|undefined} The resolved color or undefined.
|
|
734
721
|
*/
|
|
735
|
-
|
|
722
|
+
function resolveColorValue(value, opt = {}) {
|
|
736
723
|
const [{ name, type }] = value;
|
|
737
724
|
const { length } = opt;
|
|
738
725
|
switch (type) {
|
|
@@ -743,19 +730,19 @@ const resolveColorValue = (value, opt = {}) => {
|
|
|
743
730
|
return name;
|
|
744
731
|
}
|
|
745
732
|
default: {
|
|
746
|
-
return
|
|
733
|
+
return serializeColor(value, opt);
|
|
747
734
|
}
|
|
748
735
|
}
|
|
749
|
-
}
|
|
736
|
+
}
|
|
750
737
|
|
|
751
738
|
/**
|
|
752
|
-
* Resolves
|
|
739
|
+
* Resolves an image value.
|
|
753
740
|
*
|
|
754
|
-
* @param {Array<object>} value - The AST node array containing the
|
|
741
|
+
* @param {Array<object>} value - The AST node array containing the image value.
|
|
755
742
|
* @param {object} [opt={}] - The options for parsing.
|
|
756
743
|
* @returns {string|undefined} The resolved gradient/url or undefined.
|
|
757
744
|
*/
|
|
758
|
-
|
|
745
|
+
function resolveImageValue(value, opt = {}) {
|
|
759
746
|
const [{ name, type }] = value;
|
|
760
747
|
const { length } = opt;
|
|
761
748
|
switch (type) {
|
|
@@ -769,13 +756,13 @@ const resolveGradientUrlValue = (value, opt = {}) => {
|
|
|
769
756
|
return name;
|
|
770
757
|
}
|
|
771
758
|
case AST_TYPES.URL: {
|
|
772
|
-
return
|
|
759
|
+
return serializeURL(value, opt);
|
|
773
760
|
}
|
|
774
761
|
default: {
|
|
775
|
-
return
|
|
762
|
+
return serializeGradient(value, opt);
|
|
776
763
|
}
|
|
777
764
|
}
|
|
778
|
-
}
|
|
765
|
+
}
|
|
779
766
|
|
|
780
767
|
/**
|
|
781
768
|
* Resolves a border shorthand value.
|
|
@@ -785,7 +772,7 @@ const resolveGradientUrlValue = (value, opt = {}) => {
|
|
|
785
772
|
* @param {Map} parsedValues - The Map of parsed values.
|
|
786
773
|
* @returns {Array|string|undefined} - The resolved [prop, value] pair, keyword or undefined.
|
|
787
774
|
*/
|
|
788
|
-
|
|
775
|
+
function resolveBorderShorthandValue(value, subProps, parsedValues) {
|
|
789
776
|
const [{ isNumber, name, type, value: itemValue }] = value;
|
|
790
777
|
const { color: colorProp, style: styleProp, width: widthProp } = subProps;
|
|
791
778
|
switch (type) {
|
|
@@ -800,7 +787,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
|
|
|
800
787
|
if (parsedValues.has(widthProp)) {
|
|
801
788
|
return;
|
|
802
789
|
}
|
|
803
|
-
const parsedValue =
|
|
790
|
+
const parsedValue = serializeLength(value, { min: 0 });
|
|
804
791
|
if (!parsedValue) {
|
|
805
792
|
return;
|
|
806
793
|
}
|
|
@@ -811,7 +798,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
|
|
|
811
798
|
if (parsedValues.has(colorProp)) {
|
|
812
799
|
return;
|
|
813
800
|
}
|
|
814
|
-
const parsedValue =
|
|
801
|
+
const parsedValue = serializeColor(value);
|
|
815
802
|
if (!parsedValue) {
|
|
816
803
|
return;
|
|
817
804
|
}
|
|
@@ -841,7 +828,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
|
|
|
841
828
|
}
|
|
842
829
|
default:
|
|
843
830
|
}
|
|
844
|
-
}
|
|
831
|
+
}
|
|
845
832
|
|
|
846
833
|
module.exports = {
|
|
847
834
|
AST_TYPES,
|
|
@@ -849,23 +836,24 @@ module.exports = {
|
|
|
849
836
|
hasVarFunc,
|
|
850
837
|
isGlobalKeyword,
|
|
851
838
|
isValidPropertyValue,
|
|
852
|
-
parseAngle,
|
|
853
839
|
parseCSS,
|
|
854
|
-
parseColor,
|
|
855
|
-
parseGradient,
|
|
856
|
-
parseLength,
|
|
857
|
-
parseNumber,
|
|
858
|
-
parsePercentage,
|
|
859
840
|
parsePropertyValue,
|
|
860
|
-
parseString,
|
|
861
|
-
parseUrl,
|
|
862
841
|
prepareValue,
|
|
863
842
|
resolveBorderShorthandValue,
|
|
864
843
|
resolveCalc,
|
|
865
844
|
resolveColorValue,
|
|
866
845
|
resolveFunctionValue,
|
|
867
|
-
|
|
846
|
+
resolveImageValue,
|
|
868
847
|
resolveKeywordValue,
|
|
869
848
|
resolveNumericValue,
|
|
849
|
+
serializeAngle,
|
|
850
|
+
serializeColor,
|
|
851
|
+
serializeDimension,
|
|
852
|
+
serializeGradient,
|
|
853
|
+
serializeLength,
|
|
854
|
+
serializeNumber,
|
|
855
|
+
serializePercentage,
|
|
856
|
+
serializeString,
|
|
857
|
+
serializeURL,
|
|
870
858
|
splitValue
|
|
871
859
|
};
|