@iconify/tools 3.0.0-beta.1 → 3.0.0-beta.2
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/css/parser/export.cjs +1 -10
- package/lib/css/parser/export.mjs +1 -10
- package/lib/css/parser/text.cjs +6 -25
- package/lib/css/parser/text.mjs +6 -25
- package/lib/css/parser/types.d.ts +2 -3
- package/lib/svg/cleanup/root-style.cjs +18 -7
- package/lib/svg/cleanup/root-style.d.ts +5 -1
- package/lib/svg/cleanup/root-style.mjs +18 -7
- package/lib/svg/cleanup/svgo-style.cjs +3 -0
- package/lib/svg/cleanup/svgo-style.mjs +3 -0
- package/lib/svg/parse-style.cjs +144 -41
- package/lib/svg/parse-style.d.ts +15 -2
- package/lib/svg/parse-style.mjs +144 -41
- package/package.json +1 -1
|
@@ -21,7 +21,7 @@ function parseToken(token, compact, depth) {
|
|
|
21
21
|
return (compact ? "" : tab.repeat(depth)) + token.prop + (compact ? ":" : ": ") + token.value + ";" + (compact ? "" : nl);
|
|
22
22
|
}
|
|
23
23
|
case "at-rule": {
|
|
24
|
-
content =
|
|
24
|
+
content = `@${token.rule} ${token.value}`.trim();
|
|
25
25
|
break;
|
|
26
26
|
}
|
|
27
27
|
case "selector": {
|
|
@@ -33,14 +33,5 @@ function parseToken(token, compact, depth) {
|
|
|
33
33
|
});
|
|
34
34
|
return (compact ? "" : tab.repeat(depth)) + content + (compact ? "{" : " {" + nl) + children.join("") + (compact ? "}" : tab.repeat(depth) + "}" + nl);
|
|
35
35
|
}
|
|
36
|
-
function joinAtValues(values, compact) {
|
|
37
|
-
return values.map((item) => {
|
|
38
|
-
const value = typeof item === "string" ? item : joinAtValues(item, compact);
|
|
39
|
-
if (value.slice(0, 1) === "(" || value.slice(-1) === ")") {
|
|
40
|
-
return value;
|
|
41
|
-
}
|
|
42
|
-
return "(" + value + ")";
|
|
43
|
-
}).join(compact ? "," : ", ");
|
|
44
|
-
}
|
|
45
36
|
|
|
46
37
|
exports.tokensToString = tokensToString;
|
|
@@ -19,7 +19,7 @@ function parseToken(token, compact, depth) {
|
|
|
19
19
|
return (compact ? "" : tab.repeat(depth)) + token.prop + (compact ? ":" : ": ") + token.value + ";" + (compact ? "" : nl);
|
|
20
20
|
}
|
|
21
21
|
case "at-rule": {
|
|
22
|
-
content =
|
|
22
|
+
content = `@${token.rule} ${token.value}`.trim();
|
|
23
23
|
break;
|
|
24
24
|
}
|
|
25
25
|
case "selector": {
|
|
@@ -31,14 +31,5 @@ function parseToken(token, compact, depth) {
|
|
|
31
31
|
});
|
|
32
32
|
return (compact ? "" : tab.repeat(depth)) + content + (compact ? "{" : " {" + nl) + children.join("") + (compact ? "}" : tab.repeat(depth) + "}" + nl);
|
|
33
33
|
}
|
|
34
|
-
function joinAtValues(values, compact) {
|
|
35
|
-
return values.map((item) => {
|
|
36
|
-
const value = typeof item === "string" ? item : joinAtValues(item, compact);
|
|
37
|
-
if (value.slice(0, 1) === "(" || value.slice(-1) === ")") {
|
|
38
|
-
return value;
|
|
39
|
-
}
|
|
40
|
-
return "(" + value + ")";
|
|
41
|
-
}).join(compact ? "," : ", ");
|
|
42
|
-
}
|
|
43
34
|
|
|
44
35
|
export { tokensToString };
|
package/lib/css/parser/text.cjs
CHANGED
|
@@ -81,7 +81,6 @@ function textTokensToRule(tokens) {
|
|
|
81
81
|
});
|
|
82
82
|
return result.value.length ? result : null;
|
|
83
83
|
}
|
|
84
|
-
const nestableAtRules = ["media", "supports"];
|
|
85
84
|
function textTokensToSelector(tokens) {
|
|
86
85
|
const selectors = getSelectors(tokens);
|
|
87
86
|
const code = mergeTextTokens(tokens);
|
|
@@ -89,33 +88,15 @@ function textTokensToSelector(tokens) {
|
|
|
89
88
|
if (!selectors.length) {
|
|
90
89
|
return null;
|
|
91
90
|
}
|
|
92
|
-
if (
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
if (nestableAtRules.indexOf(atRule) !== -1) {
|
|
97
|
-
atValues.forEach((item, index2) => {
|
|
98
|
-
if (typeof item !== "string" || item.charAt(0) !== "(" || item.charAt(item.length - 1) !== ")") {
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
const list = item.slice(1, -1).split(/\)\s?and\s?\(/i).map((item2) => item2.trim());
|
|
102
|
-
let match = true;
|
|
103
|
-
list.forEach((item2) => {
|
|
104
|
-
if (item2.indexOf("(") !== -1 || item2.indexOf(")") !== -1) {
|
|
105
|
-
match = false;
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
if (match) {
|
|
109
|
-
atValues[index2] = list;
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
}
|
|
91
|
+
if (code.charAt(0) === "@") {
|
|
92
|
+
const parts = code.split(/\s+/);
|
|
93
|
+
const rule = parts.shift().slice(1);
|
|
94
|
+
const value = parts.join(" ").trim();
|
|
113
95
|
return {
|
|
114
96
|
type: "at-rule",
|
|
115
|
-
code,
|
|
116
97
|
index,
|
|
117
|
-
|
|
118
|
-
|
|
98
|
+
rule,
|
|
99
|
+
value
|
|
119
100
|
};
|
|
120
101
|
} else {
|
|
121
102
|
return {
|
package/lib/css/parser/text.mjs
CHANGED
|
@@ -79,7 +79,6 @@ function textTokensToRule(tokens) {
|
|
|
79
79
|
});
|
|
80
80
|
return result.value.length ? result : null;
|
|
81
81
|
}
|
|
82
|
-
const nestableAtRules = ["media", "supports"];
|
|
83
82
|
function textTokensToSelector(tokens) {
|
|
84
83
|
const selectors = getSelectors(tokens);
|
|
85
84
|
const code = mergeTextTokens(tokens);
|
|
@@ -87,33 +86,15 @@ function textTokensToSelector(tokens) {
|
|
|
87
86
|
if (!selectors.length) {
|
|
88
87
|
return null;
|
|
89
88
|
}
|
|
90
|
-
if (
|
|
91
|
-
const
|
|
92
|
-
|
|
93
|
-
const
|
|
94
|
-
if (nestableAtRules.indexOf(atRule) !== -1) {
|
|
95
|
-
atValues.forEach((item, index2) => {
|
|
96
|
-
if (typeof item !== "string" || item.charAt(0) !== "(" || item.charAt(item.length - 1) !== ")") {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
const list = item.slice(1, -1).split(/\)\s?and\s?\(/i).map((item2) => item2.trim());
|
|
100
|
-
let match = true;
|
|
101
|
-
list.forEach((item2) => {
|
|
102
|
-
if (item2.indexOf("(") !== -1 || item2.indexOf(")") !== -1) {
|
|
103
|
-
match = false;
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
if (match) {
|
|
107
|
-
atValues[index2] = list;
|
|
108
|
-
}
|
|
109
|
-
});
|
|
110
|
-
}
|
|
89
|
+
if (code.charAt(0) === "@") {
|
|
90
|
+
const parts = code.split(/\s+/);
|
|
91
|
+
const rule = parts.shift().slice(1);
|
|
92
|
+
const value = parts.join(" ").trim();
|
|
111
93
|
return {
|
|
112
94
|
type: "at-rule",
|
|
113
|
-
code,
|
|
114
95
|
index,
|
|
115
|
-
|
|
116
|
-
|
|
96
|
+
rule,
|
|
97
|
+
value
|
|
117
98
|
};
|
|
118
99
|
} else {
|
|
119
100
|
return {
|
|
@@ -11,16 +11,27 @@ require('../../css/parser/tree.cjs');
|
|
|
11
11
|
require('../parse.cjs');
|
|
12
12
|
|
|
13
13
|
function cleanupRootStyle(svg) {
|
|
14
|
+
const result = {};
|
|
14
15
|
svg_parseStyle.parseSVGStyleSync(svg, (item) => {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
switch (item.type) {
|
|
17
|
+
case "inline":
|
|
18
|
+
return item.value;
|
|
19
|
+
case "global":
|
|
20
|
+
return item.value;
|
|
21
|
+
case "at-rule":
|
|
22
|
+
if (item.prop === "supports") {
|
|
23
|
+
return item.value;
|
|
24
|
+
}
|
|
25
|
+
(result.removedAtRules || (result.removedAtRules = /* @__PURE__ */ new Set())).add(item.prop);
|
|
26
|
+
return;
|
|
27
|
+
case "keyframes":
|
|
28
|
+
(result.animations || (result.animations = /* @__PURE__ */ new Set())).add(
|
|
29
|
+
item.value
|
|
30
|
+
);
|
|
31
|
+
return item.value;
|
|
21
32
|
}
|
|
22
|
-
return item.value;
|
|
23
33
|
});
|
|
34
|
+
return result;
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
exports.cleanupRootStyle = cleanupRootStyle;
|
|
@@ -2,11 +2,15 @@ import { SVG } from '../index.js';
|
|
|
2
2
|
import '@iconify/types';
|
|
3
3
|
import '@iconify/utils/lib/customisations/defaults';
|
|
4
4
|
|
|
5
|
+
interface CleanupRootStyleResult {
|
|
6
|
+
animations?: Set<string>;
|
|
7
|
+
removedAtRules?: Set<string>;
|
|
8
|
+
}
|
|
5
9
|
/**
|
|
6
10
|
* Clean up root style
|
|
7
11
|
*
|
|
8
12
|
* This function removes all at-rule tokens, such as `@font-face`, `@media`
|
|
9
13
|
*/
|
|
10
|
-
declare function cleanupRootStyle(svg: SVG):
|
|
14
|
+
declare function cleanupRootStyle(svg: SVG): CleanupRootStyleResult;
|
|
11
15
|
|
|
12
16
|
export { cleanupRootStyle };
|
|
@@ -9,16 +9,27 @@ import '../../css/parser/tree.mjs';
|
|
|
9
9
|
import '../parse.mjs';
|
|
10
10
|
|
|
11
11
|
function cleanupRootStyle(svg) {
|
|
12
|
+
const result = {};
|
|
12
13
|
parseSVGStyleSync(svg, (item) => {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
switch (item.type) {
|
|
15
|
+
case "inline":
|
|
16
|
+
return item.value;
|
|
17
|
+
case "global":
|
|
18
|
+
return item.value;
|
|
19
|
+
case "at-rule":
|
|
20
|
+
if (item.prop === "supports") {
|
|
21
|
+
return item.value;
|
|
22
|
+
}
|
|
23
|
+
(result.removedAtRules || (result.removedAtRules = /* @__PURE__ */ new Set())).add(item.prop);
|
|
24
|
+
return;
|
|
25
|
+
case "keyframes":
|
|
26
|
+
(result.animations || (result.animations = /* @__PURE__ */ new Set())).add(
|
|
27
|
+
item.value
|
|
28
|
+
);
|
|
29
|
+
return item.value;
|
|
19
30
|
}
|
|
20
|
-
return item.value;
|
|
21
31
|
});
|
|
32
|
+
return result;
|
|
22
33
|
}
|
|
23
34
|
|
|
24
35
|
export { cleanupRootStyle };
|
|
@@ -18,6 +18,9 @@ require('@iconify/utils/lib/svg/id');
|
|
|
18
18
|
function convertStyleToAttrs(svg) {
|
|
19
19
|
let hasStyle = false;
|
|
20
20
|
svg_parseStyle.parseSVGStyleSync(svg, (item) => {
|
|
21
|
+
if (item.type !== "inline" && item.type !== "global") {
|
|
22
|
+
return item.value;
|
|
23
|
+
}
|
|
21
24
|
const prop = item.prop;
|
|
22
25
|
if (
|
|
23
26
|
// Attributes / properties now allowed
|
|
@@ -16,6 +16,9 @@ import '@iconify/utils/lib/svg/id';
|
|
|
16
16
|
function convertStyleToAttrs(svg) {
|
|
17
17
|
let hasStyle = false;
|
|
18
18
|
parseSVGStyleSync(svg, (item) => {
|
|
19
|
+
if (item.type !== "inline" && item.type !== "global") {
|
|
20
|
+
return item.value;
|
|
21
|
+
}
|
|
19
22
|
const prop = item.prop;
|
|
20
23
|
if (
|
|
21
24
|
// Attributes / properties now allowed
|
package/lib/svg/parse-style.cjs
CHANGED
|
@@ -24,7 +24,7 @@ function parseItem(item, callback, done) {
|
|
|
24
24
|
}
|
|
25
25
|
let changed2 = false;
|
|
26
26
|
const selectorStart = [];
|
|
27
|
-
|
|
27
|
+
let newTokens = [];
|
|
28
28
|
const parsedTokens = () => {
|
|
29
29
|
if (changed2) {
|
|
30
30
|
const tree = css_parser_tree.tokensTree(
|
|
@@ -34,7 +34,7 @@ function parseItem(item, callback, done) {
|
|
|
34
34
|
$element.remove();
|
|
35
35
|
} else {
|
|
36
36
|
const newContent = css_parser_export.tokensToString(tree);
|
|
37
|
-
item.$element.text(newContent);
|
|
37
|
+
item.$element.text("\n" + newContent);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
done2();
|
|
@@ -46,53 +46,156 @@ function parseItem(item, callback, done) {
|
|
|
46
46
|
}
|
|
47
47
|
switch (token.type) {
|
|
48
48
|
case "selector":
|
|
49
|
-
case "at-rule":
|
|
50
49
|
selectorStart.push(newTokens.length);
|
|
51
|
-
|
|
50
|
+
newTokens.push(token);
|
|
51
|
+
return nextToken();
|
|
52
52
|
case "close":
|
|
53
53
|
selectorStart.pop();
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
54
|
+
newTokens.push(token);
|
|
55
|
+
return nextToken();
|
|
56
|
+
case "at-rule": {
|
|
57
|
+
selectorStart.push(newTokens.length);
|
|
58
|
+
const prop = token.rule;
|
|
59
|
+
const value = token.value;
|
|
60
|
+
const isAnimation = prop === "keyframes" || prop.slice(0, 1) === "-" && prop.split("-").pop() === "keyframes";
|
|
61
|
+
const childTokens = [];
|
|
62
|
+
const animationRules = /* @__PURE__ */ Object.create(null);
|
|
63
|
+
let depth = 1;
|
|
64
|
+
let index = 0;
|
|
65
|
+
let isFrom = false;
|
|
66
|
+
while (depth > 0) {
|
|
67
|
+
const childToken = tokens[index];
|
|
68
|
+
index++;
|
|
69
|
+
if (!childToken) {
|
|
70
|
+
throw new Error("Something went wrong parsing CSS");
|
|
71
|
+
}
|
|
72
|
+
childTokens.push(childToken);
|
|
73
|
+
switch (childToken.type) {
|
|
74
|
+
case "close": {
|
|
75
|
+
depth--;
|
|
76
|
+
isFrom = false;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
case "selector": {
|
|
80
|
+
depth++;
|
|
81
|
+
if (isAnimation) {
|
|
82
|
+
const rule = childToken.code;
|
|
83
|
+
if (rule === "from" || rule === "0%") {
|
|
84
|
+
isFrom = true;
|
|
85
|
+
}
|
|
74
86
|
}
|
|
87
|
+
break;
|
|
88
|
+
}
|
|
89
|
+
case "at-rule": {
|
|
90
|
+
depth++;
|
|
91
|
+
if (isAnimation) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
"Nested at-rule in keyframes ???"
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
case "rule": {
|
|
99
|
+
if (isAnimation && isFrom) {
|
|
100
|
+
animationRules[childToken.prop] = childToken.value;
|
|
101
|
+
}
|
|
102
|
+
break;
|
|
75
103
|
}
|
|
76
|
-
return prev;
|
|
77
|
-
},
|
|
78
|
-
[]
|
|
79
|
-
),
|
|
80
|
-
prevTokens: newTokens,
|
|
81
|
-
nextTokens: tokens.slice(0)
|
|
82
|
-
},
|
|
83
|
-
(result) => {
|
|
84
|
-
if (result !== void 0) {
|
|
85
|
-
if (result !== value) {
|
|
86
|
-
changed2 = true;
|
|
87
|
-
token.value = result;
|
|
88
104
|
}
|
|
89
|
-
newTokens.push(token);
|
|
90
|
-
} else {
|
|
91
|
-
changed2 = true;
|
|
92
105
|
}
|
|
93
|
-
|
|
106
|
+
const skipCount = childTokens.length;
|
|
107
|
+
callback(
|
|
108
|
+
isAnimation ? {
|
|
109
|
+
type: "keyframes",
|
|
110
|
+
prop,
|
|
111
|
+
value,
|
|
112
|
+
token,
|
|
113
|
+
childTokens,
|
|
114
|
+
from: animationRules,
|
|
115
|
+
prevTokens: newTokens,
|
|
116
|
+
nextTokens: tokens.slice(0)
|
|
117
|
+
} : {
|
|
118
|
+
type: "at-rule",
|
|
119
|
+
prop,
|
|
120
|
+
value,
|
|
121
|
+
token,
|
|
122
|
+
childTokens,
|
|
123
|
+
prevTokens: newTokens,
|
|
124
|
+
nextTokens: tokens.slice(0)
|
|
125
|
+
},
|
|
126
|
+
(result) => {
|
|
127
|
+
if (result !== void 0) {
|
|
128
|
+
if (isAnimation) {
|
|
129
|
+
if (result !== value) {
|
|
130
|
+
changed2 = true;
|
|
131
|
+
token.value = result;
|
|
132
|
+
}
|
|
133
|
+
newTokens.push(token);
|
|
134
|
+
for (let i = 0; i < skipCount; i++) {
|
|
135
|
+
tokens.shift();
|
|
136
|
+
}
|
|
137
|
+
newTokens = newTokens.concat(childTokens);
|
|
138
|
+
} else {
|
|
139
|
+
if (result !== value) {
|
|
140
|
+
throw new Error(
|
|
141
|
+
"Changing value for at-rule is not supported"
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
newTokens.push(token);
|
|
145
|
+
}
|
|
146
|
+
} else {
|
|
147
|
+
changed2 = true;
|
|
148
|
+
for (let i = 0; i < skipCount; i++) {
|
|
149
|
+
tokens.shift();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
nextToken();
|
|
153
|
+
}
|
|
154
|
+
);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
case "rule": {
|
|
158
|
+
const value = token.value;
|
|
159
|
+
const selectorTokens = selectorStart.map((index) => newTokens[index]).filter((item2) => item2 !== null);
|
|
160
|
+
callback(
|
|
161
|
+
{
|
|
162
|
+
type: "global",
|
|
163
|
+
prop: token.prop,
|
|
164
|
+
value,
|
|
165
|
+
token,
|
|
166
|
+
selectorTokens,
|
|
167
|
+
selectors: selectorTokens.reduce(
|
|
168
|
+
(prev, current) => {
|
|
169
|
+
switch (current.type) {
|
|
170
|
+
case "selector": {
|
|
171
|
+
return prev.concat(
|
|
172
|
+
current.selectors
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return prev;
|
|
177
|
+
},
|
|
178
|
+
[]
|
|
179
|
+
),
|
|
180
|
+
prevTokens: newTokens,
|
|
181
|
+
nextTokens: tokens.slice(0)
|
|
182
|
+
},
|
|
183
|
+
(result) => {
|
|
184
|
+
if (result !== void 0) {
|
|
185
|
+
if (result !== value) {
|
|
186
|
+
changed2 = true;
|
|
187
|
+
token.value = result;
|
|
188
|
+
}
|
|
189
|
+
newTokens.push(token);
|
|
190
|
+
} else {
|
|
191
|
+
changed2 = true;
|
|
192
|
+
}
|
|
193
|
+
nextToken();
|
|
194
|
+
}
|
|
195
|
+
);
|
|
196
|
+
return;
|
|
94
197
|
}
|
|
95
|
-
|
|
198
|
+
}
|
|
96
199
|
};
|
|
97
200
|
nextToken();
|
|
98
201
|
}
|
package/lib/svg/parse-style.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { SVG } from './index.js';
|
|
2
|
-
import { CSSRuleToken, CSSToken } from '../css/parser/types.js';
|
|
2
|
+
import { CSSRuleToken, CSSToken, CSSAtRuleToken } from '../css/parser/types.js';
|
|
3
3
|
import { ParseSVGCallbackItem } from './parse.js';
|
|
4
4
|
import '@iconify/types';
|
|
5
5
|
import '@iconify/utils/lib/customisations/defaults';
|
|
@@ -24,7 +24,20 @@ interface ParseSVGStyleCallbackItemGlobal extends ParseSVGStyleCallbackItemCommo
|
|
|
24
24
|
prevTokens: (CSSToken | null)[];
|
|
25
25
|
nextTokens: CSSToken[];
|
|
26
26
|
}
|
|
27
|
-
|
|
27
|
+
interface ParseSVGStyleCallbackItemGlobalAtRule extends ParseSVGStyleCallbackItemCommon {
|
|
28
|
+
token: CSSAtRuleToken;
|
|
29
|
+
childTokens: CSSToken[];
|
|
30
|
+
prevTokens: (CSSToken | null)[];
|
|
31
|
+
nextTokens: CSSToken[];
|
|
32
|
+
}
|
|
33
|
+
interface ParseSVGStyleCallbackItemGlobalGenericAtRule extends ParseSVGStyleCallbackItemGlobalAtRule {
|
|
34
|
+
type: 'at-rule';
|
|
35
|
+
}
|
|
36
|
+
interface ParseSVGStyleCallbackItemGlobalKeyframesAtRule extends ParseSVGStyleCallbackItemGlobalAtRule {
|
|
37
|
+
type: 'keyframes';
|
|
38
|
+
from: Record<string, string>;
|
|
39
|
+
}
|
|
40
|
+
type ParseSVGStyleCallbackItem = ParseSVGStyleCallbackItemInline | ParseSVGStyleCallbackItemGlobal | ParseSVGStyleCallbackItemGlobalGenericAtRule | ParseSVGStyleCallbackItemGlobalKeyframesAtRule;
|
|
28
41
|
/**
|
|
29
42
|
* Result: undefined to remove item, string to change/keep item
|
|
30
43
|
*/
|
package/lib/svg/parse-style.mjs
CHANGED
|
@@ -22,7 +22,7 @@ function parseItem(item, callback, done) {
|
|
|
22
22
|
}
|
|
23
23
|
let changed2 = false;
|
|
24
24
|
const selectorStart = [];
|
|
25
|
-
|
|
25
|
+
let newTokens = [];
|
|
26
26
|
const parsedTokens = () => {
|
|
27
27
|
if (changed2) {
|
|
28
28
|
const tree = tokensTree(
|
|
@@ -32,7 +32,7 @@ function parseItem(item, callback, done) {
|
|
|
32
32
|
$element.remove();
|
|
33
33
|
} else {
|
|
34
34
|
const newContent = tokensToString(tree);
|
|
35
|
-
item.$element.text(newContent);
|
|
35
|
+
item.$element.text("\n" + newContent);
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
done2();
|
|
@@ -44,53 +44,156 @@ function parseItem(item, callback, done) {
|
|
|
44
44
|
}
|
|
45
45
|
switch (token.type) {
|
|
46
46
|
case "selector":
|
|
47
|
-
case "at-rule":
|
|
48
47
|
selectorStart.push(newTokens.length);
|
|
49
|
-
|
|
48
|
+
newTokens.push(token);
|
|
49
|
+
return nextToken();
|
|
50
50
|
case "close":
|
|
51
51
|
selectorStart.pop();
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
52
|
+
newTokens.push(token);
|
|
53
|
+
return nextToken();
|
|
54
|
+
case "at-rule": {
|
|
55
|
+
selectorStart.push(newTokens.length);
|
|
56
|
+
const prop = token.rule;
|
|
57
|
+
const value = token.value;
|
|
58
|
+
const isAnimation = prop === "keyframes" || prop.slice(0, 1) === "-" && prop.split("-").pop() === "keyframes";
|
|
59
|
+
const childTokens = [];
|
|
60
|
+
const animationRules = /* @__PURE__ */ Object.create(null);
|
|
61
|
+
let depth = 1;
|
|
62
|
+
let index = 0;
|
|
63
|
+
let isFrom = false;
|
|
64
|
+
while (depth > 0) {
|
|
65
|
+
const childToken = tokens[index];
|
|
66
|
+
index++;
|
|
67
|
+
if (!childToken) {
|
|
68
|
+
throw new Error("Something went wrong parsing CSS");
|
|
69
|
+
}
|
|
70
|
+
childTokens.push(childToken);
|
|
71
|
+
switch (childToken.type) {
|
|
72
|
+
case "close": {
|
|
73
|
+
depth--;
|
|
74
|
+
isFrom = false;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
case "selector": {
|
|
78
|
+
depth++;
|
|
79
|
+
if (isAnimation) {
|
|
80
|
+
const rule = childToken.code;
|
|
81
|
+
if (rule === "from" || rule === "0%") {
|
|
82
|
+
isFrom = true;
|
|
83
|
+
}
|
|
72
84
|
}
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
case "at-rule": {
|
|
88
|
+
depth++;
|
|
89
|
+
if (isAnimation) {
|
|
90
|
+
throw new Error(
|
|
91
|
+
"Nested at-rule in keyframes ???"
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
break;
|
|
95
|
+
}
|
|
96
|
+
case "rule": {
|
|
97
|
+
if (isAnimation && isFrom) {
|
|
98
|
+
animationRules[childToken.prop] = childToken.value;
|
|
99
|
+
}
|
|
100
|
+
break;
|
|
73
101
|
}
|
|
74
|
-
return prev;
|
|
75
|
-
},
|
|
76
|
-
[]
|
|
77
|
-
),
|
|
78
|
-
prevTokens: newTokens,
|
|
79
|
-
nextTokens: tokens.slice(0)
|
|
80
|
-
},
|
|
81
|
-
(result) => {
|
|
82
|
-
if (result !== void 0) {
|
|
83
|
-
if (result !== value) {
|
|
84
|
-
changed2 = true;
|
|
85
|
-
token.value = result;
|
|
86
102
|
}
|
|
87
|
-
newTokens.push(token);
|
|
88
|
-
} else {
|
|
89
|
-
changed2 = true;
|
|
90
103
|
}
|
|
91
|
-
|
|
104
|
+
const skipCount = childTokens.length;
|
|
105
|
+
callback(
|
|
106
|
+
isAnimation ? {
|
|
107
|
+
type: "keyframes",
|
|
108
|
+
prop,
|
|
109
|
+
value,
|
|
110
|
+
token,
|
|
111
|
+
childTokens,
|
|
112
|
+
from: animationRules,
|
|
113
|
+
prevTokens: newTokens,
|
|
114
|
+
nextTokens: tokens.slice(0)
|
|
115
|
+
} : {
|
|
116
|
+
type: "at-rule",
|
|
117
|
+
prop,
|
|
118
|
+
value,
|
|
119
|
+
token,
|
|
120
|
+
childTokens,
|
|
121
|
+
prevTokens: newTokens,
|
|
122
|
+
nextTokens: tokens.slice(0)
|
|
123
|
+
},
|
|
124
|
+
(result) => {
|
|
125
|
+
if (result !== void 0) {
|
|
126
|
+
if (isAnimation) {
|
|
127
|
+
if (result !== value) {
|
|
128
|
+
changed2 = true;
|
|
129
|
+
token.value = result;
|
|
130
|
+
}
|
|
131
|
+
newTokens.push(token);
|
|
132
|
+
for (let i = 0; i < skipCount; i++) {
|
|
133
|
+
tokens.shift();
|
|
134
|
+
}
|
|
135
|
+
newTokens = newTokens.concat(childTokens);
|
|
136
|
+
} else {
|
|
137
|
+
if (result !== value) {
|
|
138
|
+
throw new Error(
|
|
139
|
+
"Changing value for at-rule is not supported"
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
newTokens.push(token);
|
|
143
|
+
}
|
|
144
|
+
} else {
|
|
145
|
+
changed2 = true;
|
|
146
|
+
for (let i = 0; i < skipCount; i++) {
|
|
147
|
+
tokens.shift();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
nextToken();
|
|
151
|
+
}
|
|
152
|
+
);
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
case "rule": {
|
|
156
|
+
const value = token.value;
|
|
157
|
+
const selectorTokens = selectorStart.map((index) => newTokens[index]).filter((item2) => item2 !== null);
|
|
158
|
+
callback(
|
|
159
|
+
{
|
|
160
|
+
type: "global",
|
|
161
|
+
prop: token.prop,
|
|
162
|
+
value,
|
|
163
|
+
token,
|
|
164
|
+
selectorTokens,
|
|
165
|
+
selectors: selectorTokens.reduce(
|
|
166
|
+
(prev, current) => {
|
|
167
|
+
switch (current.type) {
|
|
168
|
+
case "selector": {
|
|
169
|
+
return prev.concat(
|
|
170
|
+
current.selectors
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return prev;
|
|
175
|
+
},
|
|
176
|
+
[]
|
|
177
|
+
),
|
|
178
|
+
prevTokens: newTokens,
|
|
179
|
+
nextTokens: tokens.slice(0)
|
|
180
|
+
},
|
|
181
|
+
(result) => {
|
|
182
|
+
if (result !== void 0) {
|
|
183
|
+
if (result !== value) {
|
|
184
|
+
changed2 = true;
|
|
185
|
+
token.value = result;
|
|
186
|
+
}
|
|
187
|
+
newTokens.push(token);
|
|
188
|
+
} else {
|
|
189
|
+
changed2 = true;
|
|
190
|
+
}
|
|
191
|
+
nextToken();
|
|
192
|
+
}
|
|
193
|
+
);
|
|
194
|
+
return;
|
|
92
195
|
}
|
|
93
|
-
|
|
196
|
+
}
|
|
94
197
|
};
|
|
95
198
|
nextToken();
|
|
96
199
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Collection of functions for cleaning up and parsing SVG for Iconify project",
|
|
5
5
|
"author": "Vjacheslav Trushkin",
|
|
6
|
-
"version": "3.0.0-beta.
|
|
6
|
+
"version": "3.0.0-beta.2",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"bugs": "https://github.com/iconify/tools/issues",
|
|
9
9
|
"homepage": "https://github.com/iconify/tools",
|