@iconify/tools 2.0.9 → 2.0.13

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 (59) hide show
  1. package/lib/colors/parse.d.ts +19 -3
  2. package/lib/colors/parse.js +109 -40
  3. package/lib/colors/parse.mjs +86 -39
  4. package/lib/colors/validate.js +5 -2
  5. package/lib/colors/validate.mjs +3 -1
  6. package/lib/download/git/index.js +12 -0
  7. package/lib/download/git/index.mjs +7 -0
  8. package/lib/download/git/reset.d.ts +4 -0
  9. package/lib/download/git/reset.js +16 -0
  10. package/lib/download/git/reset.mjs +13 -0
  11. package/lib/export/json-package.js +6 -1
  12. package/lib/export/json-package.mjs +4 -1
  13. package/lib/icon-set/index.js +11 -25
  14. package/lib/icon-set/index.mjs +13 -25
  15. package/lib/icon-set/merge.js +0 -1
  16. package/lib/icon-set/merge.mjs +1 -2
  17. package/lib/icon-set/props.d.ts +1 -1
  18. package/lib/icon-set/props.js +3 -2
  19. package/lib/icon-set/props.mjs +2 -2
  20. package/lib/icon-set/types.d.ts +3 -1
  21. package/lib/import/figma/nodes.js +3 -5
  22. package/lib/import/figma/nodes.mjs +3 -5
  23. package/lib/index.d.ts +3 -0
  24. package/lib/index.js +7 -1
  25. package/lib/index.mjs +6 -0
  26. package/lib/optimise/flags.js +9 -0
  27. package/lib/optimise/flags.mjs +8 -0
  28. package/lib/optimise/global-style.d.ts +5 -0
  29. package/lib/optimise/global-style.js +158 -0
  30. package/lib/optimise/global-style.mjs +129 -0
  31. package/lib/svg/analyse/error.d.ts +5 -0
  32. package/lib/svg/analyse/error.js +22 -0
  33. package/lib/svg/analyse/error.mjs +16 -0
  34. package/lib/svg/analyse/types.d.ts +89 -0
  35. package/lib/svg/analyse/types.js +2 -0
  36. package/lib/svg/analyse/types.mjs +0 -0
  37. package/lib/svg/analyse.d.ts +8 -0
  38. package/lib/svg/analyse.js +352 -0
  39. package/lib/svg/analyse.mjs +302 -0
  40. package/lib/svg/cleanup/attribs.d.ts +1 -1
  41. package/lib/svg/cleanup/attribs.js +8 -0
  42. package/lib/svg/cleanup/attribs.mjs +8 -1
  43. package/lib/svg/cleanup/bad-tags.d.ts +1 -1
  44. package/lib/svg/cleanup/bad-tags.js +0 -2
  45. package/lib/svg/cleanup/bad-tags.mjs +0 -3
  46. package/lib/svg/cleanup/inline-style.d.ts +1 -1
  47. package/lib/svg/cleanup/root-svg.d.ts +1 -1
  48. package/lib/svg/cleanup/root-svg.js +4 -2
  49. package/lib/svg/cleanup/root-svg.mjs +3 -3
  50. package/lib/svg/cleanup/svgo-style.d.ts +1 -1
  51. package/lib/svg/data/attributes.js +1 -1
  52. package/lib/svg/data/attributes.mjs +1 -1
  53. package/lib/svg/data/tags.d.ts +15 -7
  54. package/lib/svg/data/tags.js +20 -9
  55. package/lib/svg/data/tags.mjs +11 -6
  56. package/lib/svg/parse-style.d.ts +7 -7
  57. package/lib/svg/parse-style.js +27 -7
  58. package/lib/svg/parse-style.mjs +26 -7
  59. package/package.json +22 -2
@@ -42,7 +42,7 @@ class IconSet {
42
42
  load(data) {
43
43
  this.prefix = data.prefix;
44
44
  // Defaults
45
- const defaultProps = (0, props_1.filterProps)(data);
45
+ const defaultProps = (0, props_1.filterProps)(data, true);
46
46
  // Add icons
47
47
  this.entries = Object.create(null);
48
48
  const entries = this.entries;
@@ -51,7 +51,10 @@ class IconSet {
51
51
  const entry = {
52
52
  type: 'icon',
53
53
  body: item.body,
54
- props: { ...defaultProps, ...(0, props_1.filterProps)(item) },
54
+ props: (0, props_1.filterProps)({
55
+ ...defaultProps,
56
+ ...item,
57
+ }, true),
55
58
  chars: new Set(),
56
59
  categories: new Set(),
57
60
  };
@@ -62,7 +65,7 @@ class IconSet {
62
65
  for (const name in data.aliases) {
63
66
  const item = data.aliases[name];
64
67
  const parent = item.parent;
65
- const props = (0, props_1.filterProps)(item);
68
+ const props = (0, props_1.filterProps)(item, false);
66
69
  const chars = new Set();
67
70
  if (Object.keys(props).length) {
68
71
  // Variation
@@ -71,7 +74,6 @@ class IconSet {
71
74
  parent,
72
75
  props,
73
76
  chars,
74
- categories: new Set(),
75
77
  };
76
78
  entries[name] = entry;
77
79
  }
@@ -111,7 +113,6 @@ class IconSet {
111
113
  const icon = entries[iconName];
112
114
  switch (icon === null || icon === void 0 ? void 0 : icon.type) {
113
115
  case 'icon':
114
- case 'variation':
115
116
  icon.categories.add(item);
116
117
  }
117
118
  });
@@ -342,6 +343,7 @@ class IconSet {
342
343
  .forEach((item) => {
343
344
  const names = this.listCategory(item);
344
345
  if (names) {
346
+ names.sort((a, b) => a.localeCompare(b));
345
347
  categories[item.title] = names;
346
348
  }
347
349
  });
@@ -460,8 +462,8 @@ class IconSet {
460
462
  return null;
461
463
  }
462
464
  // Find icons
463
- const icons = this._filter((_key, item, icon) => {
464
- if (item.type === 'alias' || item.props.hidden || (icon === null || icon === void 0 ? void 0 : icon.hidden)) {
465
+ const icons = this._filter((_key, item) => {
466
+ if (item.type !== 'icon' || item.props.hidden) {
465
467
  return false;
466
468
  }
467
469
  return item.categories.has(categoryItem);
@@ -600,7 +602,7 @@ class IconSet {
600
602
  return this.setItem(name, {
601
603
  type: 'icon',
602
604
  body: icon.body,
603
- props: (0, props_1.filterProps)(icon),
605
+ props: (0, props_1.filterProps)(icon, true),
604
606
  chars: new Set(),
605
607
  categories: new Set(),
606
608
  });
@@ -619,26 +621,11 @@ class IconSet {
619
621
  * Add/update alias with props
620
622
  */
621
623
  setVariation(name, parent, props) {
622
- // Copy categories
623
- let categories;
624
- while (!categories) {
625
- const parentItem = this.entries[parent];
626
- if (!parentItem) {
627
- return false;
628
- }
629
- if (parentItem.type === 'alias') {
630
- parent = parentItem.parent;
631
- }
632
- else {
633
- categories = new Set(parentItem.categories);
634
- }
635
- }
636
624
  return this.setItem(name, {
637
625
  type: 'variation',
638
626
  parent,
639
627
  props,
640
628
  chars: new Set(),
641
- categories,
642
629
  });
643
630
  }
644
631
  /**
@@ -664,7 +651,7 @@ class IconSet {
664
651
  body,
665
652
  props,
666
653
  chars: item.chars,
667
- categories: item.categories,
654
+ categories: item.type === 'icon' ? item.categories : new Set(),
668
655
  });
669
656
  }
670
657
  }
@@ -699,7 +686,6 @@ class IconSet {
699
686
  }
700
687
  switch (item.type) {
701
688
  case 'icon':
702
- case 'variation':
703
689
  if (item.categories.has(categoryItem) !== add) {
704
690
  categoryItem.count += add ? 1 : -1;
705
691
  item.categories[add ? 'add' : 'delete'](categoryItem);
@@ -21,7 +21,7 @@ var IconSet = class {
21
21
  }
22
22
  load(data) {
23
23
  this.prefix = data.prefix;
24
- const defaultProps = filterProps(data);
24
+ const defaultProps = filterProps(data, true);
25
25
  this.entries = Object.create(null);
26
26
  const entries = this.entries;
27
27
  for (const name in data.icons) {
@@ -29,7 +29,10 @@ var IconSet = class {
29
29
  const entry = {
30
30
  type: "icon",
31
31
  body: item.body,
32
- props: { ...defaultProps, ...filterProps(item) },
32
+ props: filterProps({
33
+ ...defaultProps,
34
+ ...item
35
+ }, true),
33
36
  chars: new Set(),
34
37
  categories: new Set()
35
38
  };
@@ -39,15 +42,14 @@ var IconSet = class {
39
42
  for (const name in data.aliases) {
40
43
  const item = data.aliases[name];
41
44
  const parent = item.parent;
42
- const props = filterProps(item);
45
+ const props = filterProps(item, false);
43
46
  const chars = new Set();
44
47
  if (Object.keys(props).length) {
45
48
  const entry = {
46
49
  type: "variation",
47
50
  parent,
48
51
  props,
49
- chars,
50
- categories: new Set()
52
+ chars
51
53
  };
52
54
  entries[name] = entry;
53
55
  } else {
@@ -82,7 +84,6 @@ var IconSet = class {
82
84
  const icon = entries[iconName];
83
85
  switch (icon == null ? void 0 : icon.type) {
84
86
  case "icon":
85
- case "variation":
86
87
  icon.categories.add(item);
87
88
  }
88
89
  });
@@ -271,6 +272,7 @@ var IconSet = class {
271
272
  Array.from(this.categories).sort((a, b) => a.title.localeCompare(b.title)).forEach((item) => {
272
273
  const names2 = this.listCategory(item);
273
274
  if (names2) {
275
+ names2.sort((a, b) => a.localeCompare(b));
274
276
  categories[item.title] = names2;
275
277
  }
276
278
  });
@@ -362,8 +364,8 @@ var IconSet = class {
362
364
  if (!categoryItem) {
363
365
  return null;
364
366
  }
365
- const icons = this._filter((_key, item, icon) => {
366
- if (item.type === "alias" || item.props.hidden || (icon == null ? void 0 : icon.hidden)) {
367
+ const icons = this._filter((_key, item) => {
368
+ if (item.type !== "icon" || item.props.hidden) {
367
369
  return false;
368
370
  }
369
371
  return item.categories.has(categoryItem);
@@ -474,7 +476,7 @@ var IconSet = class {
474
476
  return this.setItem(name, {
475
477
  type: "icon",
476
478
  body: icon.body,
477
- props: filterProps(icon),
479
+ props: filterProps(icon, true),
478
480
  chars: new Set(),
479
481
  categories: new Set()
480
482
  });
@@ -487,24 +489,11 @@ var IconSet = class {
487
489
  });
488
490
  }
489
491
  setVariation(name, parent, props) {
490
- let categories;
491
- while (!categories) {
492
- const parentItem = this.entries[parent];
493
- if (!parentItem) {
494
- return false;
495
- }
496
- if (parentItem.type === "alias") {
497
- parent = parentItem.parent;
498
- } else {
499
- categories = new Set(parentItem.categories);
500
- }
501
- }
502
492
  return this.setItem(name, {
503
493
  type: "variation",
504
494
  parent,
505
495
  props,
506
- chars: new Set(),
507
- categories
496
+ chars: new Set()
508
497
  });
509
498
  }
510
499
  fromSVG(name, svg) {
@@ -525,7 +514,7 @@ var IconSet = class {
525
514
  body,
526
515
  props,
527
516
  chars: item.chars,
528
- categories: item.categories
517
+ categories: item.type === "icon" ? item.categories : new Set()
529
518
  });
530
519
  }
531
520
  }
@@ -553,7 +542,6 @@ var IconSet = class {
553
542
  }
554
543
  switch (item.type) {
555
544
  case "icon":
556
- case "variation":
557
545
  if (item.categories.has(categoryItem) !== add) {
558
546
  categoryItem.count += add ? 1 : -1;
559
547
  item.categories[add ? "add" : "delete"](categoryItem);
@@ -66,7 +66,6 @@ function mergeIconSets(oldIcons, newIcons) {
66
66
  ...props,
67
67
  hidden: true,
68
68
  },
69
- categories: new Set(),
70
69
  });
71
70
  }
72
71
  else {
@@ -49,8 +49,7 @@ function mergeIconSets(oldIcons, newIcons) {
49
49
  props: {
50
50
  ...props,
51
51
  hidden: true
52
- },
53
- categories: new Set()
52
+ }
54
53
  });
55
54
  } else {
56
55
  mergedIcons.setItem(name, {
@@ -7,4 +7,4 @@ export declare const defaultCommonProps: Required<CommonIconProps>;
7
7
  /**
8
8
  * Filter icon props: copies properties, removing undefined and default entries
9
9
  */
10
- export declare function filterProps(data: CommonIconProps): CommonIconProps;
10
+ export declare function filterProps(data: CommonIconProps, compareDefaultValues: boolean): CommonIconProps;
@@ -19,12 +19,13 @@ const props = Object.keys(exports.defaultCommonProps);
19
19
  /**
20
20
  * Filter icon props: copies properties, removing undefined and default entries
21
21
  */
22
- function filterProps(data) {
22
+ function filterProps(data, compareDefaultValues) {
23
23
  const result = {};
24
24
  props.forEach((attr) => {
25
25
  const value = data[attr];
26
26
  if (value !== void 0 &&
27
- value !== exports.defaultCommonProps[attr]) {
27
+ (!compareDefaultValues ||
28
+ value !== exports.defaultCommonProps[attr])) {
28
29
  result[attr] = value;
29
30
  }
30
31
  });
@@ -8,11 +8,11 @@ var defaultCommonProps = {
8
8
  ...extraDefaultProps
9
9
  };
10
10
  var props = Object.keys(defaultCommonProps);
11
- function filterProps(data) {
11
+ function filterProps(data, compareDefaultValues) {
12
12
  const result = {};
13
13
  props.forEach((attr) => {
14
14
  const value = data[attr];
15
- if (value !== void 0 && value !== defaultCommonProps[attr]) {
15
+ if (value !== void 0 && (!compareDefaultValues || value !== defaultCommonProps[attr])) {
16
16
  result[attr] = value;
17
17
  }
18
18
  });
@@ -25,6 +25,8 @@ export interface IconWithChars {
25
25
  }
26
26
  export interface IconWithPropsData extends IconWithChars {
27
27
  props: CommonIconProps;
28
+ }
29
+ export interface IconWithCategories {
28
30
  categories: Set<IconCategory>;
29
31
  }
30
32
  export interface IconParentData {
@@ -33,7 +35,7 @@ export interface IconParentData {
33
35
  /**
34
36
  * Icon types
35
37
  */
36
- export interface IconSetIcon extends IconWithPropsData {
38
+ export interface IconSetIcon extends IconWithPropsData, IconWithCategories {
37
39
  type: 'icon';
38
40
  body: string;
39
41
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getFigmaIconNodes = void 0;
4
- // eslint-disable-next-line @typescript-eslint/no-unused-vars-experimental, @typescript-eslint/no-unused-vars
4
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
5
5
  function assertNever(v) {
6
6
  //
7
7
  }
@@ -24,9 +24,8 @@ async function getFigmaIconNodes(document, options) {
24
24
  if (iconNode.absoluteBoundingBox) {
25
25
  const box = iconNode.absoluteBoundingBox;
26
26
  const item = {
27
- id: node.id,
27
+ ...node,
28
28
  type: iconNodeType,
29
- name: node.name,
30
29
  width: box.width,
31
30
  height: box.height,
32
31
  parents,
@@ -70,9 +69,8 @@ async function getFigmaIconNodes(document, options) {
70
69
  case 'FRAME':
71
70
  case 'GROUP': {
72
71
  const parentItem = {
73
- id: node.id,
72
+ ...node,
74
73
  type: parentNodeType,
75
- name: node.name,
76
74
  };
77
75
  const newParents = parents.concat([parentItem]);
78
76
  if (!parents.length && options.pages) {
@@ -16,9 +16,8 @@ async function getFigmaIconNodes(document, options) {
16
16
  if (iconNode.absoluteBoundingBox) {
17
17
  const box = iconNode.absoluteBoundingBox;
18
18
  const item = {
19
- id: node.id,
19
+ ...node,
20
20
  type: iconNodeType,
21
- name: node.name,
22
21
  width: box.width,
23
22
  height: box.height,
24
23
  parents
@@ -57,9 +56,8 @@ async function getFigmaIconNodes(document, options) {
57
56
  case "FRAME":
58
57
  case "GROUP": {
59
58
  const parentItem = {
60
- id: node.id,
61
- type: parentNodeType,
62
- name: node.name
59
+ ...node,
60
+ type: parentNodeType
63
61
  };
64
62
  const newParents = parents.concat([parentItem]);
65
63
  if (!parents.length && options.pages) {
package/lib/index.d.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { SVG } from './svg/index';
2
2
  export { parseSVG } from './svg/parse';
3
3
  export { parseSVGStyle } from './svg/parse-style';
4
+ export { analyseSVGStructure } from './svg/analyse';
4
5
  export { cleanupSVG } from './svg/cleanup';
5
6
  export { removeBadAttributes } from './svg/cleanup/attribs';
6
7
  export { checkBadTags } from './svg/cleanup/bad-tags';
@@ -14,6 +15,7 @@ export { importDirectory } from './import/directory';
14
15
  export { downloadGitRepo } from './download/git/index';
15
16
  export { getGitRepoHash } from './download/git/hash';
16
17
  export { getGitRepoBranch } from './download/git/branch';
18
+ export { resetGitRepoContents } from './download/git/reset';
17
19
  export { downloadGitHubRepo } from './download/github/index';
18
20
  export { getGitHubRepoHash } from './download/github/hash';
19
21
  export { downloadGitLabRepo } from './download/gitlab/index';
@@ -26,6 +28,7 @@ export { validateColors } from './colors/validate';
26
28
  export { runSVGO } from './optimise/svgo';
27
29
  export { deOptimisePaths } from './optimise/flags';
28
30
  export { scaleSVG } from './optimise/scale';
31
+ export { cleanupGlobalStyle } from './optimise/global-style';
29
32
  export { exportToDirectory } from './export/directory';
30
33
  export { exportIconPackage } from './export/icon-package';
31
34
  export { exportJSONPackage } from './export/json-package';
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.sendAPIQuery = exports.bumpVersion = exports.cleanupIconKeyword = exports.execAsync = exports.untar = exports.unzip = exports.compareDirectories = exports.scanDirectory = exports.prepareDirectoryForExport = exports.writeJSONFile = exports.exportJSONPackage = exports.exportIconPackage = exports.exportToDirectory = exports.scaleSVG = exports.deOptimisePaths = exports.runSVGO = exports.validateColors = exports.isEmptyColor = exports.parseColors = exports.downloadPackage = exports.getPackageVersion = exports.getNPMVersion = exports.downloadNPMPackage = exports.getGitLabRepoHash = exports.downloadGitLabRepo = exports.getGitHubRepoHash = exports.downloadGitHubRepo = exports.getGitRepoBranch = exports.getGitRepoHash = exports.downloadGitRepo = exports.importDirectory = exports.importFromFigma = exports.mergeIconSets = exports.blankIconSet = exports.IconSet = exports.convertStyleToAttrs = exports.cleanupSVGRoot = exports.cleanupInlineStyle = exports.checkBadTags = exports.removeBadAttributes = exports.cleanupSVG = exports.parseSVGStyle = exports.parseSVG = exports.SVG = void 0;
3
+ exports.sendAPIQuery = exports.bumpVersion = exports.cleanupIconKeyword = exports.execAsync = exports.untar = exports.unzip = exports.compareDirectories = exports.scanDirectory = exports.prepareDirectoryForExport = exports.writeJSONFile = exports.exportJSONPackage = exports.exportIconPackage = exports.exportToDirectory = exports.cleanupGlobalStyle = exports.scaleSVG = exports.deOptimisePaths = exports.runSVGO = exports.validateColors = exports.isEmptyColor = exports.parseColors = exports.downloadPackage = exports.getPackageVersion = exports.getNPMVersion = exports.downloadNPMPackage = exports.getGitLabRepoHash = exports.downloadGitLabRepo = exports.getGitHubRepoHash = exports.downloadGitHubRepo = exports.resetGitRepoContents = exports.getGitRepoBranch = exports.getGitRepoHash = exports.downloadGitRepo = exports.importDirectory = exports.importFromFigma = exports.mergeIconSets = exports.blankIconSet = exports.IconSet = exports.convertStyleToAttrs = exports.cleanupSVGRoot = exports.cleanupInlineStyle = exports.checkBadTags = exports.removeBadAttributes = exports.cleanupSVG = exports.analyseSVGStructure = exports.parseSVGStyle = exports.parseSVG = exports.SVG = void 0;
4
4
  // SVG class and functions
5
5
  var index_1 = require("./svg/index");
6
6
  Object.defineProperty(exports, "SVG", { enumerable: true, get: function () { return index_1.SVG; } });
@@ -8,6 +8,8 @@ var parse_1 = require("./svg/parse");
8
8
  Object.defineProperty(exports, "parseSVG", { enumerable: true, get: function () { return parse_1.parseSVG; } });
9
9
  var parse_style_1 = require("./svg/parse-style");
10
10
  Object.defineProperty(exports, "parseSVGStyle", { enumerable: true, get: function () { return parse_style_1.parseSVGStyle; } });
11
+ var analyse_1 = require("./svg/analyse");
12
+ Object.defineProperty(exports, "analyseSVGStructure", { enumerable: true, get: function () { return analyse_1.analyseSVGStructure; } });
11
13
  // SVG cleanup
12
14
  var cleanup_1 = require("./svg/cleanup");
13
15
  Object.defineProperty(exports, "cleanupSVG", { enumerable: true, get: function () { return cleanup_1.cleanupSVG; } });
@@ -39,6 +41,8 @@ var hash_1 = require("./download/git/hash");
39
41
  Object.defineProperty(exports, "getGitRepoHash", { enumerable: true, get: function () { return hash_1.getGitRepoHash; } });
40
42
  var branch_1 = require("./download/git/branch");
41
43
  Object.defineProperty(exports, "getGitRepoBranch", { enumerable: true, get: function () { return branch_1.getGitRepoBranch; } });
44
+ var reset_1 = require("./download/git/reset");
45
+ Object.defineProperty(exports, "resetGitRepoContents", { enumerable: true, get: function () { return reset_1.resetGitRepoContents; } });
42
46
  var index_5 = require("./download/github/index");
43
47
  Object.defineProperty(exports, "downloadGitHubRepo", { enumerable: true, get: function () { return index_5.downloadGitHubRepo; } });
44
48
  var hash_2 = require("./download/github/hash");
@@ -66,6 +70,8 @@ var flags_1 = require("./optimise/flags");
66
70
  Object.defineProperty(exports, "deOptimisePaths", { enumerable: true, get: function () { return flags_1.deOptimisePaths; } });
67
71
  var scale_1 = require("./optimise/scale");
68
72
  Object.defineProperty(exports, "scaleSVG", { enumerable: true, get: function () { return scale_1.scaleSVG; } });
73
+ var global_style_1 = require("./optimise/global-style");
74
+ Object.defineProperty(exports, "cleanupGlobalStyle", { enumerable: true, get: function () { return global_style_1.cleanupGlobalStyle; } });
69
75
  // Export
70
76
  var directory_2 = require("./export/directory");
71
77
  Object.defineProperty(exports, "exportToDirectory", { enumerable: true, get: function () { return directory_2.exportToDirectory; } });
package/lib/index.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
  import { SVG } from "./svg/index.mjs";
3
3
  import { parseSVG } from "./svg/parse.mjs";
4
4
  import { parseSVGStyle } from "./svg/parse-style.mjs";
5
+ import { analyseSVGStructure } from "./svg/analyse.mjs";
5
6
  import { cleanupSVG } from "./svg/cleanup.mjs";
6
7
  import { removeBadAttributes } from "./svg/cleanup/attribs.mjs";
7
8
  import { checkBadTags } from "./svg/cleanup/bad-tags.mjs";
@@ -15,6 +16,7 @@ import { importDirectory } from "./import/directory.mjs";
15
16
  import { downloadGitRepo } from "./download/git/index.mjs";
16
17
  import { getGitRepoHash } from "./download/git/hash.mjs";
17
18
  import { getGitRepoBranch } from "./download/git/branch.mjs";
19
+ import { resetGitRepoContents } from "./download/git/reset.mjs";
18
20
  import { downloadGitHubRepo } from "./download/github/index.mjs";
19
21
  import { getGitHubRepoHash } from "./download/github/hash.mjs";
20
22
  import { downloadGitLabRepo } from "./download/gitlab/index.mjs";
@@ -27,6 +29,7 @@ import { validateColors } from "./colors/validate.mjs";
27
29
  import { runSVGO } from "./optimise/svgo.mjs";
28
30
  import { deOptimisePaths } from "./optimise/flags.mjs";
29
31
  import { scaleSVG } from "./optimise/scale.mjs";
32
+ import { cleanupGlobalStyle } from "./optimise/global-style.mjs";
30
33
  import { exportToDirectory } from "./export/directory.mjs";
31
34
  import { exportIconPackage } from "./export/icon-package.mjs";
32
35
  import { exportJSONPackage } from "./export/json-package.mjs";
@@ -43,9 +46,11 @@ import { sendAPIQuery } from "./download/api/index.mjs";
43
46
  export {
44
47
  IconSet,
45
48
  SVG,
49
+ analyseSVGStructure,
46
50
  blankIconSet,
47
51
  bumpVersion,
48
52
  checkBadTags,
53
+ cleanupGlobalStyle,
49
54
  cleanupIconKeyword,
50
55
  cleanupInlineStyle,
51
56
  cleanupSVG,
@@ -77,6 +82,7 @@ export {
77
82
  parseSVGStyle,
78
83
  prepareDirectoryForExport,
79
84
  removeBadAttributes,
85
+ resetGitRepoContents,
80
86
  runSVGO,
81
87
  scaleSVG,
82
88
  scanDirectory,
@@ -64,6 +64,15 @@ function cleanPath(path) {
64
64
  });
65
65
  currentArgs = [];
66
66
  canParseCommandOrComma = true;
67
+ // Change command for lines after moving
68
+ switch (currentCommand) {
69
+ case 'M':
70
+ currentCommand = 'L';
71
+ break;
72
+ case 'm':
73
+ currentCommand = 'l';
74
+ break;
75
+ }
67
76
  }
68
77
  };
69
78
  const parseNumber = () => {
@@ -44,6 +44,14 @@ function cleanPath(path) {
44
44
  });
45
45
  currentArgs = [];
46
46
  canParseCommandOrComma = true;
47
+ switch (currentCommand) {
48
+ case "M":
49
+ currentCommand = "L";
50
+ break;
51
+ case "m":
52
+ currentCommand = "l";
53
+ break;
54
+ }
47
55
  }
48
56
  };
49
57
  const parseNumber = () => {
@@ -0,0 +1,5 @@
1
+ import type { SVG } from '../svg';
2
+ /**
3
+ * Expand global style
4
+ */
5
+ export declare function cleanupGlobalStyle(svg: SVG): Promise<void>;
@@ -0,0 +1,158 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cleanupGlobalStyle = void 0;
4
+ require("../svg/data/attributes");
5
+ const tags_1 = require("../svg/data/tags");
6
+ const parse_1 = require("../svg/parse");
7
+ const parse_style_1 = require("../svg/parse-style");
8
+ function getClassList(value) {
9
+ return value === null || value === void 0 ? void 0 : value.split(/\s+/);
10
+ }
11
+ const tempDataAttrbiute = 'data-gstyle-temp';
12
+ /**
13
+ * Expand global style
14
+ */
15
+ async function cleanupGlobalStyle(svg) {
16
+ const backup = svg.toString();
17
+ let containsTempAttr = false;
18
+ // Find all animated classes
19
+ const animatedClasses = new Set();
20
+ await (0, parse_1.parseSVG)(svg, (item) => {
21
+ if (!tags_1.animateTags.has(item.tagName)) {
22
+ return;
23
+ }
24
+ const $element = item.$element;
25
+ if ($element.attr('attributeName') !== 'class') {
26
+ return;
27
+ }
28
+ ['from', 'to', 'values'].forEach((attr) => {
29
+ const value = $element.attr(attr);
30
+ if (typeof value !== 'string') {
31
+ return;
32
+ }
33
+ value.split(';').forEach((item) => {
34
+ getClassList(item).forEach((className) => {
35
+ animatedClasses.add(className);
36
+ });
37
+ });
38
+ });
39
+ });
40
+ // Parse style
41
+ try {
42
+ await (0, parse_style_1.parseSVGStyle)(svg, async (styleItem) => {
43
+ var _a;
44
+ const returnValue = styleItem.value;
45
+ if (styleItem.type !== 'global') {
46
+ return returnValue;
47
+ }
48
+ // Handle only simple selectors
49
+ if (styleItem.selectors.length !== 1 ||
50
+ styleItem.selectorTokens.length !== 1) {
51
+ return returnValue;
52
+ }
53
+ // 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;
73
+ }
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;
78
+ }
79
+ // Check if element is a match
80
+ 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;
91
+ }
92
+ }
93
+ }
94
+ return true;
95
+ };
96
+ // Parse all elements
97
+ await (0, parse_1.parseSVG)(svg, (svgItem) => {
98
+ var _a;
99
+ const tagName = svgItem.tagName;
100
+ const $element = svgItem.$element;
101
+ if (!isMatch(tagName, $element)) {
102
+ return;
103
+ }
104
+ // Transfer attribute
105
+ const addedAttributes = new Set((_a = $element.attr(tempDataAttrbiute)) === null || _a === void 0 ? void 0 : _a.split(/\s+/));
106
+ const prop = styleItem.prop;
107
+ if ($element.attr(prop) !== void 0) {
108
+ // Previously added attribute?
109
+ if (addedAttributes.has(prop)) {
110
+ // Two CSS rules are applied to same element: abort parsing and restore content from backup.
111
+ // This parse is very basic, it does not account for specificity.
112
+ throw new Error('Duplicate attribute');
113
+ }
114
+ }
115
+ $element.attr(prop, styleItem.value);
116
+ addedAttributes.add(prop);
117
+ $element.attr(tempDataAttrbiute, Array.from(addedAttributes).join(' '));
118
+ containsTempAttr = true;
119
+ });
120
+ // Remove class attribute
121
+ if (matchType === 'class' &&
122
+ ((_a = styleItem.nextTokens[0]) === null || _a === void 0 ? void 0 : _a.type) === 'close') {
123
+ // Can remove class
124
+ await (0, parse_1.parseSVG)(svg, (svgItem) => {
125
+ const $element = svgItem.$element;
126
+ if (!isMatch('', $element)) {
127
+ return;
128
+ }
129
+ // Remove class
130
+ const classList = getClassList($element.attr('class'));
131
+ if (!classList) {
132
+ return;
133
+ }
134
+ const filtered = classList.filter((item) => item !== valueMatch);
135
+ if (!filtered.length) {
136
+ $element.removeAttr('class');
137
+ }
138
+ else {
139
+ $element.attr('class', filtered.join(' '));
140
+ }
141
+ });
142
+ }
143
+ // Remove rule
144
+ return;
145
+ });
146
+ // Remove temporary attributes
147
+ if (containsTempAttr) {
148
+ await (0, parse_1.parseSVG)(svg, (item) => {
149
+ item.$element.removeAttr(tempDataAttrbiute);
150
+ });
151
+ }
152
+ }
153
+ catch (err) {
154
+ // Failed: restore from backup
155
+ svg.load(backup);
156
+ }
157
+ }
158
+ exports.cleanupGlobalStyle = cleanupGlobalStyle;