@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,88 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runSVGO = exports.shapeModifiyingSVGOPlugins = exports.defaultSVGOPlugins = void 0;
4
+ const svgo_1 = require("svgo");
5
+ exports.defaultSVGOPlugins = [
6
+ 'cleanupAttrs',
7
+ 'mergeStyles',
8
+ 'inlineStyles',
9
+ 'removeComments',
10
+ 'removeUselessDefs',
11
+ 'removeEditorsNSData',
12
+ 'removeEmptyAttrs',
13
+ 'removeEmptyContainers',
14
+ 'convertStyleToAttrs',
15
+ 'convertColors',
16
+ 'convertTransform',
17
+ 'removeUnknownsAndDefaults',
18
+ 'removeNonInheritableGroupAttrs',
19
+ 'removeUselessStrokeAndFill',
20
+ 'removeUnusedNS',
21
+ 'cleanupNumericValues',
22
+ 'cleanupListOfValues',
23
+ 'moveElemsAttrsToGroup',
24
+ 'moveGroupAttrsToElems',
25
+ 'collapseGroups',
26
+ 'sortDefsChildren',
27
+ 'sortAttrs',
28
+ ];
29
+ /**
30
+ * Plugins that modify shapes. Added to plugins list, unless 'keepShapes' option is enabled
31
+ */
32
+ exports.shapeModifiyingSVGOPlugins = [
33
+ 'removeHiddenElems',
34
+ 'convertShapeToPath',
35
+ 'convertEllipseToCircle',
36
+ {
37
+ name: 'convertPathData',
38
+ params: {
39
+ noSpaceAfterFlags: true,
40
+ },
41
+ },
42
+ {
43
+ name: 'mergePaths',
44
+ params: {
45
+ noSpaceAfterFlags: true,
46
+ },
47
+ },
48
+ 'removeOffCanvasPaths',
49
+ 'reusePaths',
50
+ ];
51
+ /**
52
+ * Run SVGO on icon
53
+ */
54
+ async function runSVGO(svg, options = {}) {
55
+ // Options
56
+ const multipass = options.multipass !== false;
57
+ // Plugins list
58
+ let plugins;
59
+ if (options.plugins) {
60
+ plugins = options.plugins;
61
+ }
62
+ else {
63
+ plugins = exports.defaultSVGOPlugins.concat(options.keepShapes ? [] : exports.shapeModifiyingSVGOPlugins, options.cleanupIDs !== false
64
+ ? [
65
+ {
66
+ name: 'cleanupIDs',
67
+ params: {
68
+ prefix: typeof options.cleanupIDs === 'string'
69
+ ? options.cleanupIDs
70
+ : 'svg-',
71
+ },
72
+ },
73
+ ]
74
+ : []);
75
+ }
76
+ // Run SVGO
77
+ const pluginOptions = {
78
+ plugins,
79
+ multipass,
80
+ };
81
+ // Load data (changing type because SVGO types do not include error ?????)
82
+ const result = (0, svgo_1.optimize)(svg.toString(), pluginOptions);
83
+ if (typeof result.error === 'string') {
84
+ throw new Error(result.error);
85
+ }
86
+ svg.load(result.data);
87
+ }
88
+ exports.runSVGO = runSVGO;
@@ -0,0 +1,75 @@
1
+ // src/optimise/svgo.ts
2
+ import { optimize } from "svgo";
3
+ var defaultSVGOPlugins = [
4
+ "cleanupAttrs",
5
+ "mergeStyles",
6
+ "inlineStyles",
7
+ "removeComments",
8
+ "removeUselessDefs",
9
+ "removeEditorsNSData",
10
+ "removeEmptyAttrs",
11
+ "removeEmptyContainers",
12
+ "convertStyleToAttrs",
13
+ "convertColors",
14
+ "convertTransform",
15
+ "removeUnknownsAndDefaults",
16
+ "removeNonInheritableGroupAttrs",
17
+ "removeUselessStrokeAndFill",
18
+ "removeUnusedNS",
19
+ "cleanupNumericValues",
20
+ "cleanupListOfValues",
21
+ "moveElemsAttrsToGroup",
22
+ "moveGroupAttrsToElems",
23
+ "collapseGroups",
24
+ "sortDefsChildren",
25
+ "sortAttrs"
26
+ ];
27
+ var shapeModifiyingSVGOPlugins = [
28
+ "removeHiddenElems",
29
+ "convertShapeToPath",
30
+ "convertEllipseToCircle",
31
+ {
32
+ name: "convertPathData",
33
+ params: {
34
+ noSpaceAfterFlags: true
35
+ }
36
+ },
37
+ {
38
+ name: "mergePaths",
39
+ params: {
40
+ noSpaceAfterFlags: true
41
+ }
42
+ },
43
+ "removeOffCanvasPaths",
44
+ "reusePaths"
45
+ ];
46
+ async function runSVGO(svg, options = {}) {
47
+ const multipass = options.multipass !== false;
48
+ let plugins;
49
+ if (options.plugins) {
50
+ plugins = options.plugins;
51
+ } else {
52
+ plugins = defaultSVGOPlugins.concat(options.keepShapes ? [] : shapeModifiyingSVGOPlugins, options.cleanupIDs !== false ? [
53
+ {
54
+ name: "cleanupIDs",
55
+ params: {
56
+ prefix: typeof options.cleanupIDs === "string" ? options.cleanupIDs : "svg-"
57
+ }
58
+ }
59
+ ] : []);
60
+ }
61
+ const pluginOptions = {
62
+ plugins,
63
+ multipass
64
+ };
65
+ const result = optimize(svg.toString(), pluginOptions);
66
+ if (typeof result.error === "string") {
67
+ throw new Error(result.error);
68
+ }
69
+ svg.load(result.data);
70
+ }
71
+ export {
72
+ defaultSVGOPlugins,
73
+ runSVGO,
74
+ shapeModifiyingSVGOPlugins
75
+ };
@@ -0,0 +1,5 @@
1
+ import type { SVG } from '..';
2
+ /**
3
+ * Remove useless attributes
4
+ */
5
+ export declare function removeBadAttributes(svg: SVG): Promise<void>;
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.removeBadAttributes = void 0;
4
+ const attributes_1 = require("../data/attributes");
5
+ const parse_1 = require("../parse");
6
+ /**
7
+ * Remove useless attributes
8
+ */
9
+ async function removeBadAttributes(svg) {
10
+ await (0, parse_1.parseSVG)(svg, (item) => {
11
+ const attribs = item.element.attribs;
12
+ const $element = item.$element;
13
+ // Common tags
14
+ Object.keys(attribs).forEach((attr) => {
15
+ // Bad attributes, events
16
+ if (attr.slice(0, 2) === 'on' ||
17
+ attributes_1.badAttributes.has(attr) ||
18
+ attributes_1.badSoftwareAttributes.has(attr) ||
19
+ attributes_1.badAttributePrefixes.has(attr.split('-').shift())) {
20
+ $element.removeAttr(attr);
21
+ return;
22
+ }
23
+ // Check for namespace
24
+ const nsParts = attr.split(':');
25
+ if (nsParts.length > 1) {
26
+ const namespace = nsParts.shift();
27
+ const newAttr = nsParts.join(':');
28
+ switch (namespace) {
29
+ case 'xlink': {
30
+ // Deprecated: use without namespace
31
+ if (attribs[newAttr] === void 0) {
32
+ $element.attr(newAttr, attribs[attr]);
33
+ }
34
+ break;
35
+ }
36
+ }
37
+ // Remove all namespace attributes
38
+ $element.removeAttr(attr);
39
+ }
40
+ });
41
+ });
42
+ }
43
+ exports.removeBadAttributes = removeBadAttributes;
@@ -0,0 +1,36 @@
1
+ // src/svg/cleanup/attribs.ts
2
+ import {
3
+ badAttributes,
4
+ badAttributePrefixes,
5
+ badSoftwareAttributes
6
+ } from "../data/attributes.mjs";
7
+ import { parseSVG } from "../parse.mjs";
8
+ async function removeBadAttributes(svg) {
9
+ await parseSVG(svg, (item) => {
10
+ const attribs = item.element.attribs;
11
+ const $element = item.$element;
12
+ Object.keys(attribs).forEach((attr) => {
13
+ if (attr.slice(0, 2) === "on" || badAttributes.has(attr) || badSoftwareAttributes.has(attr) || badAttributePrefixes.has(attr.split("-").shift())) {
14
+ $element.removeAttr(attr);
15
+ return;
16
+ }
17
+ const nsParts = attr.split(":");
18
+ if (nsParts.length > 1) {
19
+ const namespace = nsParts.shift();
20
+ const newAttr = nsParts.join(":");
21
+ switch (namespace) {
22
+ case "xlink": {
23
+ if (attribs[newAttr] === void 0) {
24
+ $element.attr(newAttr, attribs[attr]);
25
+ }
26
+ break;
27
+ }
28
+ }
29
+ $element.removeAttr(attr);
30
+ }
31
+ });
32
+ });
33
+ }
34
+ export {
35
+ removeBadAttributes
36
+ };
@@ -0,0 +1,5 @@
1
+ import type { SVG } from '..';
2
+ /**
3
+ * Test for bag tags
4
+ */
5
+ export declare function checkBadTags(svg: SVG): Promise<void>;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.checkBadTags = void 0;
4
+ const parse_1 = require("../parse");
5
+ const tags_1 = require("../data/tags");
6
+ // List of required parent tags
7
+ const requiredParentTags = new Map();
8
+ // <feFunc*> must be children of <feComponentTransfer>
9
+ requiredParentTags.set(new Set(['feComponentTransfer']), tags_1.feComponentTransferChildTag);
10
+ // <feMergeNode> must be children of <feMerge>
11
+ requiredParentTags.set(new Set(['feMerge']), tags_1.feMergeChildTags);
12
+ // Children of <fe*Lightning>
13
+ requiredParentTags.set(tags_1.feLightningTags, tags_1.feLightningChildTags);
14
+ // Filter tags must be children of <filter>
15
+ requiredParentTags.set(tags_1.filterTag, tags_1.filterChildTags);
16
+ // Tags that must be inside <defs>: gradients, <pattern>, <marker>
17
+ requiredParentTags.set(tags_1.defsTag, tags_1.tagsInsideDefs);
18
+ // <stop> must be inside gradient
19
+ requiredParentTags.set(tags_1.gradientTags, tags_1.gradientChildTags);
20
+ // Animations must be inside shapes or filters
21
+ requiredParentTags.set(tags_1.tagsBeforeAnimation, tags_1.animateTags);
22
+ // <mpath> must be inside <animateMotion>
23
+ requiredParentTags.set(new Set(['animateMotion']), tags_1.animateMotionChildTags);
24
+ /**
25
+ * Test for bag tags
26
+ */
27
+ async function checkBadTags(svg) {
28
+ await (0, parse_1.parseSVG)(svg, (item) => {
29
+ var _a;
30
+ const tagName = item.tagName;
31
+ const $element = item.$element;
32
+ // SVG as root
33
+ if (tagName === 'svg') {
34
+ if (item.parents.length) {
35
+ // Technically code is correct, but it badly complicates parsing, so not supported
36
+ throw new Error(`Unexpected element: <${tagName}>`);
37
+ }
38
+ return;
39
+ }
40
+ // Unsupported: quietly remove it
41
+ if (tags_1.unsupportedTags.has(tagName)) {
42
+ $element.remove();
43
+ item.testChildren = false;
44
+ return;
45
+ }
46
+ // Bad or unknown element
47
+ if (tags_1.badTags.has(tagName) || !tags_1.allValidTags.has(tagName)) {
48
+ const parts = tagName.split(':');
49
+ if (parts.length > 1) {
50
+ // Custom tag, most likely Inkscape junk
51
+ $element.remove();
52
+ item.testChildren = false;
53
+ return;
54
+ }
55
+ throw new Error(`Unexpected element: <${tagName}>`);
56
+ }
57
+ // Check for valid parent tag
58
+ const parentTagName = (_a = item.parents[0]) === null || _a === void 0 ? void 0 : _a.tagName;
59
+ for (const [parents, children] of requiredParentTags) {
60
+ if (children.has(tagName)) {
61
+ if (!parents.has(parentTagName)) {
62
+ throw new Error(`Element <${tagName}> has wrong parent element`);
63
+ }
64
+ return;
65
+ }
66
+ }
67
+ });
68
+ }
69
+ exports.checkBadTags = checkBadTags;
@@ -0,0 +1,68 @@
1
+ // src/svg/cleanup/bad-tags.ts
2
+ import { parseSVG } from "../parse.mjs";
3
+ import {
4
+ allValidTags,
5
+ animateMotionChildTags,
6
+ animateTags,
7
+ badTags,
8
+ defsTag,
9
+ feComponentTransferChildTag,
10
+ feLightningChildTags,
11
+ feLightningTags,
12
+ feMergeChildTags,
13
+ filterChildTags,
14
+ filterTag,
15
+ gradientChildTags,
16
+ gradientTags,
17
+ tagsBeforeAnimation,
18
+ tagsInsideDefs,
19
+ unsupportedTags
20
+ } from "../data/tags.mjs";
21
+ var requiredParentTags = new Map();
22
+ requiredParentTags.set(new Set(["feComponentTransfer"]), feComponentTransferChildTag);
23
+ requiredParentTags.set(new Set(["feMerge"]), feMergeChildTags);
24
+ requiredParentTags.set(feLightningTags, feLightningChildTags);
25
+ requiredParentTags.set(filterTag, filterChildTags);
26
+ requiredParentTags.set(defsTag, tagsInsideDefs);
27
+ requiredParentTags.set(gradientTags, gradientChildTags);
28
+ requiredParentTags.set(tagsBeforeAnimation, animateTags);
29
+ requiredParentTags.set(new Set(["animateMotion"]), animateMotionChildTags);
30
+ async function checkBadTags(svg) {
31
+ await parseSVG(svg, (item) => {
32
+ var _a;
33
+ const tagName = item.tagName;
34
+ const $element = item.$element;
35
+ if (tagName === "svg") {
36
+ if (item.parents.length) {
37
+ throw new Error(`Unexpected element: <${tagName}>`);
38
+ }
39
+ return;
40
+ }
41
+ if (unsupportedTags.has(tagName)) {
42
+ $element.remove();
43
+ item.testChildren = false;
44
+ return;
45
+ }
46
+ if (badTags.has(tagName) || !allValidTags.has(tagName)) {
47
+ const parts = tagName.split(":");
48
+ if (parts.length > 1) {
49
+ $element.remove();
50
+ item.testChildren = false;
51
+ return;
52
+ }
53
+ throw new Error(`Unexpected element: <${tagName}>`);
54
+ }
55
+ const parentTagName = (_a = item.parents[0]) == null ? void 0 : _a.tagName;
56
+ for (const [parents, children] of requiredParentTags) {
57
+ if (children.has(tagName)) {
58
+ if (!parents.has(parentTagName)) {
59
+ throw new Error(`Element <${tagName}> has wrong parent element`);
60
+ }
61
+ return;
62
+ }
63
+ }
64
+ });
65
+ }
66
+ export {
67
+ checkBadTags
68
+ };
@@ -0,0 +1,5 @@
1
+ import type { SVG } from '..';
2
+ /**
3
+ * Expand inline style
4
+ */
5
+ export declare function cleanupInlineStyle(svg: SVG): Promise<void>;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cleanupInlineStyle = void 0;
4
+ const parse_1 = require("../../css/parse");
5
+ const attributes_1 = require("../data/attributes");
6
+ const parse_2 = require("../parse");
7
+ /**
8
+ * Expand inline style
9
+ */
10
+ async function cleanupInlineStyle(svg) {
11
+ await (0, parse_2.parseSVG)(svg, (item) => {
12
+ const $element = item.$element;
13
+ const attribs = item.element.attribs;
14
+ const tagName = item.tagName;
15
+ // Expand style
16
+ if (attribs.style) {
17
+ const parsedStyle = (0, parse_1.parseInlineStyle)(attribs.style);
18
+ if (parsedStyle === null) {
19
+ // Ignore style
20
+ $element.removeAttr('style');
21
+ }
22
+ else {
23
+ const newStyle = Object.create(null);
24
+ const checkRule = (prop, value) => {
25
+ var _a, _b, _c;
26
+ function warn() {
27
+ console.warn(`Removing unexpected style on "${tagName}": ${prop}`);
28
+ }
29
+ // Check for bad attributes that should be removed
30
+ if (attributes_1.badAttributes.has(prop) ||
31
+ ((_a = attributes_1.tagSpecificNonPresentationalAttributes[tagName]) === null || _a === void 0 ? void 0 : _a.has(prop))) {
32
+ return;
33
+ }
34
+ // Valid attributes
35
+ if (((_b = attributes_1.tagSpecificAnimatedAttributes[tagName]) === null || _b === void 0 ? void 0 : _b.has(prop)) ||
36
+ ((_c = attributes_1.tagSpecificPresentationalAttributes[tagName]) === null || _c === void 0 ? void 0 : _c.has(prop))) {
37
+ $element.attr(prop, value);
38
+ return;
39
+ }
40
+ // Attributes inside <clipPath>
41
+ if (attributes_1.insideClipPathAttributes.has(prop)) {
42
+ if (item.parents.find((item) => item.tagName === 'clipPath')) {
43
+ $element.attr(prop, value);
44
+ }
45
+ return;
46
+ }
47
+ // Bad software stuff
48
+ if (attributes_1.badSoftwareAttributes.has(prop) ||
49
+ attributes_1.badAttributePrefixes.has(prop.split('-').shift())) {
50
+ return;
51
+ }
52
+ // Vendor specific junk
53
+ if (prop.slice(0, 1) === '-') {
54
+ return;
55
+ }
56
+ // Unknown
57
+ warn();
58
+ };
59
+ // Check all properties
60
+ for (const prop in parsedStyle) {
61
+ checkRule(prop, parsedStyle[prop]);
62
+ }
63
+ // Update style
64
+ const newStyleStr = Object.keys(newStyle)
65
+ .map((key) => key + ':' + newStyle[key] + ';')
66
+ .join('');
67
+ if (newStyleStr.length) {
68
+ $element.attr('style', newStyleStr);
69
+ }
70
+ else {
71
+ $element.removeAttr('style');
72
+ }
73
+ }
74
+ }
75
+ });
76
+ }
77
+ exports.cleanupInlineStyle = cleanupInlineStyle;
@@ -0,0 +1,65 @@
1
+ // src/svg/cleanup/inline-style.ts
2
+ import { parseInlineStyle } from "../../css/parse.mjs";
3
+ import {
4
+ badAttributes,
5
+ badAttributePrefixes,
6
+ badSoftwareAttributes,
7
+ insideClipPathAttributes,
8
+ tagSpecificAnimatedAttributes,
9
+ tagSpecificNonPresentationalAttributes,
10
+ tagSpecificPresentationalAttributes
11
+ } from "../data/attributes.mjs";
12
+ import { parseSVG } from "../parse.mjs";
13
+ async function cleanupInlineStyle(svg) {
14
+ await parseSVG(svg, (item) => {
15
+ const $element = item.$element;
16
+ const attribs = item.element.attribs;
17
+ const tagName = item.tagName;
18
+ if (attribs.style) {
19
+ const parsedStyle = parseInlineStyle(attribs.style);
20
+ if (parsedStyle === null) {
21
+ $element.removeAttr("style");
22
+ } else {
23
+ const newStyle = Object.create(null);
24
+ const checkRule = (prop, value) => {
25
+ var _a, _b, _c;
26
+ function warn() {
27
+ console.warn(`Removing unexpected style on "${tagName}": ${prop}`);
28
+ }
29
+ if (badAttributes.has(prop) || ((_a = tagSpecificNonPresentationalAttributes[tagName]) == null ? void 0 : _a.has(prop))) {
30
+ return;
31
+ }
32
+ if (((_b = tagSpecificAnimatedAttributes[tagName]) == null ? void 0 : _b.has(prop)) || ((_c = tagSpecificPresentationalAttributes[tagName]) == null ? void 0 : _c.has(prop))) {
33
+ $element.attr(prop, value);
34
+ return;
35
+ }
36
+ if (insideClipPathAttributes.has(prop)) {
37
+ if (item.parents.find((item2) => item2.tagName === "clipPath")) {
38
+ $element.attr(prop, value);
39
+ }
40
+ return;
41
+ }
42
+ if (badSoftwareAttributes.has(prop) || badAttributePrefixes.has(prop.split("-").shift())) {
43
+ return;
44
+ }
45
+ if (prop.slice(0, 1) === "-") {
46
+ return;
47
+ }
48
+ warn();
49
+ };
50
+ for (const prop in parsedStyle) {
51
+ checkRule(prop, parsedStyle[prop]);
52
+ }
53
+ const newStyleStr = Object.keys(newStyle).map((key) => key + ":" + newStyle[key] + ";").join("");
54
+ if (newStyleStr.length) {
55
+ $element.attr("style", newStyleStr);
56
+ } else {
57
+ $element.removeAttr("style");
58
+ }
59
+ }
60
+ }
61
+ });
62
+ }
63
+ export {
64
+ cleanupInlineStyle
65
+ };
@@ -0,0 +1,5 @@
1
+ import type { SVG } from '..';
2
+ /**
3
+ * Clean up SVG
4
+ */
5
+ export declare function cleanupSVGRoot(svg: SVG): Promise<void>;
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cleanupSVGRoot = void 0;
4
+ const attributes_1 = require("../data/attributes");
5
+ const tags_1 = require("../data/tags");
6
+ /**
7
+ * Clean up SVG
8
+ */
9
+ async function cleanupSVGRoot(svg) {
10
+ const cheerio = svg.$svg;
11
+ const $root = svg.$svg(':root');
12
+ const root = $root.get(0);
13
+ const tagName = 'svg';
14
+ if (root.tagName !== tagName) {
15
+ throw new Error(`Unexpected root tag <${root.tagName}>`);
16
+ }
17
+ const attribs = root.attribs;
18
+ // Check attributes
19
+ const moveToChildren = {};
20
+ Object.keys(attribs).forEach((attr) => {
21
+ var _a, _b;
22
+ const value = attribs[attr];
23
+ // Bad attributes, irrelevant common attributes, namespaces
24
+ if (attributes_1.commonAttributes.has(attr) ||
25
+ attributes_1.badAttributes.has(attr) ||
26
+ attributes_1.junkSVGAttributes.has(attr) ||
27
+ attributes_1.badSoftwareAttributes.has(attr) ||
28
+ attributes_1.badAttributePrefixes.has(attr.split('-').shift()) ||
29
+ attr.split(':').length > 1) {
30
+ $root.removeAttr(attr);
31
+ return;
32
+ }
33
+ // Special handling for dimensions
34
+ switch (attr) {
35
+ case 'width':
36
+ case 'height':
37
+ // Cleanup dimensions
38
+ if (value.slice(-2) === 'px') {
39
+ // Remove 'px'
40
+ const num = value.replace('px', '');
41
+ if (parseFloat(num) + '' === num) {
42
+ $root.attr(attr, num);
43
+ }
44
+ }
45
+ return;
46
+ }
47
+ // Attributes that belong to <svg>
48
+ if ((_a = attributes_1.tagSpecificNonPresentationalAttributes[tagName]) === null || _a === void 0 ? void 0 : _a.has(attr)) {
49
+ return;
50
+ }
51
+ // Presentational attributes: move to child elements
52
+ if (((_b = attributes_1.tagSpecificPresentationalAttributes[tagName]) === null || _b === void 0 ? void 0 : _b.has(attr)) &&
53
+ attributes_1.tagSpecificPresentationalAttributes.g.has(attr)) {
54
+ moveToChildren[attr] = value;
55
+ $root.removeAttr(attr);
56
+ return;
57
+ }
58
+ // Styling: 'style' should be checked by expandInlineStyle(), remove others
59
+ if (attributes_1.stylingAttributes.has(attr)) {
60
+ switch (attr) {
61
+ case 'style':
62
+ return;
63
+ case 'class':
64
+ $root.removeAttr(attr);
65
+ return;
66
+ }
67
+ throw new Error(`Unexpected attribute "${attr}" on <${tagName}>`);
68
+ }
69
+ // Junk from bad editors, mostly Adobe Illustrator and Inkscape
70
+ if (
71
+ // Events
72
+ attr.slice(0, 2) === 'on' ||
73
+ // aria-stuff
74
+ attr.slice(0, 5) === 'aria-' ||
75
+ // Junk
76
+ attr.slice(0, 6) === 'xmlns:') {
77
+ $root.removeAttr(attr);
78
+ return;
79
+ }
80
+ console.log(`Removing unexpected attribute on SVG: ${attr}`);
81
+ $root.removeAttr(attr);
82
+ });
83
+ if (Object.keys(moveToChildren).length) {
84
+ // Wrap child elements
85
+ const $wrapper = cheerio('<g />');
86
+ for (const key in moveToChildren) {
87
+ $wrapper.attr(key, moveToChildren[key]);
88
+ }
89
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars-experimental
90
+ $root.children().each((index, child) => {
91
+ const $child = cheerio(child);
92
+ if (child.type !== 'tag') {
93
+ $child.appendTo($wrapper);
94
+ return;
95
+ }
96
+ const tagName = child.tagName;
97
+ if (tagName === 'style' || tags_1.maskAndSymbolTags.has(tagName)) {
98
+ // Do not wrap these elements
99
+ return;
100
+ }
101
+ $child.appendTo($wrapper);
102
+ });
103
+ $wrapper.appendTo($root);
104
+ }
105
+ }
106
+ exports.cleanupSVGRoot = cleanupSVGRoot;