@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.
@@ -46,52 +46,76 @@ async function cleanupGlobalStyle(svg) {
46
46
  return returnValue;
47
47
  }
48
48
  // Handle only simple selectors
49
- if (styleItem.selectors.length !== 1 ||
50
- styleItem.selectorTokens.length !== 1) {
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 selectorToken = styleItem.selectorTokens[0];
55
- if (selectorToken.type !== 'selector') {
56
- return returnValue;
57
- }
58
- // Simple selector and simple rule
59
- const selector = styleItem.selectors[0];
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
- const valueMatch = matchType === 'tag' ? selector : selector.slice(1);
75
- if (matchType === 'class' && animatedClasses.has(valueMatch)) {
76
- // Class name is used in animations
77
- return returnValue;
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
- switch (matchType) {
82
- case 'id':
83
- return $element.attr('id') === valueMatch;
84
- case 'tag':
85
- return tagName === valueMatch;
86
- case 'class': {
87
- const className = $element.attr('class');
88
- if (!className ||
89
- getClassList(className).indexOf(valueMatch) === -1) {
90
- return false;
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 true;
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
- if (matchType === 'class' &&
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 !== valueMatch);
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
- if (styleItem.selectors.length !== 1 || styleItem.selectorTokens.length !== 1) {
42
- return returnValue;
43
- }
44
- const selectorToken = styleItem.selectorTokens[0];
45
- if (selectorToken.type !== "selector") {
46
- return returnValue;
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 valueMatch = matchType === "tag" ? selector : selector.slice(1);
61
- if (matchType === "class" && animatedClasses.has(valueMatch)) {
62
- return returnValue;
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
- switch (matchType) {
66
- case "id":
67
- return $element.attr("id") === valueMatch;
68
- case "tag":
69
- return tagName === valueMatch;
70
- case "class": {
71
- const className = $element.attr("class");
72
- if (!className || getClassList(className).indexOf(valueMatch) === -1) {
73
- return false;
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 true;
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
- if (matchType === "class" && ((_a = styleItem.nextTokens[0]) == null ? void 0 : _a.type) === "close") {
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 !== valueMatch);
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().replace(/\s*\n\s*/g, '');
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().replace(/\s*\n\s*/g, "");
25
+ return minify(this.toString());
23
26
  }
24
27
  getBody() {
25
- return this.$svg("svg").html().replace(/\s*\n\s*/g, "");
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.13",
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",