@iconify/tools 1.3.17 → 2.0.0-dev.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.
Files changed (147) hide show
  1. package/.editorconfig +13 -0
  2. package/.eslintignore +2 -0
  3. package/lib/colors/attribs.d.ts +16 -0
  4. package/lib/colors/attribs.js +26 -0
  5. package/lib/colors/attribs.mjs +28 -0
  6. package/lib/colors/parse.d.ts +37 -0
  7. package/lib/colors/parse.js +261 -0
  8. package/lib/colors/parse.mjs +212 -0
  9. package/lib/css/parse.d.ts +4 -0
  10. package/lib/css/parse.js +23 -0
  11. package/lib/css/parse.mjs +20 -0
  12. package/lib/css/parser/error.d.ts +11 -0
  13. package/lib/css/parser/error.js +27 -0
  14. package/lib/css/parser/error.mjs +23 -0
  15. package/lib/css/parser/export.d.ts +5 -0
  16. package/lib/css/parser/export.js +69 -0
  17. package/lib/css/parser/export.mjs +46 -0
  18. package/lib/css/parser/strings.d.ts +13 -0
  19. package/lib/css/parser/strings.js +93 -0
  20. package/lib/css/parser/strings.mjs +74 -0
  21. package/lib/css/parser/text.d.ts +17 -0
  22. package/lib/css/parser/text.js +174 -0
  23. package/lib/css/parser/text.mjs +133 -0
  24. package/lib/css/parser/tokens.d.ts +6 -0
  25. package/lib/css/parser/tokens.js +200 -0
  26. package/lib/css/parser/tokens.mjs +186 -0
  27. package/lib/css/parser/tree.d.ts +5 -0
  28. package/lib/css/parser/tree.js +44 -0
  29. package/lib/css/parser/tree.mjs +40 -0
  30. package/lib/css/parser/types.d.ts +51 -0
  31. package/lib/css/parser/types.js +2 -0
  32. package/lib/css/parser/types.mjs +0 -0
  33. package/lib/icon-set/index.d.ts +134 -0
  34. package/lib/icon-set/index.js +776 -0
  35. package/lib/icon-set/index.mjs +617 -0
  36. package/lib/icon-set/match.d.ts +6 -0
  37. package/lib/icon-set/match.js +66 -0
  38. package/lib/icon-set/match.mjs +55 -0
  39. package/lib/icon-set/merge.d.ts +5 -0
  40. package/lib/icon-set/merge.js +91 -0
  41. package/lib/icon-set/merge.mjs +75 -0
  42. package/lib/icon-set/props.d.ts +10 -0
  43. package/lib/icon-set/props.js +33 -0
  44. package/lib/icon-set/props.mjs +25 -0
  45. package/lib/icon-set/types.d.ts +68 -0
  46. package/lib/icon-set/types.js +2 -0
  47. package/lib/icon-set/types.mjs +0 -0
  48. package/lib/import/directory.d.ts +35 -0
  49. package/lib/import/directory.js +59 -0
  50. package/lib/import/directory.mjs +47 -0
  51. package/lib/misc/keyword.d.ts +4 -0
  52. package/lib/misc/keyword.js +31 -0
  53. package/lib/misc/keyword.mjs +17 -0
  54. package/lib/misc/scan.d.ts +24 -0
  55. package/lib/misc/scan.js +48 -0
  56. package/lib/misc/scan.mjs +43 -0
  57. package/lib/optimise/flags.d.ts +5 -0
  58. package/lib/optimise/flags.js +303 -0
  59. package/lib/optimise/flags.mjs +241 -0
  60. package/lib/optimise/scale.d.ts +5 -0
  61. package/lib/optimise/scale.js +42 -0
  62. package/lib/optimise/scale.mjs +22 -0
  63. package/lib/optimise/svgo.d.ts +27 -0
  64. package/lib/optimise/svgo.js +88 -0
  65. package/lib/optimise/svgo.mjs +75 -0
  66. package/lib/svg/cleanup/attribs.d.ts +5 -0
  67. package/lib/svg/cleanup/attribs.js +43 -0
  68. package/lib/svg/cleanup/attribs.mjs +36 -0
  69. package/lib/svg/cleanup/bad-tags.d.ts +5 -0
  70. package/lib/svg/cleanup/bad-tags.js +69 -0
  71. package/lib/svg/cleanup/bad-tags.mjs +68 -0
  72. package/lib/svg/cleanup/inline-style.d.ts +5 -0
  73. package/lib/svg/cleanup/inline-style.js +77 -0
  74. package/lib/svg/cleanup/inline-style.mjs +65 -0
  75. package/lib/svg/cleanup/root-svg.d.ts +5 -0
  76. package/lib/svg/cleanup/root-svg.js +106 -0
  77. package/lib/svg/cleanup/root-svg.mjs +88 -0
  78. package/lib/svg/cleanup/svgo-style.d.ts +5 -0
  79. package/lib/svg/cleanup/svgo-style.js +35 -0
  80. package/lib/svg/cleanup/svgo-style.mjs +29 -0
  81. package/lib/svg/cleanup.d.ts +5 -0
  82. package/lib/svg/cleanup.js +24 -0
  83. package/lib/svg/cleanup.mjs +16 -0
  84. package/lib/svg/data/attributes.d.ts +71 -0
  85. package/lib/svg/data/attributes.js +403 -0
  86. package/lib/svg/data/attributes.mjs +352 -0
  87. package/lib/svg/data/tags.d.ts +89 -0
  88. package/lib/svg/data/tags.js +185 -0
  89. package/lib/svg/data/tags.mjs +136 -0
  90. package/lib/svg/index.d.ts +33 -0
  91. package/lib/svg/index.js +122 -0
  92. package/lib/svg/index.mjs +85 -0
  93. package/lib/svg/parse-style.d.ts +40 -0
  94. package/lib/svg/parse-style.js +131 -0
  95. package/lib/svg/parse-style.mjs +109 -0
  96. package/lib/svg/parse.d.ts +30 -0
  97. package/lib/svg/parse.js +49 -0
  98. package/lib/svg/parse.mjs +40 -0
  99. package/package.json +167 -13
  100. package/README.md +0 -576
  101. package/license.txt +0 -21
  102. package/sample/parse.js +0 -74
  103. package/sample/source/icon-close.svg +0 -15
  104. package/sample/source/icon-confirm.svg +0 -14
  105. package/sample/source/icon-search.svg +0 -16
  106. package/src/collection.js +0 -641
  107. package/src/colors/change_palette.js +0 -227
  108. package/src/colors/get_palette.js +0 -143
  109. package/src/colors/opacify.js +0 -195
  110. package/src/export/component.js +0 -482
  111. package/src/export/dir.js +0 -109
  112. package/src/export/json.js +0 -329
  113. package/src/export/phantomjs.js +0 -76
  114. package/src/export/phantomjs_script.js +0 -125
  115. package/src/export/png.js +0 -193
  116. package/src/export/svg.js +0 -55
  117. package/src/export/templates/component.md +0 -79
  118. package/src/export/templates/info.md +0 -3
  119. package/src/export/templates/sample-react-1.md +0 -21
  120. package/src/export/templates/sample-react-2.md +0 -15
  121. package/src/export/templates/sample-react.md +0 -11
  122. package/src/export/templates/sample-svelte.md +0 -11
  123. package/src/export/templates/sample-svelte1.md +0 -22
  124. package/src/export/templates/sample-svelte2.md +0 -13
  125. package/src/export/templates/sample-vue-0.md +0 -30
  126. package/src/export/templates/sample-vue-1.md +0 -25
  127. package/src/export/templates/sample-vue-2.md +0 -27
  128. package/src/export/templates/sample-vue.md +0 -28
  129. package/src/helpers.js +0 -43
  130. package/src/import/dir.js +0 -234
  131. package/src/import/font.js +0 -402
  132. package/src/import/json.js +0 -200
  133. package/src/import/svg.js +0 -60
  134. package/src/import/web_icons.js +0 -248
  135. package/src/modules.js +0 -50
  136. package/src/optimize/crop.js +0 -554
  137. package/src/optimize/crop_script.js +0 -525
  138. package/src/optimize/flags.js +0 -430
  139. package/src/optimize/scale.js +0 -72
  140. package/src/optimize/svgo.js +0 -161
  141. package/src/optimize/tags.js +0 -522
  142. package/src/shapes/convert.js +0 -264
  143. package/src/shapes/index.js +0 -135
  144. package/src/shapes/length.js +0 -707
  145. package/src/shapes/length_script.js +0 -105
  146. package/src/shapes/options.js +0 -60
  147. package/src/svg.js +0 -162
@@ -0,0 +1,136 @@
1
+ // src/svg/data/tags.ts
2
+ var badTags = new Set([
3
+ "foreignObject",
4
+ "script",
5
+ "image",
6
+ "feImage",
7
+ "animateColor",
8
+ "altGlyph",
9
+ "text",
10
+ "tspan",
11
+ "switch",
12
+ "textPath",
13
+ "font",
14
+ "font-face",
15
+ "glyph",
16
+ "missing-glyph",
17
+ "hkern",
18
+ "vhern",
19
+ "view",
20
+ "a"
21
+ ]);
22
+ var unsupportedTags = new Set(["metadata", "desc", "title"]);
23
+ var styleTag = new Set(["style"]);
24
+ var defsTag = new Set(["defs"]);
25
+ var maskAndSymbolTags = new Set(["clipPath", "mask", "symbol"]);
26
+ var shapeTags = new Set([
27
+ "circle",
28
+ "ellipse",
29
+ "line",
30
+ "path",
31
+ "polygon",
32
+ "polyline",
33
+ "rect"
34
+ ]);
35
+ var useTag = new Set(["use"]);
36
+ var groupTag = new Set(["g"]);
37
+ var markerTag = new Set(["marker"]);
38
+ var animateTags = new Set([
39
+ "animate",
40
+ "animateMotion",
41
+ "animateTransform",
42
+ "discard",
43
+ "set"
44
+ ]);
45
+ var animateMotionChildTags = new Set(["mpath"]);
46
+ var gradientTags = new Set(["linearGradient", "radialGradient"]);
47
+ var gradientChildTags = new Set(["stop"]);
48
+ var patternTag = new Set(["pattern"]);
49
+ var filterTag = new Set(["filter"]);
50
+ var feLightningTags = new Set([
51
+ "feDiffuseLighting",
52
+ "feSpecularLighting"
53
+ ]);
54
+ var filterChildTags = new Set([
55
+ "feBlend",
56
+ "feColorMatrix",
57
+ "feComponentTransfer",
58
+ "feComposite",
59
+ "feConvolveMatrix",
60
+ "feDisplacementMap",
61
+ "feDropShadow",
62
+ "feFlood",
63
+ "feGaussianBlur",
64
+ "feMerge",
65
+ "feMorphology",
66
+ "feOffset",
67
+ "feTile",
68
+ "feTurbulence",
69
+ ...feLightningTags
70
+ ]);
71
+ var feComponentTransferChildTag = new Set([
72
+ "feFuncR",
73
+ "feFuncG",
74
+ "feFuncB",
75
+ "feFuncA"
76
+ ]);
77
+ var feLightningChildTags = new Set([
78
+ "feSpotLight",
79
+ "fePointLight",
80
+ "feDistantLight"
81
+ ]);
82
+ var feMergeChildTags = new Set(["feMergeNode"]);
83
+ var tagsInsideDefs = new Set([
84
+ ...gradientTags,
85
+ ...patternTag,
86
+ ...markerTag
87
+ ]);
88
+ var tagsBeforeAnimation = new Set([
89
+ ...shapeTags,
90
+ ...filterChildTags,
91
+ ...feComponentTransferChildTag
92
+ ]);
93
+ var allValidTags = new Set([
94
+ ...styleTag,
95
+ ...defsTag,
96
+ ...maskAndSymbolTags,
97
+ ...shapeTags,
98
+ ...useTag,
99
+ ...groupTag,
100
+ ...markerTag,
101
+ ...animateTags,
102
+ ...animateMotionChildTags,
103
+ ...gradientTags,
104
+ ...gradientChildTags,
105
+ ...patternTag,
106
+ ...filterTag,
107
+ ...filterChildTags,
108
+ ...feComponentTransferChildTag,
109
+ ...feLightningChildTags,
110
+ ...feMergeChildTags
111
+ ]);
112
+ export {
113
+ allValidTags,
114
+ animateMotionChildTags,
115
+ animateTags,
116
+ badTags,
117
+ defsTag,
118
+ feComponentTransferChildTag,
119
+ feLightningChildTags,
120
+ feLightningTags,
121
+ feMergeChildTags,
122
+ filterChildTags,
123
+ filterTag,
124
+ gradientChildTags,
125
+ gradientTags,
126
+ groupTag,
127
+ markerTag,
128
+ maskAndSymbolTags,
129
+ patternTag,
130
+ shapeTags,
131
+ styleTag,
132
+ tagsBeforeAnimation,
133
+ tagsInsideDefs,
134
+ unsupportedTags,
135
+ useTag
136
+ };
@@ -0,0 +1,33 @@
1
+ /// <reference types="cheerio" />
2
+ export interface ViewBox {
3
+ left: number;
4
+ top: number;
5
+ width: number;
6
+ height: number;
7
+ }
8
+ export declare class SVG {
9
+ $svg: cheerio.Root;
10
+ viewBox: ViewBox;
11
+ /**
12
+ * Constructor
13
+ */
14
+ constructor(content: string);
15
+ /**
16
+ * Get SVG as string
17
+ */
18
+ toString(): string;
19
+ /**
20
+ * Get SVG as string without whitespaces
21
+ */
22
+ toMinifiedString(): string;
23
+ /**
24
+ * Get body
25
+ */
26
+ getBody(): string;
27
+ /**
28
+ * Load SVG
29
+ *
30
+ * @param {string} content
31
+ */
32
+ load(content: string): void;
33
+ }
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SVG = void 0;
7
+ const cheerio_1 = __importDefault(require("cheerio"));
8
+ class SVG {
9
+ /**
10
+ * Constructor
11
+ */
12
+ constructor(content) {
13
+ this.load(content);
14
+ }
15
+ /**
16
+ * Get SVG as string
17
+ */
18
+ toString() {
19
+ const $root = this.$svg(':root');
20
+ const box = this.viewBox;
21
+ // Add missing viewBox attribute
22
+ if ($root.attr('viewBox') === void 0) {
23
+ $root.attr('viewBox', box.left + ' ' + box.top + ' ' + box.width + ' ' + box.height);
24
+ }
25
+ // Add missing width/height
26
+ if ($root.attr('width') === void 0) {
27
+ $root.attr('width', box.width + '');
28
+ }
29
+ if ($root.attr('height') === void 0) {
30
+ $root.attr('height', box.height + '');
31
+ }
32
+ return this.$svg.html();
33
+ }
34
+ /**
35
+ * Get SVG as string without whitespaces
36
+ */
37
+ toMinifiedString() {
38
+ return this.toString().replace(/\s*\n\s*/g, '');
39
+ }
40
+ /**
41
+ * Get body
42
+ */
43
+ getBody() {
44
+ // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
45
+ return this.$svg('svg')
46
+ .html()
47
+ .replace(/\s*\n\s*/g, '');
48
+ }
49
+ /**
50
+ * Load SVG
51
+ *
52
+ * @param {string} content
53
+ */
54
+ load(content) {
55
+ // Remove junk
56
+ function remove(str1, str2, append) {
57
+ let start = 0;
58
+ while ((start = content.indexOf(str1, start)) !== -1) {
59
+ const end = content.indexOf(str2, start + str1.length);
60
+ if (end === -1) {
61
+ return;
62
+ }
63
+ content =
64
+ content.slice(0, start) +
65
+ append +
66
+ content.slice(end + str2.length);
67
+ start = start + append.length;
68
+ }
69
+ }
70
+ // Remove comments
71
+ remove('<!--', '-->', '');
72
+ // Remove doctype and XML declaration
73
+ remove('<?xml', '?>', '');
74
+ remove('<!DOCTYPE svg', '<svg', '<svg');
75
+ // Remove Adobe Illustrator junk
76
+ remove('xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"', '', '');
77
+ remove('xml:space="preserve"', '', '');
78
+ // Remove empty <g> elements
79
+ content = content.replace(/<g>\s*<\/g>/g, '');
80
+ // Load content
81
+ this.$svg = cheerio_1.default.load(content.trim(), {
82
+ lowerCaseAttributeNames: false,
83
+ xmlMode: true,
84
+ });
85
+ // Check root
86
+ const $root = this.$svg(':root');
87
+ if ($root.length > 1 || $root.get(0).tagName !== 'svg') {
88
+ throw new Error('Invalid SVG file: bad root tag');
89
+ }
90
+ // Get dimensions and origin
91
+ const viewBox = $root.attr('viewBox');
92
+ if (viewBox !== void 0) {
93
+ const list = viewBox.split(' ');
94
+ this.viewBox = {
95
+ left: parseFloat(list[0]),
96
+ top: parseFloat(list[1]),
97
+ width: parseFloat(list[2]),
98
+ height: parseFloat(list[3]),
99
+ };
100
+ }
101
+ else {
102
+ const width = $root.attr('width');
103
+ const height = $root.attr('height');
104
+ if (!width || !height) {
105
+ throw new Error('Invalid SVG file: missing dimensions');
106
+ }
107
+ this.viewBox = {
108
+ left: 0,
109
+ top: 0,
110
+ width: parseFloat(width),
111
+ height: parseFloat(height),
112
+ };
113
+ }
114
+ Object.keys(this.viewBox).forEach((key) => {
115
+ const attr = key;
116
+ if (isNaN(this.viewBox[attr])) {
117
+ throw new Error(`Invalid SVG file: invalid ${attr}`);
118
+ }
119
+ });
120
+ }
121
+ }
122
+ exports.SVG = SVG;
@@ -0,0 +1,85 @@
1
+ // src/svg/index.ts
2
+ import cheerio from "cheerio";
3
+ var SVG = class {
4
+ constructor(content) {
5
+ this.load(content);
6
+ }
7
+ toString() {
8
+ const $root = this.$svg(":root");
9
+ const box = this.viewBox;
10
+ if ($root.attr("viewBox") === void 0) {
11
+ $root.attr("viewBox", box.left + " " + box.top + " " + box.width + " " + box.height);
12
+ }
13
+ if ($root.attr("width") === void 0) {
14
+ $root.attr("width", box.width + "");
15
+ }
16
+ if ($root.attr("height") === void 0) {
17
+ $root.attr("height", box.height + "");
18
+ }
19
+ return this.$svg.html();
20
+ }
21
+ toMinifiedString() {
22
+ return this.toString().replace(/\s*\n\s*/g, "");
23
+ }
24
+ getBody() {
25
+ return this.$svg("svg").html().replace(/\s*\n\s*/g, "");
26
+ }
27
+ load(content) {
28
+ function remove(str1, str2, append) {
29
+ let start = 0;
30
+ while ((start = content.indexOf(str1, start)) !== -1) {
31
+ const end = content.indexOf(str2, start + str1.length);
32
+ if (end === -1) {
33
+ return;
34
+ }
35
+ content = content.slice(0, start) + append + content.slice(end + str2.length);
36
+ start = start + append.length;
37
+ }
38
+ }
39
+ remove("<!--", "-->", "");
40
+ remove("<?xml", "?>", "");
41
+ remove("<!DOCTYPE svg", "<svg", "<svg");
42
+ remove('xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"', "", "");
43
+ remove('xml:space="preserve"', "", "");
44
+ content = content.replace(/<g>\s*<\/g>/g, "");
45
+ this.$svg = cheerio.load(content.trim(), {
46
+ lowerCaseAttributeNames: false,
47
+ xmlMode: true
48
+ });
49
+ const $root = this.$svg(":root");
50
+ if ($root.length > 1 || $root.get(0).tagName !== "svg") {
51
+ throw new Error("Invalid SVG file: bad root tag");
52
+ }
53
+ const viewBox = $root.attr("viewBox");
54
+ if (viewBox !== void 0) {
55
+ const list = viewBox.split(" ");
56
+ this.viewBox = {
57
+ left: parseFloat(list[0]),
58
+ top: parseFloat(list[1]),
59
+ width: parseFloat(list[2]),
60
+ height: parseFloat(list[3])
61
+ };
62
+ } else {
63
+ const width = $root.attr("width");
64
+ const height = $root.attr("height");
65
+ if (!width || !height) {
66
+ throw new Error("Invalid SVG file: missing dimensions");
67
+ }
68
+ this.viewBox = {
69
+ left: 0,
70
+ top: 0,
71
+ width: parseFloat(width),
72
+ height: parseFloat(height)
73
+ };
74
+ }
75
+ Object.keys(this.viewBox).forEach((key) => {
76
+ const attr = key;
77
+ if (isNaN(this.viewBox[attr])) {
78
+ throw new Error(`Invalid SVG file: invalid ${attr}`);
79
+ }
80
+ });
81
+ }
82
+ };
83
+ export {
84
+ SVG
85
+ };
@@ -0,0 +1,40 @@
1
+ import type { SVG } from '.';
2
+ import { ParseSVGCallbackItem } from './parse';
3
+ /**
4
+ * Item in callback
5
+ */
6
+ interface ParseSVGStyleCallbackItemCommon {
7
+ prop: string;
8
+ value: string;
9
+ }
10
+ interface ParseSVGStyleCallbackItemInline extends ParseSVGStyleCallbackItemCommon {
11
+ type: 'inline';
12
+ item: ParseSVGCallbackItem;
13
+ }
14
+ interface ParseSVGStyleCallbackItemGlobal extends ParseSVGStyleCallbackItemCommon {
15
+ type: 'global';
16
+ }
17
+ export declare type ParseSVGStyleCallbackItem = ParseSVGStyleCallbackItemInline | ParseSVGStyleCallbackItemGlobal;
18
+ /**
19
+ * Result: undefined to remove item, string to change/keep item
20
+ */
21
+ export declare type ParseSVGStyleCallbackResult = string | undefined;
22
+ /**
23
+ * Callback function
24
+ */
25
+ export declare type ParseSVGStyleCallback = (item: ParseSVGStyleCallbackItem) => ParseSVGStyleCallbackResult | Promise<ParseSVGStyleCallbackResult>;
26
+ /**
27
+ * Options
28
+ */
29
+ interface ParseSVGStyleOptions {
30
+ skipMasks?: boolean;
31
+ }
32
+ /**
33
+ * Parse styles in SVG
34
+ *
35
+ * This function finds CSS in SVG, parses it, calls callback for each rule.
36
+ * Callback should return new value (string) or undefined to remove rule.
37
+ * Callback can be asynchronous.
38
+ */
39
+ export declare function parseSVGStyle(svg: SVG, callback: ParseSVGStyleCallback, options?: ParseSVGStyleOptions): Promise<void>;
40
+ export {};
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseSVGStyle = void 0;
4
+ const parse_1 = require("../css/parse");
5
+ const export_1 = require("../css/parser/export");
6
+ const tokens_1 = require("../css/parser/tokens");
7
+ const tree_1 = require("../css/parser/tree");
8
+ const tags_1 = require("./data/tags");
9
+ const parse_2 = require("./parse");
10
+ /**
11
+ * Parse styles in SVG
12
+ *
13
+ * This function finds CSS in SVG, parses it, calls callback for each rule.
14
+ * Callback should return new value (string) or undefined to remove rule.
15
+ * Callback can be asynchronous.
16
+ */
17
+ async function parseSVGStyle(svg, callback, options = {}) {
18
+ return (0, parse_2.parseSVG)(svg, async (item) => {
19
+ const tagName = item.tagName;
20
+ const $element = item.$element;
21
+ if (tagName === 'style') {
22
+ // Style tag
23
+ const content = $element.html();
24
+ if (typeof content !== 'string') {
25
+ $element.remove();
26
+ return;
27
+ }
28
+ const tokens = (0, tokens_1.getTokens)(content);
29
+ if (!(tokens instanceof Array)) {
30
+ // Invalid style
31
+ throw new Error('Error parsing style');
32
+ }
33
+ // Parse all tokens
34
+ let changed = false;
35
+ const newTokens = [];
36
+ for (let i = 0; i < tokens.length; i++) {
37
+ const token = tokens[i];
38
+ if (token.type !== 'rule') {
39
+ newTokens.push(token);
40
+ continue;
41
+ }
42
+ const value = token.value;
43
+ let result = callback({
44
+ type: 'global',
45
+ prop: token.prop,
46
+ value,
47
+ });
48
+ if (result instanceof Promise) {
49
+ result = await result;
50
+ }
51
+ if (result !== void 0) {
52
+ if (result !== value) {
53
+ changed = true;
54
+ token.value = result;
55
+ }
56
+ newTokens.push(token);
57
+ }
58
+ else {
59
+ // Delete token
60
+ changed = true;
61
+ }
62
+ }
63
+ if (!changed) {
64
+ return;
65
+ }
66
+ // Update style
67
+ const tree = (0, tree_1.tokensTree)(newTokens);
68
+ if (!tree.length) {
69
+ // Empty
70
+ $element.remove();
71
+ return;
72
+ }
73
+ const newContent = (0, export_1.tokensToString)(tree);
74
+ item.$element.text(newContent);
75
+ return;
76
+ }
77
+ // Skip masks
78
+ if (options.skipMasks && tags_1.maskAndSymbolTags.has(tagName)) {
79
+ return;
80
+ }
81
+ // Parse style
82
+ const attribs = item.element.attribs;
83
+ if (attribs.style === void 0) {
84
+ return;
85
+ }
86
+ const parsedStyle = (0, parse_1.parseInlineStyle)(attribs.style);
87
+ if (parsedStyle === null) {
88
+ // Ignore style
89
+ $element.removeAttr('style');
90
+ return;
91
+ }
92
+ const props = Object.keys(parsedStyle);
93
+ let changed = false;
94
+ for (let i = 0; i < props.length; i++) {
95
+ const prop = props[i];
96
+ const value = parsedStyle[prop];
97
+ let result = callback({
98
+ type: 'inline',
99
+ prop,
100
+ value,
101
+ item,
102
+ });
103
+ if (result instanceof Promise) {
104
+ result = await result;
105
+ }
106
+ if (result !== value) {
107
+ changed = true;
108
+ if (result === void 0) {
109
+ delete parsedStyle[prop];
110
+ }
111
+ else {
112
+ parsedStyle[prop] = result;
113
+ }
114
+ }
115
+ }
116
+ // Update style
117
+ if (!changed) {
118
+ return;
119
+ }
120
+ const newStyle = Object.keys(parsedStyle)
121
+ .map((key) => key + ':' + parsedStyle[key] + ';')
122
+ .join('');
123
+ if (!newStyle.length) {
124
+ $element.removeAttr('style');
125
+ }
126
+ else {
127
+ $element.attr('style', newStyle);
128
+ }
129
+ });
130
+ }
131
+ exports.parseSVGStyle = parseSVGStyle;
@@ -0,0 +1,109 @@
1
+ // src/svg/parse-style.ts
2
+ import { parseInlineStyle } from "../css/parse.mjs";
3
+ import { tokensToString } from "../css/parser/export.mjs";
4
+ import { getTokens } from "../css/parser/tokens.mjs";
5
+ import { tokensTree } from "../css/parser/tree.mjs";
6
+ import { maskAndSymbolTags } from "./data/tags.mjs";
7
+ import { parseSVG } from "./parse.mjs";
8
+ async function parseSVGStyle(svg, callback, options = {}) {
9
+ return parseSVG(svg, async (item) => {
10
+ const tagName = item.tagName;
11
+ const $element = item.$element;
12
+ if (tagName === "style") {
13
+ const content = $element.html();
14
+ if (typeof content !== "string") {
15
+ $element.remove();
16
+ return;
17
+ }
18
+ const tokens = getTokens(content);
19
+ if (!(tokens instanceof Array)) {
20
+ throw new Error("Error parsing style");
21
+ }
22
+ let changed2 = false;
23
+ const newTokens = [];
24
+ for (let i = 0; i < tokens.length; i++) {
25
+ const token = tokens[i];
26
+ if (token.type !== "rule") {
27
+ newTokens.push(token);
28
+ continue;
29
+ }
30
+ const value = token.value;
31
+ let result = callback({
32
+ type: "global",
33
+ prop: token.prop,
34
+ value
35
+ });
36
+ if (result instanceof Promise) {
37
+ result = await result;
38
+ }
39
+ if (result !== void 0) {
40
+ if (result !== value) {
41
+ changed2 = true;
42
+ token.value = result;
43
+ }
44
+ newTokens.push(token);
45
+ } else {
46
+ changed2 = true;
47
+ }
48
+ }
49
+ if (!changed2) {
50
+ return;
51
+ }
52
+ const tree = tokensTree(newTokens);
53
+ if (!tree.length) {
54
+ $element.remove();
55
+ return;
56
+ }
57
+ const newContent = tokensToString(tree);
58
+ item.$element.text(newContent);
59
+ return;
60
+ }
61
+ if (options.skipMasks && maskAndSymbolTags.has(tagName)) {
62
+ return;
63
+ }
64
+ const attribs = item.element.attribs;
65
+ if (attribs.style === void 0) {
66
+ return;
67
+ }
68
+ const parsedStyle = parseInlineStyle(attribs.style);
69
+ if (parsedStyle === null) {
70
+ $element.removeAttr("style");
71
+ return;
72
+ }
73
+ const props = Object.keys(parsedStyle);
74
+ let changed = false;
75
+ for (let i = 0; i < props.length; i++) {
76
+ const prop = props[i];
77
+ const value = parsedStyle[prop];
78
+ let result = callback({
79
+ type: "inline",
80
+ prop,
81
+ value,
82
+ item
83
+ });
84
+ if (result instanceof Promise) {
85
+ result = await result;
86
+ }
87
+ if (result !== value) {
88
+ changed = true;
89
+ if (result === void 0) {
90
+ delete parsedStyle[prop];
91
+ } else {
92
+ parsedStyle[prop] = result;
93
+ }
94
+ }
95
+ }
96
+ if (!changed) {
97
+ return;
98
+ }
99
+ const newStyle = Object.keys(parsedStyle).map((key) => key + ":" + parsedStyle[key] + ";").join("");
100
+ if (!newStyle.length) {
101
+ $element.removeAttr("style");
102
+ } else {
103
+ $element.attr("style", newStyle);
104
+ }
105
+ });
106
+ }
107
+ export {
108
+ parseSVGStyle
109
+ };
@@ -0,0 +1,30 @@
1
+ /// <reference types="cheerio" />
2
+ import type { SVG } from './';
3
+ /**
4
+ * Shortcuts for Cheerio elements
5
+ */
6
+ export declare type CheerioElement = cheerio.TagElement;
7
+ export declare type WrappedCheerioElement = cheerio.Cheerio;
8
+ /**
9
+ * Item in callback
10
+ */
11
+ export interface ParseSVGCallbackItem {
12
+ tagName: string;
13
+ element: CheerioElement;
14
+ $element: WrappedCheerioElement;
15
+ svg: SVG;
16
+ parents: ParseSVGCallbackItem[];
17
+ testChildren: boolean;
18
+ removeNode: boolean;
19
+ }
20
+ /**
21
+ * Callback function
22
+ */
23
+ export declare type ParseSVGCallback = (item: ParseSVGCallbackItem) => void | Promise<void>;
24
+ /**
25
+ * Parse SVG
26
+ *
27
+ * This function finds all elements in SVG and calls callback for each element.
28
+ * Callback can be asynchronous.
29
+ */
30
+ export declare function parseSVG(svg: SVG, callback: ParseSVGCallback): Promise<void>;