@iconify/tools 2.0.13 → 2.0.14
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/optimise/global-style.js +65 -38
- package/lib/optimise/global-style.mjs +51 -33
- package/lib/svg/index.js +13 -4
- package/lib/svg/index.mjs +5 -2
- package/package.json +1 -1
|
@@ -46,52 +46,76 @@ async function cleanupGlobalStyle(svg) {
|
|
|
46
46
|
return returnValue;
|
|
47
47
|
}
|
|
48
48
|
// Handle only simple selectors
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
/*
|
|
50
|
+
if (
|
|
51
|
+
styleItem.selectors.length !== 1 ||
|
|
52
|
+
styleItem.selectorTokens.length !== 1
|
|
53
|
+
) {
|
|
51
54
|
return returnValue;
|
|
52
55
|
}
|
|
56
|
+
*/
|
|
53
57
|
// Do not handle media queries
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const firstChar = selector.charAt(0);
|
|
61
|
-
let matchType;
|
|
62
|
-
if (firstChar === '.') {
|
|
63
|
-
matchType = 'class';
|
|
64
|
-
}
|
|
65
|
-
else if (firstChar === '#') {
|
|
66
|
-
matchType = 'id';
|
|
67
|
-
}
|
|
68
|
-
else if (tags_1.allValidTags.has(selector)) {
|
|
69
|
-
matchType = 'tag';
|
|
70
|
-
}
|
|
71
|
-
else {
|
|
72
|
-
return returnValue;
|
|
58
|
+
const selectorTokens = styleItem.selectorTokens;
|
|
59
|
+
for (let i = 0; i < selectorTokens.length; i++) {
|
|
60
|
+
const selectorToken = selectorTokens[i];
|
|
61
|
+
if (selectorToken.type !== 'selector') {
|
|
62
|
+
return returnValue;
|
|
63
|
+
}
|
|
73
64
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
65
|
+
// Parse each selectors
|
|
66
|
+
const selectors = styleItem.selectors;
|
|
67
|
+
const matches = [];
|
|
68
|
+
for (let i = 0; i < selectors.length; i++) {
|
|
69
|
+
const selector = styleItem.selectors[i];
|
|
70
|
+
const firstChar = selector.charAt(0);
|
|
71
|
+
let matchType;
|
|
72
|
+
if (firstChar === '.') {
|
|
73
|
+
matchType = 'class';
|
|
74
|
+
}
|
|
75
|
+
else if (firstChar === '#') {
|
|
76
|
+
matchType = 'id';
|
|
77
|
+
}
|
|
78
|
+
else if (tags_1.allValidTags.has(selector)) {
|
|
79
|
+
matchType = 'tag';
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
return returnValue;
|
|
83
|
+
}
|
|
84
|
+
const valueMatch = matchType === 'tag' ? selector : selector.slice(1);
|
|
85
|
+
if (matchType === 'class' && animatedClasses.has(valueMatch)) {
|
|
86
|
+
// Class name is used in animations
|
|
87
|
+
return returnValue;
|
|
88
|
+
}
|
|
89
|
+
matches.push({
|
|
90
|
+
type: matchType,
|
|
91
|
+
value: valueMatch,
|
|
92
|
+
});
|
|
78
93
|
}
|
|
79
94
|
// Check if element is a match
|
|
80
95
|
const isMatch = (tagName, $element) => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
96
|
+
for (let i = 0; i < matches.length; i++) {
|
|
97
|
+
const { type, value } = matches[i];
|
|
98
|
+
switch (type) {
|
|
99
|
+
case 'id':
|
|
100
|
+
if ($element.attr('id') === value) {
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
break;
|
|
104
|
+
case 'tag':
|
|
105
|
+
if (tagName === value) {
|
|
106
|
+
return true;
|
|
107
|
+
}
|
|
108
|
+
break;
|
|
109
|
+
case 'class': {
|
|
110
|
+
const className = $element.attr('class');
|
|
111
|
+
if (className &&
|
|
112
|
+
getClassList(className).indexOf(value) !== -1) {
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
91
115
|
}
|
|
92
116
|
}
|
|
93
117
|
}
|
|
94
|
-
return
|
|
118
|
+
return false;
|
|
95
119
|
};
|
|
96
120
|
// Parse all elements
|
|
97
121
|
await (0, parse_1.parseSVG)(svg, (svgItem) => {
|
|
@@ -118,7 +142,10 @@ async function cleanupGlobalStyle(svg) {
|
|
|
118
142
|
containsTempAttr = true;
|
|
119
143
|
});
|
|
120
144
|
// Remove class attribute
|
|
121
|
-
|
|
145
|
+
const classMatches = matches
|
|
146
|
+
.filter((item) => item.type === 'class')
|
|
147
|
+
.map((item) => item.value);
|
|
148
|
+
if (classMatches.length &&
|
|
122
149
|
((_a = styleItem.nextTokens[0]) === null || _a === void 0 ? void 0 : _a.type) === 'close') {
|
|
123
150
|
// Can remove class
|
|
124
151
|
await (0, parse_1.parseSVG)(svg, (svgItem) => {
|
|
@@ -131,7 +158,7 @@ async function cleanupGlobalStyle(svg) {
|
|
|
131
158
|
if (!classList) {
|
|
132
159
|
return;
|
|
133
160
|
}
|
|
134
|
-
const filtered = classList.filter((item) => item
|
|
161
|
+
const filtered = classList.filter((item) => classMatches.indexOf(item) === -1);
|
|
135
162
|
if (!filtered.length) {
|
|
136
163
|
$element.removeAttr('class');
|
|
137
164
|
}
|
|
@@ -38,43 +38,60 @@ async function cleanupGlobalStyle(svg) {
|
|
|
38
38
|
if (styleItem.type !== "global") {
|
|
39
39
|
return returnValue;
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
const selector = styleItem.selectors[0];
|
|
49
|
-
const firstChar = selector.charAt(0);
|
|
50
|
-
let matchType;
|
|
51
|
-
if (firstChar === ".") {
|
|
52
|
-
matchType = "class";
|
|
53
|
-
} else if (firstChar === "#") {
|
|
54
|
-
matchType = "id";
|
|
55
|
-
} else if (allValidTags.has(selector)) {
|
|
56
|
-
matchType = "tag";
|
|
57
|
-
} else {
|
|
58
|
-
return returnValue;
|
|
41
|
+
const selectorTokens = styleItem.selectorTokens;
|
|
42
|
+
for (let i = 0; i < selectorTokens.length; i++) {
|
|
43
|
+
const selectorToken = selectorTokens[i];
|
|
44
|
+
if (selectorToken.type !== "selector") {
|
|
45
|
+
return returnValue;
|
|
46
|
+
}
|
|
59
47
|
}
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
48
|
+
const selectors = styleItem.selectors;
|
|
49
|
+
const matches = [];
|
|
50
|
+
for (let i = 0; i < selectors.length; i++) {
|
|
51
|
+
const selector = styleItem.selectors[i];
|
|
52
|
+
const firstChar = selector.charAt(0);
|
|
53
|
+
let matchType;
|
|
54
|
+
if (firstChar === ".") {
|
|
55
|
+
matchType = "class";
|
|
56
|
+
} else if (firstChar === "#") {
|
|
57
|
+
matchType = "id";
|
|
58
|
+
} else if (allValidTags.has(selector)) {
|
|
59
|
+
matchType = "tag";
|
|
60
|
+
} else {
|
|
61
|
+
return returnValue;
|
|
62
|
+
}
|
|
63
|
+
const valueMatch = matchType === "tag" ? selector : selector.slice(1);
|
|
64
|
+
if (matchType === "class" && animatedClasses.has(valueMatch)) {
|
|
65
|
+
return returnValue;
|
|
66
|
+
}
|
|
67
|
+
matches.push({
|
|
68
|
+
type: matchType,
|
|
69
|
+
value: valueMatch
|
|
70
|
+
});
|
|
63
71
|
}
|
|
64
72
|
const isMatch = (tagName, $element) => {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
73
|
+
for (let i = 0; i < matches.length; i++) {
|
|
74
|
+
const { type, value } = matches[i];
|
|
75
|
+
switch (type) {
|
|
76
|
+
case "id":
|
|
77
|
+
if ($element.attr("id") === value) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
case "tag":
|
|
82
|
+
if (tagName === value) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
break;
|
|
86
|
+
case "class": {
|
|
87
|
+
const className = $element.attr("class");
|
|
88
|
+
if (className && getClassList(className).indexOf(value) !== -1) {
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
74
91
|
}
|
|
75
92
|
}
|
|
76
93
|
}
|
|
77
|
-
return
|
|
94
|
+
return false;
|
|
78
95
|
};
|
|
79
96
|
await parseSVG(svg, (svgItem) => {
|
|
80
97
|
var _a2;
|
|
@@ -95,7 +112,8 @@ async function cleanupGlobalStyle(svg) {
|
|
|
95
112
|
$element.attr(tempDataAttrbiute, Array.from(addedAttributes).join(" "));
|
|
96
113
|
containsTempAttr = true;
|
|
97
114
|
});
|
|
98
|
-
|
|
115
|
+
const classMatches = matches.filter((item) => item.type === "class").map((item) => item.value);
|
|
116
|
+
if (classMatches.length && ((_a = styleItem.nextTokens[0]) == null ? void 0 : _a.type) === "close") {
|
|
99
117
|
await parseSVG(svg, (svgItem) => {
|
|
100
118
|
const $element = svgItem.$element;
|
|
101
119
|
if (!isMatch("", $element)) {
|
|
@@ -105,7 +123,7 @@ async function cleanupGlobalStyle(svg) {
|
|
|
105
123
|
if (!classList) {
|
|
106
124
|
return;
|
|
107
125
|
}
|
|
108
|
-
const filtered = classList.filter((item) => item
|
|
126
|
+
const filtered = classList.filter((item) => classMatches.indexOf(item) === -1);
|
|
109
127
|
if (!filtered.length) {
|
|
110
128
|
$element.removeAttr("class");
|
|
111
129
|
} else {
|
package/lib/svg/index.js
CHANGED
|
@@ -5,6 +5,17 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.SVG = void 0;
|
|
7
7
|
const cheerio_1 = __importDefault(require("cheerio"));
|
|
8
|
+
/**
|
|
9
|
+
* Remove whitespace
|
|
10
|
+
*/
|
|
11
|
+
function minify(str) {
|
|
12
|
+
return (str
|
|
13
|
+
// Replace new line only after one of allowed characters that are not part of common attributes
|
|
14
|
+
.replace(/(["';{}}><])\s*\n\s*/g, '$1')
|
|
15
|
+
// Keep one space in case it is inside attribute
|
|
16
|
+
.replace(/\s*\n\s*/g, ' ')
|
|
17
|
+
.trim());
|
|
18
|
+
}
|
|
8
19
|
/**
|
|
9
20
|
* SVG class, used to manipulate icon content.
|
|
10
21
|
*/
|
|
@@ -38,16 +49,14 @@ class SVG {
|
|
|
38
49
|
* Get SVG as string without whitespaces
|
|
39
50
|
*/
|
|
40
51
|
toMinifiedString() {
|
|
41
|
-
return this.toString()
|
|
52
|
+
return minify(this.toString());
|
|
42
53
|
}
|
|
43
54
|
/**
|
|
44
55
|
* Get body
|
|
45
56
|
*/
|
|
46
57
|
getBody() {
|
|
47
58
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
48
|
-
return this.$svg('svg')
|
|
49
|
-
.html()
|
|
50
|
-
.replace(/\s*\n\s*/g, '');
|
|
59
|
+
return minify(this.$svg('svg').html());
|
|
51
60
|
}
|
|
52
61
|
/**
|
|
53
62
|
* Load SVG
|
package/lib/svg/index.mjs
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// src/svg/index.ts
|
|
2
2
|
import cheerio from "cheerio";
|
|
3
|
+
function minify(str) {
|
|
4
|
+
return str.replace(/(["';{}}><])\s*\n\s*/g, "$1").replace(/\s*\n\s*/g, " ").trim();
|
|
5
|
+
}
|
|
3
6
|
var SVG = class {
|
|
4
7
|
constructor(content) {
|
|
5
8
|
this.load(content);
|
|
@@ -19,10 +22,10 @@ var SVG = class {
|
|
|
19
22
|
return this.$svg.html();
|
|
20
23
|
}
|
|
21
24
|
toMinifiedString() {
|
|
22
|
-
return this.toString()
|
|
25
|
+
return minify(this.toString());
|
|
23
26
|
}
|
|
24
27
|
getBody() {
|
|
25
|
-
return this.$svg("svg").html()
|
|
28
|
+
return minify(this.$svg("svg").html());
|
|
26
29
|
}
|
|
27
30
|
load(content) {
|
|
28
31
|
function remove(str1, str2, append) {
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@iconify/tools",
|
|
3
3
|
"description": "Collection of functions for cleaning up and parsing SVG for Iconify project",
|
|
4
4
|
"author": "Vjacheslav Trushkin",
|
|
5
|
-
"version": "2.0.
|
|
5
|
+
"version": "2.0.14",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"bugs": "https://github.com/iconify/tools/issues",
|
|
8
8
|
"homepage": "https://github.com/iconify/tools",
|