cssstyle 5.3.6 → 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 +360 -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 +176 -309
- package/lib/parsers.js +155 -191
- 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 +27 -25
- 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} +27 -23
- package/lib/properties/{webkitBorderAfterColor.js → borderBlockStartColor.js} +27 -23
- package/lib/properties/borderBottom.js +40 -36
- package/lib/properties/borderBottomColor.js +26 -22
- package/lib/properties/borderBottomStyle.js +26 -22
- package/lib/properties/borderBottomWidth.js +29 -25
- package/lib/properties/borderCollapse.js +26 -22
- package/lib/properties/borderColor.js +36 -33
- package/lib/properties/{webkitBorderStartColor.js → borderInlineEndColor.js} +27 -23
- package/lib/properties/borderInlineStartColor.js +49 -0
- package/lib/properties/borderLeft.js +40 -36
- package/lib/properties/borderLeftColor.js +26 -22
- package/lib/properties/borderLeftStyle.js +26 -22
- package/lib/properties/borderLeftWidth.js +29 -25
- package/lib/properties/borderRight.js +40 -36
- package/lib/properties/borderRightColor.js +26 -22
- package/lib/properties/borderRightStyle.js +26 -22
- package/lib/properties/borderRightWidth.js +29 -25
- 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 +26 -22
- package/lib/properties/borderTopStyle.js +26 -22
- package/lib/properties/borderTopWidth.js +29 -25
- package/lib/properties/borderWidth.js +36 -33
- package/lib/properties/bottom.js +28 -24
- package/lib/properties/clear.js +26 -22
- package/lib/properties/clip.js +37 -31
- package/lib/properties/color.js +26 -22
- package/lib/properties/display.js +36 -30
- package/lib/properties/flex.js +53 -45
- package/lib/properties/flexBasis.js +29 -27
- package/lib/properties/flexGrow.js +29 -27
- package/lib/properties/flexShrink.js +29 -27
- package/lib/properties/float.js +26 -22
- package/lib/properties/floodColor.js +26 -22
- package/lib/properties/font.js +89 -118
- package/lib/properties/fontFamily.js +38 -33
- package/lib/properties/fontSize.js +30 -28
- package/lib/properties/fontStyle.js +38 -34
- package/lib/properties/fontVariant.js +35 -33
- package/lib/properties/fontWeight.js +34 -32
- package/lib/properties/height.js +29 -25
- package/lib/properties/left.js +28 -24
- package/lib/properties/lightingColor.js +26 -22
- package/lib/properties/lineHeight.js +29 -27
- package/lib/properties/margin.js +40 -34
- package/lib/properties/marginBottom.js +31 -28
- package/lib/properties/marginLeft.js +31 -28
- package/lib/properties/marginRight.js +31 -28
- package/lib/properties/marginTop.js +31 -28
- package/lib/properties/opacity.js +28 -24
- package/lib/properties/outlineColor.js +26 -22
- package/lib/properties/padding.js +40 -34
- package/lib/properties/paddingBottom.js +32 -29
- package/lib/properties/paddingLeft.js +32 -29
- package/lib/properties/paddingRight.js +32 -29
- package/lib/properties/paddingTop.js +32 -29
- package/lib/properties/right.js +28 -24
- package/lib/properties/stopColor.js +26 -22
- package/lib/properties/{webkitBorderBeforeColor.js → textEmphasisColor.js} +27 -23
- package/lib/properties/top.js +28 -25
- package/lib/properties/webkitTextFillColor.js +26 -22
- package/lib/properties/webkitTextStrokeColor.js +26 -22
- package/lib/properties/width.js +29 -25
- 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 -6638
- 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}$`);
|
|
@@ -96,34 +98,16 @@ const lruCache = new LRUCache({
|
|
|
96
98
|
* Prepares a stringified value.
|
|
97
99
|
*
|
|
98
100
|
* @param {string|number|null|undefined} value - The value to prepare.
|
|
99
|
-
* @param {object} [globalObject=globalThis] - The global object.
|
|
100
101
|
* @returns {string} The prepared value.
|
|
101
102
|
*/
|
|
102
|
-
|
|
103
|
+
function prepareValue(value) {
|
|
103
104
|
// `null` is converted to an empty string.
|
|
104
105
|
// @see https://webidl.spec.whatwg.org/#LegacyNullToEmptyString
|
|
105
106
|
if (value === null) {
|
|
106
107
|
return "";
|
|
107
108
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
case "string":
|
|
111
|
-
return value.trim();
|
|
112
|
-
case "number":
|
|
113
|
-
return value.toString();
|
|
114
|
-
case "undefined":
|
|
115
|
-
return "undefined";
|
|
116
|
-
case "symbol":
|
|
117
|
-
throw new globalObject.TypeError("Can not convert symbol to string.");
|
|
118
|
-
default: {
|
|
119
|
-
const str = value.toString();
|
|
120
|
-
if (typeof str === "string") {
|
|
121
|
-
return str.trim();
|
|
122
|
-
}
|
|
123
|
-
throw new globalObject.TypeError(`Can not convert ${type} to string.`);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
};
|
|
109
|
+
return `${value}`.trim();
|
|
110
|
+
}
|
|
127
111
|
|
|
128
112
|
/**
|
|
129
113
|
* Checks if the value is a global keyword.
|
|
@@ -131,9 +115,9 @@ const prepareValue = (value, globalObject = globalThis) => {
|
|
|
131
115
|
* @param {string} val - The value to check.
|
|
132
116
|
* @returns {boolean} True if the value is a global keyword, false otherwise.
|
|
133
117
|
*/
|
|
134
|
-
|
|
118
|
+
function isGlobalKeyword(val) {
|
|
135
119
|
return GLOBAL_KEYS.has(asciiLowercase(val));
|
|
136
|
-
}
|
|
120
|
+
}
|
|
137
121
|
|
|
138
122
|
/**
|
|
139
123
|
* Checks if the value starts with or contains a CSS var() function.
|
|
@@ -141,9 +125,9 @@ const isGlobalKeyword = (val) => {
|
|
|
141
125
|
* @param {string} val - The value to check.
|
|
142
126
|
* @returns {boolean} True if the value contains a var() function, false otherwise.
|
|
143
127
|
*/
|
|
144
|
-
|
|
128
|
+
function hasVarFunc(val) {
|
|
145
129
|
return varRegEx.test(val) || varContainedRegEx.test(val);
|
|
146
|
-
}
|
|
130
|
+
}
|
|
147
131
|
|
|
148
132
|
/**
|
|
149
133
|
* Checks if the value starts with or contains CSS calc() or math functions.
|
|
@@ -151,28 +135,20 @@ const hasVarFunc = (val) => {
|
|
|
151
135
|
* @param {string} val - The value to check.
|
|
152
136
|
* @returns {boolean} True if the value contains calc() or math functions, false otherwise.
|
|
153
137
|
*/
|
|
154
|
-
|
|
138
|
+
function hasCalcFunc(val) {
|
|
155
139
|
return calcRegEx.test(val) || calcContainedRegEx.test(val);
|
|
156
|
-
}
|
|
140
|
+
}
|
|
157
141
|
|
|
158
142
|
/**
|
|
159
143
|
* Parses a CSS string into an AST.
|
|
160
144
|
*
|
|
161
145
|
* @param {string} val - The CSS string to parse.
|
|
162
146
|
* @param {object} opt - The options for parsing.
|
|
163
|
-
* @
|
|
164
|
-
* @returns {object} The AST or a plain object.
|
|
147
|
+
* @returns {object} The AST.
|
|
165
148
|
*/
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
}
|
|
170
|
-
const ast = cssTree.parse(val, opt);
|
|
171
|
-
if (toObject) {
|
|
172
|
-
return cssTree.toPlainObject(ast);
|
|
173
|
-
}
|
|
174
|
-
return ast;
|
|
175
|
-
};
|
|
149
|
+
function parseCSS(val, opt) {
|
|
150
|
+
return cssTree.parse(prepareValue(val), opt);
|
|
151
|
+
}
|
|
176
152
|
|
|
177
153
|
/**
|
|
178
154
|
* Checks if the value is a valid property value.
|
|
@@ -182,22 +158,14 @@ const parseCSS = (val, opt, toObject = false) => {
|
|
|
182
158
|
* @param {string} val - The property value.
|
|
183
159
|
* @returns {boolean} True if the value is valid, false otherwise.
|
|
184
160
|
*/
|
|
185
|
-
|
|
186
|
-
if (
|
|
187
|
-
|
|
161
|
+
function isValidPropertyValue(prop, val) {
|
|
162
|
+
if (!propertyDefinitions.has(prop)) {
|
|
163
|
+
return false;
|
|
188
164
|
}
|
|
165
|
+
val = prepareValue(val);
|
|
189
166
|
if (val === "") {
|
|
190
167
|
return true;
|
|
191
168
|
}
|
|
192
|
-
// cssTree.lexer does not support deprecated system colors
|
|
193
|
-
// @see https://github.com/w3c/webref/issues/1519#issuecomment-3120290261
|
|
194
|
-
// @see https://github.com/w3c/webref/issues/1647
|
|
195
|
-
if (SYS_COLORS.has(asciiLowercase(val))) {
|
|
196
|
-
if (/^(?:-webkit-)?(?:[a-z][a-z\d]*-)*color$/i.test(prop)) {
|
|
197
|
-
return true;
|
|
198
|
-
}
|
|
199
|
-
return false;
|
|
200
|
-
}
|
|
201
169
|
const cacheKey = `isValidPropertyValue_${prop}_${val}`;
|
|
202
170
|
const cachedValue = lruCache.get(cacheKey);
|
|
203
171
|
if (typeof cachedValue === "boolean") {
|
|
@@ -215,7 +183,7 @@ const isValidPropertyValue = (prop, val) => {
|
|
|
215
183
|
}
|
|
216
184
|
lruCache.set(cacheKey, result);
|
|
217
185
|
return result;
|
|
218
|
-
}
|
|
186
|
+
}
|
|
219
187
|
|
|
220
188
|
/**
|
|
221
189
|
* Resolves CSS math functions.
|
|
@@ -224,10 +192,8 @@ const isValidPropertyValue = (prop, val) => {
|
|
|
224
192
|
* @param {object} [opt={ format: "specifiedValue" }] - The options for resolving.
|
|
225
193
|
* @returns {string|undefined} The resolved value.
|
|
226
194
|
*/
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
val = prepareValue(val);
|
|
230
|
-
}
|
|
195
|
+
function resolveCalc(val, opt = { format: "specifiedValue" }) {
|
|
196
|
+
val = prepareValue(val);
|
|
231
197
|
if (val === "" || hasVarFunc(val) || !hasCalcFunc(val)) {
|
|
232
198
|
return val;
|
|
233
199
|
}
|
|
@@ -236,13 +202,12 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
236
202
|
if (typeof cachedValue === "string") {
|
|
237
203
|
return cachedValue;
|
|
238
204
|
}
|
|
239
|
-
const
|
|
240
|
-
if (!
|
|
205
|
+
const ast = parseCSS(val, { context: "value" });
|
|
206
|
+
if (!ast?.children) {
|
|
241
207
|
return;
|
|
242
208
|
}
|
|
243
|
-
const { children: items } = obj;
|
|
244
209
|
const values = [];
|
|
245
|
-
for (const item of
|
|
210
|
+
for (const item of ast.children) {
|
|
246
211
|
const { type: itemType, name: itemName, value: itemValue } = item;
|
|
247
212
|
if (itemType === AST_TYPES.FUNCTION) {
|
|
248
213
|
const value = cssTree
|
|
@@ -264,7 +229,7 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
264
229
|
const resolvedValue = values.join(" ");
|
|
265
230
|
lruCache.set(cacheKey, resolvedValue);
|
|
266
231
|
return resolvedValue;
|
|
267
|
-
}
|
|
232
|
+
}
|
|
268
233
|
|
|
269
234
|
/**
|
|
270
235
|
* Parses a property value.
|
|
@@ -275,9 +240,12 @@ const resolveCalc = (val, opt = { format: "specifiedValue" }) => {
|
|
|
275
240
|
* @param {object} [opt={}] - The options for parsing.
|
|
276
241
|
* @returns {string|Array<object>|undefined} The parsed value.
|
|
277
242
|
*/
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
243
|
+
function parsePropertyValue(prop, val, opt = {}) {
|
|
244
|
+
if (!propertyDefinitions.has(prop)) {
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
const { caseSensitive } = opt;
|
|
248
|
+
val = prepareValue(val);
|
|
281
249
|
if (val === "" || hasVarFunc(val)) {
|
|
282
250
|
return val;
|
|
283
251
|
} else if (hasCalcFunc(val)) {
|
|
@@ -293,41 +261,18 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
293
261
|
const cachedValue = lruCache.get(cacheKey);
|
|
294
262
|
if (cachedValue === false) {
|
|
295
263
|
return;
|
|
296
|
-
} else if (
|
|
297
|
-
if (Array.isArray(cachedValue)) {
|
|
298
|
-
return cachedValue;
|
|
299
|
-
}
|
|
300
|
-
} else if (typeof cachedValue === "string") {
|
|
264
|
+
} else if (cachedValue !== undefined) {
|
|
301
265
|
return cachedValue;
|
|
302
266
|
}
|
|
303
267
|
let parsedValue;
|
|
304
268
|
const lowerCasedValue = asciiLowercase(val);
|
|
305
269
|
if (GLOBAL_KEYS.has(lowerCasedValue)) {
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
name: lowerCasedValue
|
|
311
|
-
}
|
|
312
|
-
];
|
|
313
|
-
} else {
|
|
314
|
-
parsedValue = lowerCasedValue;
|
|
315
|
-
}
|
|
316
|
-
} else if (SYS_COLORS.has(lowerCasedValue)) {
|
|
317
|
-
if (/^(?:(?:-webkit-)?(?:[a-z][a-z\d]*-)*color|border)$/i.test(prop)) {
|
|
318
|
-
if (inArray) {
|
|
319
|
-
parsedValue = [
|
|
320
|
-
{
|
|
321
|
-
type: AST_TYPES.IDENTIFIER,
|
|
322
|
-
name: lowerCasedValue
|
|
323
|
-
}
|
|
324
|
-
];
|
|
325
|
-
} else {
|
|
326
|
-
parsedValue = lowerCasedValue;
|
|
270
|
+
parsedValue = [
|
|
271
|
+
{
|
|
272
|
+
type: AST_TYPES.GLOBAL_KEYWORD,
|
|
273
|
+
name: lowerCasedValue
|
|
327
274
|
}
|
|
328
|
-
|
|
329
|
-
parsedValue = false;
|
|
330
|
-
}
|
|
275
|
+
];
|
|
331
276
|
} else {
|
|
332
277
|
try {
|
|
333
278
|
const ast = parseCSS(val, {
|
|
@@ -336,9 +281,9 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
336
281
|
const { error, matched } = cssTree.lexer.matchProperty(prop, ast);
|
|
337
282
|
if (error || !matched) {
|
|
338
283
|
parsedValue = false;
|
|
339
|
-
} else
|
|
340
|
-
const
|
|
341
|
-
const
|
|
284
|
+
} else {
|
|
285
|
+
const items = ast.children;
|
|
286
|
+
const itemCount = items.size;
|
|
342
287
|
const values = [];
|
|
343
288
|
for (const item of items) {
|
|
344
289
|
const { children, name, type, value, unit } = item;
|
|
@@ -356,12 +301,12 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
356
301
|
.generate(item)
|
|
357
302
|
.replace(/\)(?!\)|\s|,)/g, ") ")
|
|
358
303
|
.trim();
|
|
359
|
-
const raw =
|
|
304
|
+
const raw = itemCount === 1 ? val : css;
|
|
360
305
|
// Remove "${name}(" from the start and ")" from the end
|
|
361
306
|
const itemValue = raw.slice(name.length + 1, -1).trim();
|
|
362
307
|
if (name === "calc") {
|
|
363
|
-
if (children.
|
|
364
|
-
const
|
|
308
|
+
if (children.size === 1) {
|
|
309
|
+
const child = children.first;
|
|
365
310
|
if (child.type === AST_TYPES.NUMBER) {
|
|
366
311
|
values.push({
|
|
367
312
|
type: AST_TYPES.CALC,
|
|
@@ -415,8 +360,6 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
415
360
|
}
|
|
416
361
|
}
|
|
417
362
|
parsedValue = values;
|
|
418
|
-
} else {
|
|
419
|
-
parsedValue = val;
|
|
420
363
|
}
|
|
421
364
|
} catch {
|
|
422
365
|
parsedValue = false;
|
|
@@ -427,18 +370,18 @@ const parsePropertyValue = (prop, val, opt = {}) => {
|
|
|
427
370
|
return;
|
|
428
371
|
}
|
|
429
372
|
return parsedValue;
|
|
430
|
-
}
|
|
373
|
+
}
|
|
431
374
|
|
|
432
375
|
/**
|
|
433
376
|
* Parses a numeric value (number, dimension, percentage).
|
|
434
|
-
* Helper function for
|
|
377
|
+
* Helper function for serializeNumber, serializeLength, etc.
|
|
435
378
|
*
|
|
436
379
|
* @param {Array<object>} val - The AST value.
|
|
437
380
|
* @param {object} [opt={}] - The options for parsing.
|
|
438
381
|
* @param {Function} validateType - Function to validate the node type.
|
|
439
382
|
* @returns {object|undefined} The parsed result containing num and unit, or undefined.
|
|
440
383
|
*/
|
|
441
|
-
|
|
384
|
+
function parseNumericValue(val, opt, validateType) {
|
|
442
385
|
const [item] = val;
|
|
443
386
|
const { type, value, unit } = item ?? {};
|
|
444
387
|
if (!validateType(type, value, unit)) {
|
|
@@ -462,31 +405,31 @@ const parseNumericValue = (val, opt, validateType) => {
|
|
|
462
405
|
unit: unit ? asciiLowercase(unit) : null,
|
|
463
406
|
type
|
|
464
407
|
};
|
|
465
|
-
}
|
|
408
|
+
}
|
|
466
409
|
|
|
467
410
|
/**
|
|
468
|
-
*
|
|
411
|
+
* Serializes a <number> value.
|
|
469
412
|
*
|
|
470
413
|
* @param {Array<object>} val - The AST value.
|
|
471
414
|
* @param {object} [opt={}] - The options for parsing.
|
|
472
415
|
* @returns {string|undefined} The parsed number.
|
|
473
416
|
*/
|
|
474
|
-
|
|
417
|
+
function serializeNumber(val, opt = {}) {
|
|
475
418
|
const res = parseNumericValue(val, opt, (type) => type === AST_TYPES.NUMBER);
|
|
476
419
|
if (!res) {
|
|
477
420
|
return;
|
|
478
421
|
}
|
|
479
422
|
return `${res.num}`;
|
|
480
|
-
}
|
|
423
|
+
}
|
|
481
424
|
|
|
482
425
|
/**
|
|
483
|
-
*
|
|
426
|
+
* Serializes an <angle> value.
|
|
484
427
|
*
|
|
485
428
|
* @param {Array<object>} val - The AST value.
|
|
486
429
|
* @param {object} [opt={}] - The options for parsing.
|
|
487
|
-
* @returns {string|undefined} The
|
|
430
|
+
* @returns {string|undefined} The serialized angle.
|
|
488
431
|
*/
|
|
489
|
-
|
|
432
|
+
function serializeAngle(val, opt = {}) {
|
|
490
433
|
const res = parseNumericValue(
|
|
491
434
|
val,
|
|
492
435
|
opt,
|
|
@@ -496,67 +439,85 @@ const parseLength = (val, opt = {}) => {
|
|
|
496
439
|
return;
|
|
497
440
|
}
|
|
498
441
|
const { num, unit } = res;
|
|
499
|
-
if (
|
|
500
|
-
|
|
501
|
-
|
|
442
|
+
if (unit) {
|
|
443
|
+
if (!/^(?:deg|g?rad|turn)$/i.test(unit)) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
502
446
|
return `${num}${unit}`;
|
|
447
|
+
} else if (num === 0) {
|
|
448
|
+
return `${num}deg`;
|
|
503
449
|
}
|
|
504
|
-
}
|
|
450
|
+
}
|
|
505
451
|
|
|
506
452
|
/**
|
|
507
|
-
*
|
|
453
|
+
* Serializes a <length> value.
|
|
508
454
|
*
|
|
509
455
|
* @param {Array<object>} val - The AST value.
|
|
510
456
|
* @param {object} [opt={}] - The options for parsing.
|
|
511
|
-
* @returns {string|undefined} The
|
|
457
|
+
* @returns {string|undefined} The serialized length.
|
|
512
458
|
*/
|
|
513
|
-
|
|
459
|
+
function serializeLength(val, opt = {}) {
|
|
514
460
|
const res = parseNumericValue(
|
|
515
461
|
val,
|
|
516
462
|
opt,
|
|
517
|
-
(type, value) => type === AST_TYPES.
|
|
463
|
+
(type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
|
|
518
464
|
);
|
|
519
465
|
if (!res) {
|
|
520
466
|
return;
|
|
521
467
|
}
|
|
522
|
-
const { num } = res;
|
|
523
|
-
|
|
524
|
-
}
|
|
468
|
+
const { num, unit } = res;
|
|
469
|
+
if (num === 0 && !unit) {
|
|
470
|
+
return `${num}px`;
|
|
471
|
+
} else if (unit) {
|
|
472
|
+
return `${num}${unit}`;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
525
475
|
|
|
526
476
|
/**
|
|
527
|
-
*
|
|
477
|
+
* Serializes a <dimension> value, e.g. <frequency>, <time> and <resolution>.
|
|
528
478
|
*
|
|
529
479
|
* @param {Array<object>} val - The AST value.
|
|
530
480
|
* @param {object} [opt={}] - The options for parsing.
|
|
531
|
-
* @returns {string|undefined} The
|
|
481
|
+
* @returns {string|undefined} The serialized dimension.
|
|
532
482
|
*/
|
|
533
|
-
|
|
534
|
-
const res = parseNumericValue(
|
|
535
|
-
val,
|
|
536
|
-
opt,
|
|
537
|
-
(type, value) => type === AST_TYPES.DIMENSION || (type === AST_TYPES.NUMBER && value === "0")
|
|
538
|
-
);
|
|
483
|
+
function serializeDimension(val, opt = {}) {
|
|
484
|
+
const res = parseNumericValue(val, opt, (type) => type === AST_TYPES.DIMENSION);
|
|
539
485
|
if (!res) {
|
|
540
486
|
return;
|
|
541
487
|
}
|
|
542
488
|
const { num, unit } = res;
|
|
543
489
|
if (unit) {
|
|
544
|
-
if (!/^(?:deg|g?rad|turn)$/i.test(unit)) {
|
|
545
|
-
return;
|
|
546
|
-
}
|
|
547
490
|
return `${num}${unit}`;
|
|
548
|
-
} else if (num === 0) {
|
|
549
|
-
return `${num}deg`;
|
|
550
491
|
}
|
|
551
|
-
}
|
|
492
|
+
}
|
|
552
493
|
|
|
553
494
|
/**
|
|
554
|
-
*
|
|
495
|
+
* Serializes a <percentage> value.
|
|
555
496
|
*
|
|
556
497
|
* @param {Array<object>} val - The AST value.
|
|
557
|
-
* @
|
|
498
|
+
* @param {object} [opt={}] - The options for parsing.
|
|
499
|
+
* @returns {string|undefined} The serialized percentage.
|
|
558
500
|
*/
|
|
559
|
-
|
|
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) {
|
|
560
521
|
const [item] = val;
|
|
561
522
|
const { type, value } = item ?? {};
|
|
562
523
|
if (type !== AST_TYPES.URL) {
|
|
@@ -564,15 +525,15 @@ const parseUrl = (val) => {
|
|
|
564
525
|
}
|
|
565
526
|
const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
|
|
566
527
|
return `url("${str}")`;
|
|
567
|
-
}
|
|
528
|
+
}
|
|
568
529
|
|
|
569
530
|
/**
|
|
570
|
-
*
|
|
531
|
+
* Serializes a <string> value.
|
|
571
532
|
*
|
|
572
533
|
* @param {Array<object>} val - The AST value.
|
|
573
|
-
* @returns {string|undefined} The
|
|
534
|
+
* @returns {string|undefined} The serialized string.
|
|
574
535
|
*/
|
|
575
|
-
|
|
536
|
+
function serializeString(val) {
|
|
576
537
|
const [item] = val;
|
|
577
538
|
const { type, value } = item ?? {};
|
|
578
539
|
if (type !== AST_TYPES.STRING) {
|
|
@@ -580,15 +541,15 @@ const parseString = (val) => {
|
|
|
580
541
|
}
|
|
581
542
|
const str = value.replace(/\\\\/g, "\\").replaceAll('"', '\\"');
|
|
582
543
|
return `"${str}"`;
|
|
583
|
-
}
|
|
544
|
+
}
|
|
584
545
|
|
|
585
546
|
/**
|
|
586
|
-
*
|
|
547
|
+
* Serializes a <color> value.
|
|
587
548
|
*
|
|
588
549
|
* @param {Array<object>} val - The AST value.
|
|
589
|
-
* @returns {string|undefined} The
|
|
550
|
+
* @returns {string|undefined} The serialized color.
|
|
590
551
|
*/
|
|
591
|
-
|
|
552
|
+
function serializeColor(val) {
|
|
592
553
|
const [item] = val;
|
|
593
554
|
const { name, type, value } = item ?? {};
|
|
594
555
|
switch (type) {
|
|
@@ -624,15 +585,15 @@ const parseColor = (val) => {
|
|
|
624
585
|
}
|
|
625
586
|
default:
|
|
626
587
|
}
|
|
627
|
-
}
|
|
588
|
+
}
|
|
628
589
|
|
|
629
590
|
/**
|
|
630
|
-
*
|
|
591
|
+
* Serializes a <gradient> value.
|
|
631
592
|
*
|
|
632
593
|
* @param {Array<object>} val - The AST value.
|
|
633
|
-
* @returns {string|undefined} The
|
|
594
|
+
* @returns {string|undefined} The serialized gradient.
|
|
634
595
|
*/
|
|
635
|
-
|
|
596
|
+
function serializeGradient(val) {
|
|
636
597
|
const [item] = val;
|
|
637
598
|
const { name, type, value } = item ?? {};
|
|
638
599
|
if (type !== AST_TYPES.FUNCTION) {
|
|
@@ -644,7 +605,7 @@ const parseGradient = (val) => {
|
|
|
644
605
|
if (res) {
|
|
645
606
|
return res;
|
|
646
607
|
}
|
|
647
|
-
}
|
|
608
|
+
}
|
|
648
609
|
|
|
649
610
|
/**
|
|
650
611
|
* Resolves a keyword value.
|
|
@@ -653,7 +614,7 @@ const parseGradient = (val) => {
|
|
|
653
614
|
* @param {object} [opt={}] - The options for parsing.
|
|
654
615
|
* @returns {string|undefined} The resolved keyword or undefined.
|
|
655
616
|
*/
|
|
656
|
-
|
|
617
|
+
function resolveKeywordValue(value, opt = {}) {
|
|
657
618
|
const [{ name, type }] = value;
|
|
658
619
|
const { length } = opt;
|
|
659
620
|
switch (type) {
|
|
@@ -668,7 +629,7 @@ const resolveKeywordValue = (value, opt = {}) => {
|
|
|
668
629
|
}
|
|
669
630
|
default:
|
|
670
631
|
}
|
|
671
|
-
}
|
|
632
|
+
}
|
|
672
633
|
|
|
673
634
|
/**
|
|
674
635
|
* Resolves a function value.
|
|
@@ -677,7 +638,7 @@ const resolveKeywordValue = (value, opt = {}) => {
|
|
|
677
638
|
* @param {object} [opt={}] - The options for parsing.
|
|
678
639
|
* @returns {string|undefined} The resolved function or undefined.
|
|
679
640
|
*/
|
|
680
|
-
|
|
641
|
+
function resolveFunctionValue(value, opt = {}) {
|
|
681
642
|
const [{ name, type, value: itemValue }] = value;
|
|
682
643
|
const { length } = opt;
|
|
683
644
|
switch (type) {
|
|
@@ -695,16 +656,16 @@ const resolveFunctionValue = (value, opt = {}) => {
|
|
|
695
656
|
}
|
|
696
657
|
default:
|
|
697
658
|
}
|
|
698
|
-
}
|
|
659
|
+
}
|
|
699
660
|
|
|
700
661
|
/**
|
|
701
|
-
* Resolves a
|
|
662
|
+
* Resolves a numeric value.
|
|
702
663
|
*
|
|
703
|
-
* @param {Array<object>} value - The AST node array containing the value.
|
|
664
|
+
* @param {Array<object>} value - The AST node array containing the numeric value.
|
|
704
665
|
* @param {object} [opt={}] - The options for parsing.
|
|
705
666
|
* @returns {string|undefined} The resolved length/percentage/number or undefined.
|
|
706
667
|
*/
|
|
707
|
-
|
|
668
|
+
function resolveNumericValue(value, opt = {}) {
|
|
708
669
|
const [{ name, type: itemType, value: itemValue }] = value;
|
|
709
670
|
const { length, type } = opt;
|
|
710
671
|
switch (itemType) {
|
|
@@ -713,9 +674,11 @@ const resolveNumericValue = (value, opt = {}) => {
|
|
|
713
674
|
}
|
|
714
675
|
case AST_TYPES.DIMENSION: {
|
|
715
676
|
if (type === "angle") {
|
|
716
|
-
return
|
|
677
|
+
return serializeAngle(value, opt);
|
|
678
|
+
} else if (type === "length") {
|
|
679
|
+
return serializeLength(value, opt);
|
|
717
680
|
}
|
|
718
|
-
return
|
|
681
|
+
return serializeDimension(value, opt);
|
|
719
682
|
}
|
|
720
683
|
case AST_TYPES.GLOBAL_KEYWORD: {
|
|
721
684
|
if (length > 1) {
|
|
@@ -729,25 +692,25 @@ const resolveNumericValue = (value, opt = {}) => {
|
|
|
729
692
|
case AST_TYPES.NUMBER: {
|
|
730
693
|
switch (type) {
|
|
731
694
|
case "angle": {
|
|
732
|
-
return
|
|
695
|
+
return serializeAngle(value, opt);
|
|
733
696
|
}
|
|
734
697
|
case "length": {
|
|
735
|
-
return
|
|
698
|
+
return serializeLength(value, opt);
|
|
736
699
|
}
|
|
737
700
|
case "percentage": {
|
|
738
|
-
return
|
|
701
|
+
return serializePercentage(value, opt);
|
|
739
702
|
}
|
|
740
703
|
default: {
|
|
741
|
-
return
|
|
704
|
+
return serializeNumber(value, opt);
|
|
742
705
|
}
|
|
743
706
|
}
|
|
744
707
|
}
|
|
745
708
|
case AST_TYPES.PERCENTAGE: {
|
|
746
|
-
return
|
|
709
|
+
return serializePercentage(value, opt);
|
|
747
710
|
}
|
|
748
711
|
default:
|
|
749
712
|
}
|
|
750
|
-
}
|
|
713
|
+
}
|
|
751
714
|
|
|
752
715
|
/**
|
|
753
716
|
* Resolves a color value.
|
|
@@ -756,7 +719,7 @@ const resolveNumericValue = (value, opt = {}) => {
|
|
|
756
719
|
* @param {object} [opt={}] - The options for parsing.
|
|
757
720
|
* @returns {string|undefined} The resolved color or undefined.
|
|
758
721
|
*/
|
|
759
|
-
|
|
722
|
+
function resolveColorValue(value, opt = {}) {
|
|
760
723
|
const [{ name, type }] = value;
|
|
761
724
|
const { length } = opt;
|
|
762
725
|
switch (type) {
|
|
@@ -767,19 +730,19 @@ const resolveColorValue = (value, opt = {}) => {
|
|
|
767
730
|
return name;
|
|
768
731
|
}
|
|
769
732
|
default: {
|
|
770
|
-
return
|
|
733
|
+
return serializeColor(value, opt);
|
|
771
734
|
}
|
|
772
735
|
}
|
|
773
|
-
}
|
|
736
|
+
}
|
|
774
737
|
|
|
775
738
|
/**
|
|
776
|
-
* Resolves
|
|
739
|
+
* Resolves an image value.
|
|
777
740
|
*
|
|
778
|
-
* @param {Array<object>} value - The AST node array containing the
|
|
741
|
+
* @param {Array<object>} value - The AST node array containing the image value.
|
|
779
742
|
* @param {object} [opt={}] - The options for parsing.
|
|
780
743
|
* @returns {string|undefined} The resolved gradient/url or undefined.
|
|
781
744
|
*/
|
|
782
|
-
|
|
745
|
+
function resolveImageValue(value, opt = {}) {
|
|
783
746
|
const [{ name, type }] = value;
|
|
784
747
|
const { length } = opt;
|
|
785
748
|
switch (type) {
|
|
@@ -793,13 +756,13 @@ const resolveGradientUrlValue = (value, opt = {}) => {
|
|
|
793
756
|
return name;
|
|
794
757
|
}
|
|
795
758
|
case AST_TYPES.URL: {
|
|
796
|
-
return
|
|
759
|
+
return serializeURL(value, opt);
|
|
797
760
|
}
|
|
798
761
|
default: {
|
|
799
|
-
return
|
|
762
|
+
return serializeGradient(value, opt);
|
|
800
763
|
}
|
|
801
764
|
}
|
|
802
|
-
}
|
|
765
|
+
}
|
|
803
766
|
|
|
804
767
|
/**
|
|
805
768
|
* Resolves a border shorthand value.
|
|
@@ -809,7 +772,7 @@ const resolveGradientUrlValue = (value, opt = {}) => {
|
|
|
809
772
|
* @param {Map} parsedValues - The Map of parsed values.
|
|
810
773
|
* @returns {Array|string|undefined} - The resolved [prop, value] pair, keyword or undefined.
|
|
811
774
|
*/
|
|
812
|
-
|
|
775
|
+
function resolveBorderShorthandValue(value, subProps, parsedValues) {
|
|
813
776
|
const [{ isNumber, name, type, value: itemValue }] = value;
|
|
814
777
|
const { color: colorProp, style: styleProp, width: widthProp } = subProps;
|
|
815
778
|
switch (type) {
|
|
@@ -824,7 +787,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
|
|
|
824
787
|
if (parsedValues.has(widthProp)) {
|
|
825
788
|
return;
|
|
826
789
|
}
|
|
827
|
-
const parsedValue =
|
|
790
|
+
const parsedValue = serializeLength(value, { min: 0 });
|
|
828
791
|
if (!parsedValue) {
|
|
829
792
|
return;
|
|
830
793
|
}
|
|
@@ -835,7 +798,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
|
|
|
835
798
|
if (parsedValues.has(colorProp)) {
|
|
836
799
|
return;
|
|
837
800
|
}
|
|
838
|
-
const parsedValue =
|
|
801
|
+
const parsedValue = serializeColor(value);
|
|
839
802
|
if (!parsedValue) {
|
|
840
803
|
return;
|
|
841
804
|
}
|
|
@@ -865,7 +828,7 @@ const resolveBorderShorthandValue = (value, subProps, parsedValues) => {
|
|
|
865
828
|
}
|
|
866
829
|
default:
|
|
867
830
|
}
|
|
868
|
-
}
|
|
831
|
+
}
|
|
869
832
|
|
|
870
833
|
module.exports = {
|
|
871
834
|
AST_TYPES,
|
|
@@ -873,23 +836,24 @@ module.exports = {
|
|
|
873
836
|
hasVarFunc,
|
|
874
837
|
isGlobalKeyword,
|
|
875
838
|
isValidPropertyValue,
|
|
876
|
-
parseAngle,
|
|
877
839
|
parseCSS,
|
|
878
|
-
parseColor,
|
|
879
|
-
parseGradient,
|
|
880
|
-
parseLength,
|
|
881
|
-
parseNumber,
|
|
882
|
-
parsePercentage,
|
|
883
840
|
parsePropertyValue,
|
|
884
|
-
parseString,
|
|
885
|
-
parseUrl,
|
|
886
841
|
prepareValue,
|
|
887
842
|
resolveBorderShorthandValue,
|
|
888
843
|
resolveCalc,
|
|
889
844
|
resolveColorValue,
|
|
890
845
|
resolveFunctionValue,
|
|
891
|
-
|
|
846
|
+
resolveImageValue,
|
|
892
847
|
resolveKeywordValue,
|
|
893
848
|
resolveNumericValue,
|
|
849
|
+
serializeAngle,
|
|
850
|
+
serializeColor,
|
|
851
|
+
serializeDimension,
|
|
852
|
+
serializeGradient,
|
|
853
|
+
serializeLength,
|
|
854
|
+
serializeNumber,
|
|
855
|
+
serializePercentage,
|
|
856
|
+
serializeString,
|
|
857
|
+
serializeURL,
|
|
894
858
|
splitValue
|
|
895
859
|
};
|