@iconify/tools 2.0.11 → 2.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/colors/parse.d.ts +14 -7
- package/lib/colors/parse.js +101 -39
- package/lib/colors/parse.mjs +81 -38
- package/lib/download/git/index.js +12 -0
- package/lib/download/git/index.mjs +7 -0
- package/lib/download/git/reset.d.ts +4 -0
- package/lib/download/git/reset.js +16 -0
- package/lib/download/git/reset.mjs +13 -0
- package/lib/export/json-package.js +6 -1
- package/lib/export/json-package.mjs +4 -1
- package/lib/icon-set/index.js +7 -4
- package/lib/icon-set/index.mjs +7 -4
- package/lib/icon-set/props.d.ts +1 -1
- package/lib/icon-set/props.js +3 -2
- package/lib/icon-set/props.mjs +2 -2
- package/lib/import/figma/nodes.js +3 -5
- package/lib/import/figma/nodes.mjs +3 -5
- package/lib/index.d.ts +3 -0
- package/lib/index.js +7 -1
- package/lib/index.mjs +6 -0
- package/lib/optimise/global-style.d.ts +5 -0
- package/lib/optimise/global-style.js +185 -0
- package/lib/optimise/global-style.mjs +147 -0
- package/lib/svg/analyse/error.d.ts +5 -0
- package/lib/svg/analyse/error.js +22 -0
- package/lib/svg/analyse/error.mjs +16 -0
- package/lib/svg/analyse/types.d.ts +89 -0
- package/lib/svg/analyse/types.js +2 -0
- package/lib/svg/analyse/types.mjs +0 -0
- package/lib/svg/analyse.d.ts +8 -0
- package/lib/svg/analyse.js +352 -0
- package/lib/svg/analyse.mjs +302 -0
- package/lib/svg/cleanup/attribs.d.ts +1 -1
- package/lib/svg/cleanup/attribs.js +8 -0
- package/lib/svg/cleanup/attribs.mjs +8 -1
- package/lib/svg/cleanup/bad-tags.d.ts +1 -1
- package/lib/svg/cleanup/bad-tags.js +0 -2
- package/lib/svg/cleanup/bad-tags.mjs +0 -3
- package/lib/svg/cleanup/inline-style.d.ts +1 -1
- package/lib/svg/cleanup/root-svg.d.ts +1 -1
- package/lib/svg/cleanup/root-svg.js +3 -1
- package/lib/svg/cleanup/root-svg.mjs +2 -2
- package/lib/svg/cleanup/svgo-style.d.ts +1 -1
- package/lib/svg/data/attributes.js +1 -1
- package/lib/svg/data/attributes.mjs +1 -1
- package/lib/svg/data/tags.d.ts +15 -7
- package/lib/svg/data/tags.js +20 -9
- package/lib/svg/data/tags.mjs +11 -6
- package/lib/svg/index.js +13 -4
- package/lib/svg/index.mjs +5 -2
- package/lib/svg/parse-style.d.ts +7 -7
- package/lib/svg/parse-style.js +27 -7
- package/lib/svg/parse-style.mjs +26 -7
- package/package.json +21 -1
package/lib/icon-set/index.mjs
CHANGED
|
@@ -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:
|
|
32
|
+
props: filterProps({
|
|
33
|
+
...defaultProps,
|
|
34
|
+
...item
|
|
35
|
+
}, true),
|
|
33
36
|
chars: new Set(),
|
|
34
37
|
categories: new Set()
|
|
35
38
|
};
|
|
@@ -39,7 +42,7 @@ 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 = {
|
|
@@ -473,7 +476,7 @@ var IconSet = class {
|
|
|
473
476
|
return this.setItem(name, {
|
|
474
477
|
type: "icon",
|
|
475
478
|
body: icon.body,
|
|
476
|
-
props: filterProps(icon),
|
|
479
|
+
props: filterProps(icon, true),
|
|
477
480
|
chars: new Set(),
|
|
478
481
|
categories: new Set()
|
|
479
482
|
});
|
package/lib/icon-set/props.d.ts
CHANGED
|
@@ -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;
|
package/lib/icon-set/props.js
CHANGED
|
@@ -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
|
-
|
|
27
|
+
(!compareDefaultValues ||
|
|
28
|
+
value !== exports.defaultCommonProps[attr])) {
|
|
28
29
|
result[attr] = value;
|
|
29
30
|
}
|
|
30
31
|
});
|
package/lib/icon-set/props.mjs
CHANGED
|
@@ -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
|
});
|
|
@@ -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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
@@ -0,0 +1,185 @@
|
|
|
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
|
+
/*
|
|
50
|
+
if (
|
|
51
|
+
styleItem.selectors.length !== 1 ||
|
|
52
|
+
styleItem.selectorTokens.length !== 1
|
|
53
|
+
) {
|
|
54
|
+
return returnValue;
|
|
55
|
+
}
|
|
56
|
+
*/
|
|
57
|
+
// Do not handle media queries
|
|
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
|
+
}
|
|
64
|
+
}
|
|
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
|
+
});
|
|
93
|
+
}
|
|
94
|
+
// Check if element is a match
|
|
95
|
+
const isMatch = (tagName, $element) => {
|
|
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
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
};
|
|
120
|
+
// Parse all elements
|
|
121
|
+
await (0, parse_1.parseSVG)(svg, (svgItem) => {
|
|
122
|
+
var _a;
|
|
123
|
+
const tagName = svgItem.tagName;
|
|
124
|
+
const $element = svgItem.$element;
|
|
125
|
+
if (!isMatch(tagName, $element)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// Transfer attribute
|
|
129
|
+
const addedAttributes = new Set((_a = $element.attr(tempDataAttrbiute)) === null || _a === void 0 ? void 0 : _a.split(/\s+/));
|
|
130
|
+
const prop = styleItem.prop;
|
|
131
|
+
if ($element.attr(prop) !== void 0) {
|
|
132
|
+
// Previously added attribute?
|
|
133
|
+
if (addedAttributes.has(prop)) {
|
|
134
|
+
// Two CSS rules are applied to same element: abort parsing and restore content from backup.
|
|
135
|
+
// This parse is very basic, it does not account for specificity.
|
|
136
|
+
throw new Error('Duplicate attribute');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
$element.attr(prop, styleItem.value);
|
|
140
|
+
addedAttributes.add(prop);
|
|
141
|
+
$element.attr(tempDataAttrbiute, Array.from(addedAttributes).join(' '));
|
|
142
|
+
containsTempAttr = true;
|
|
143
|
+
});
|
|
144
|
+
// Remove class attribute
|
|
145
|
+
const classMatches = matches
|
|
146
|
+
.filter((item) => item.type === 'class')
|
|
147
|
+
.map((item) => item.value);
|
|
148
|
+
if (classMatches.length &&
|
|
149
|
+
((_a = styleItem.nextTokens[0]) === null || _a === void 0 ? void 0 : _a.type) === 'close') {
|
|
150
|
+
// Can remove class
|
|
151
|
+
await (0, parse_1.parseSVG)(svg, (svgItem) => {
|
|
152
|
+
const $element = svgItem.$element;
|
|
153
|
+
if (!isMatch('', $element)) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
// Remove class
|
|
157
|
+
const classList = getClassList($element.attr('class'));
|
|
158
|
+
if (!classList) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
const filtered = classList.filter((item) => classMatches.indexOf(item) === -1);
|
|
162
|
+
if (!filtered.length) {
|
|
163
|
+
$element.removeAttr('class');
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
$element.attr('class', filtered.join(' '));
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
// Remove rule
|
|
171
|
+
return;
|
|
172
|
+
});
|
|
173
|
+
// Remove temporary attributes
|
|
174
|
+
if (containsTempAttr) {
|
|
175
|
+
await (0, parse_1.parseSVG)(svg, (item) => {
|
|
176
|
+
item.$element.removeAttr(tempDataAttrbiute);
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
catch (err) {
|
|
181
|
+
// Failed: restore from backup
|
|
182
|
+
svg.load(backup);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
exports.cleanupGlobalStyle = cleanupGlobalStyle;
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
// src/optimise/global-style.ts
|
|
2
|
+
import "../svg/data/attributes.mjs";
|
|
3
|
+
import { allValidTags, animateTags } from "../svg/data/tags.mjs";
|
|
4
|
+
import { parseSVG } from "../svg/parse.mjs";
|
|
5
|
+
import { parseSVGStyle } from "../svg/parse-style.mjs";
|
|
6
|
+
function getClassList(value) {
|
|
7
|
+
return value == null ? void 0 : value.split(/\s+/);
|
|
8
|
+
}
|
|
9
|
+
var tempDataAttrbiute = "data-gstyle-temp";
|
|
10
|
+
async function cleanupGlobalStyle(svg) {
|
|
11
|
+
const backup = svg.toString();
|
|
12
|
+
let containsTempAttr = false;
|
|
13
|
+
const animatedClasses = new Set();
|
|
14
|
+
await parseSVG(svg, (item) => {
|
|
15
|
+
if (!animateTags.has(item.tagName)) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
const $element = item.$element;
|
|
19
|
+
if ($element.attr("attributeName") !== "class") {
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
["from", "to", "values"].forEach((attr) => {
|
|
23
|
+
const value = $element.attr(attr);
|
|
24
|
+
if (typeof value !== "string") {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
value.split(";").forEach((item2) => {
|
|
28
|
+
getClassList(item2).forEach((className) => {
|
|
29
|
+
animatedClasses.add(className);
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
try {
|
|
35
|
+
await parseSVGStyle(svg, async (styleItem) => {
|
|
36
|
+
var _a;
|
|
37
|
+
const returnValue = styleItem.value;
|
|
38
|
+
if (styleItem.type !== "global") {
|
|
39
|
+
return returnValue;
|
|
40
|
+
}
|
|
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
|
+
}
|
|
47
|
+
}
|
|
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
|
+
});
|
|
71
|
+
}
|
|
72
|
+
const isMatch = (tagName, $element) => {
|
|
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
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return false;
|
|
95
|
+
};
|
|
96
|
+
await parseSVG(svg, (svgItem) => {
|
|
97
|
+
var _a2;
|
|
98
|
+
const tagName = svgItem.tagName;
|
|
99
|
+
const $element = svgItem.$element;
|
|
100
|
+
if (!isMatch(tagName, $element)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const addedAttributes = new Set((_a2 = $element.attr(tempDataAttrbiute)) == null ? void 0 : _a2.split(/\s+/));
|
|
104
|
+
const prop = styleItem.prop;
|
|
105
|
+
if ($element.attr(prop) !== void 0) {
|
|
106
|
+
if (addedAttributes.has(prop)) {
|
|
107
|
+
throw new Error("Duplicate attribute");
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
$element.attr(prop, styleItem.value);
|
|
111
|
+
addedAttributes.add(prop);
|
|
112
|
+
$element.attr(tempDataAttrbiute, Array.from(addedAttributes).join(" "));
|
|
113
|
+
containsTempAttr = true;
|
|
114
|
+
});
|
|
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") {
|
|
117
|
+
await parseSVG(svg, (svgItem) => {
|
|
118
|
+
const $element = svgItem.$element;
|
|
119
|
+
if (!isMatch("", $element)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
const classList = getClassList($element.attr("class"));
|
|
123
|
+
if (!classList) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
const filtered = classList.filter((item) => classMatches.indexOf(item) === -1);
|
|
127
|
+
if (!filtered.length) {
|
|
128
|
+
$element.removeAttr("class");
|
|
129
|
+
} else {
|
|
130
|
+
$element.attr("class", filtered.join(" "));
|
|
131
|
+
}
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
});
|
|
136
|
+
if (containsTempAttr) {
|
|
137
|
+
await parseSVG(svg, (item) => {
|
|
138
|
+
item.$element.removeAttr(tempDataAttrbiute);
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
} catch (err) {
|
|
142
|
+
svg.load(backup);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export {
|
|
146
|
+
cleanupGlobalStyle
|
|
147
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.analyseTagError = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Get tag for error message
|
|
6
|
+
*/
|
|
7
|
+
function analyseTagError(element) {
|
|
8
|
+
let result = '<' + element.tagName;
|
|
9
|
+
if (element._id) {
|
|
10
|
+
result += ' id="' + element._id + '"';
|
|
11
|
+
}
|
|
12
|
+
const attribs = element.attribs;
|
|
13
|
+
if (attribs['d']) {
|
|
14
|
+
const value = attribs['d'];
|
|
15
|
+
result +=
|
|
16
|
+
' d="' +
|
|
17
|
+
(value.length > 16 ? value.slice(0, 12) + '...' : value) +
|
|
18
|
+
'"';
|
|
19
|
+
}
|
|
20
|
+
return result + '>';
|
|
21
|
+
}
|
|
22
|
+
exports.analyseTagError = analyseTagError;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// src/svg/analyse/error.ts
|
|
2
|
+
function analyseTagError(element) {
|
|
3
|
+
let result = "<" + element.tagName;
|
|
4
|
+
if (element._id) {
|
|
5
|
+
result += ' id="' + element._id + '"';
|
|
6
|
+
}
|
|
7
|
+
const attribs = element.attribs;
|
|
8
|
+
if (attribs["d"]) {
|
|
9
|
+
const value = attribs["d"];
|
|
10
|
+
result += ' d="' + (value.length > 16 ? value.slice(0, 12) + "..." : value) + '"';
|
|
11
|
+
}
|
|
12
|
+
return result + ">";
|
|
13
|
+
}
|
|
14
|
+
export {
|
|
15
|
+
analyseTagError
|
|
16
|
+
};
|