parseWsc.js
1.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
'use strict';
const { list } = require('postcss');
const { isWidth, isStyle, isColor } = require('./validateWsc.js');
const none = /^\s*(none|medium)(\s+none(\s+(none|currentcolor))?)?\s*$/i;
/* Approximate https://drafts.csswg.org/css-values-4/#typedef-dashed-ident */
// eslint-disable-next-line no-control-regex
const varRE = /--(\w|-|[^\x00-\x7F])+/g;
/** @type {(v: string) => string} */
const toLower = (v) => {
let match;
let lastIndex = 0;
let result = '';
varRE.lastIndex = 0;
while ((match = varRE.exec(v)) !== null) {
if (match.index > lastIndex) {
result += v.substring(lastIndex, match.index).toLowerCase();
}
result += match[0];
lastIndex = match.index + match[0].length;
}
if (lastIndex < v.length) {
result += v.substring(lastIndex).toLowerCase();
}
if (result === '') {
return v;
}
return result;
};
/**
* @param {string} value
* @return {[string, string, string]}
*/
module.exports = function parseWsc(value) {
if (none.test(value)) {
return ['medium', 'none', 'currentcolor'];
}
let width, style, color;
const values = list.space(value);
if (
values.length > 1 &&
isStyle(values[1]) &&
values[0].toLowerCase() === 'none'
) {
values.unshift();
width = '0';
}
/** @type {string[]} */
const unknown = [];
values.forEach((v) => {
if (isStyle(v)) {
style = toLower(v);
} else if (isWidth(v)) {
width = toLower(v);
} else if (isColor(v)) {
color = toLower(v);
} else {
unknown.push(v);
}
});
if (unknown.length) {
if (!width && style && color) {
width = unknown.pop();
}
if (width && !style && color) {
style = unknown.pop();
}
if (width && style && !color) {
color = unknown.pop();
}
}
return /** @type {[string, string, string]} */ ([width, style, color]);
};