@cyberalien/svg-utils 1.0.11 → 1.1.1
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/components/helpers/css/generate.js +10 -10
- package/lib/components/helpers/filenames/types.d.ts +3 -1
- package/lib/components/helpers/filenames/types.js +1 -0
- package/lib/components/jsx.js +1 -1
- package/lib/components/prepare/iconify.d.ts +1 -1
- package/lib/components/svelte.js +1 -1
- package/lib/components/types/options.d.ts +2 -1
- package/lib/components/vue-func.js +1 -1
- package/lib/components/vue.js +1 -1
- package/lib/css/hash.d.ts +1 -1
- package/lib/css/hash.js +2 -4
- package/lib/css/types.d.ts +2 -2
- package/lib/helpers/hash/context.d.ts +6 -0
- package/lib/helpers/hash/context.js +8 -0
- package/lib/helpers/hash/types.d.ts +24 -4
- package/lib/helpers/hash/unique.js +3 -4
- package/lib/index.d.ts +4 -3
- package/lib/index.js +2 -1
- package/lib/svg/ids/change.js +2 -2
- package/lib/svg/ids/types.d.ts +3 -1
- package/lib/svg/ids/unique.d.ts +2 -1
- package/lib/svg/ids/unique.js +4 -6
- package/lib/svg-css/content.d.ts +1 -1
- package/lib/svg-css/props/props.js +1 -1
- package/lib/svg-css/root.d.ts +1 -1
- package/lib/svg-css/root.js +2 -4
- package/lib/svg-css/types.d.ts +1 -3
- package/lib/xml/parse.js +9 -9
- package/package.json +11 -11
- package/lib/svg-css/animations/attribute.d.ts +0 -11
- package/lib/svg-css/animations/attribute.js +0 -19
- package/lib/svg-css/animations/common.d.ts +0 -8
- package/lib/svg-css/animations/common.js +0 -16
- package/lib/svg-css/animations/find.d.ts +0 -9
- package/lib/svg-css/animations/find.js +0 -48
- package/lib/svg-css/animations/types.d.ts +0 -19
- package/lib/svg-css/animations/types.js +0 -1
- /package/lib/svg-css/{animations → props}/tags.d.ts +0 -0
- /package/lib/svg-css/{animations → props}/tags.js +0 -0
|
@@ -21,51 +21,51 @@ function generateCSSFilesForComponent(content, imports, assets, options) {
|
|
|
21
21
|
const mergedContent = [];
|
|
22
22
|
for (const className in classes) {
|
|
23
23
|
const baseContent = stringifyCSSSelector(`${classNamePrefix}.${className}`, classes[className]);
|
|
24
|
-
let content
|
|
24
|
+
let content = baseContent;
|
|
25
25
|
if (embedAnimations && keyframes) {
|
|
26
26
|
for (const animationName in keyframes) if (baseContent.includes(animationName)) {
|
|
27
27
|
const value = keyframes[animationName];
|
|
28
|
-
content
|
|
28
|
+
content += "\n" + (typeof value === "string" ? value : stringifyCSSKeyframes(keyframesPrefix + animationName, value));
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
if (mergeCSS) {
|
|
32
|
-
mergedContent.push(content
|
|
32
|
+
mergedContent.push(content);
|
|
33
33
|
continue;
|
|
34
34
|
}
|
|
35
35
|
const filename = getGeneratedCSSFilename(className, options);
|
|
36
36
|
assets.push({
|
|
37
37
|
...filename,
|
|
38
|
-
content
|
|
38
|
+
content
|
|
39
39
|
});
|
|
40
40
|
if (isModule) imports.modules[filename.import] = generateCSSDefaultImportName(className);
|
|
41
41
|
else imports.css.add(filename.import);
|
|
42
42
|
}
|
|
43
43
|
if (!embedAnimations && keyframes) for (const animationName in keyframes) {
|
|
44
44
|
const value = keyframes[animationName];
|
|
45
|
-
const content
|
|
45
|
+
const content = typeof value === "string" ? value : stringifyCSSKeyframes(keyframesPrefix + animationName, value);
|
|
46
46
|
if (mergeCSS) {
|
|
47
|
-
mergedContent.push(content
|
|
47
|
+
mergedContent.push(content);
|
|
48
48
|
continue;
|
|
49
49
|
}
|
|
50
50
|
const filename = getGeneratedCSSFilename(animationName, options);
|
|
51
51
|
assets.push({
|
|
52
52
|
...filename,
|
|
53
|
-
content
|
|
53
|
+
content
|
|
54
54
|
});
|
|
55
55
|
if (isModule) imports.modules[filename.import] = generateCSSDefaultImportName(animationName);
|
|
56
56
|
else imports.css.add(filename.import);
|
|
57
57
|
}
|
|
58
58
|
if (mergeCSS && mergedContent.length) {
|
|
59
|
-
const content
|
|
59
|
+
const content = mergedContent.join("\n");
|
|
60
60
|
if (typeof mergeCSS == "object") {
|
|
61
61
|
assets.push({
|
|
62
62
|
...mergeCSS,
|
|
63
|
-
content
|
|
63
|
+
content
|
|
64
64
|
});
|
|
65
65
|
if (isModule) imports.modules[mergeCSS.import] = "css";
|
|
66
66
|
else if (!returnCSS) imports.css.add(mergeCSS.import);
|
|
67
67
|
}
|
|
68
|
-
return returnCSS ? content
|
|
68
|
+
return returnCSS ? content : void 0;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { UniqueHashPartialOptions } from "../../../helpers/hash/types.js";
|
|
1
2
|
import { FactoryIconData } from "../../types/data.js";
|
|
2
3
|
import { ComponentFactoryFileSystemOptions, GeneratedAssetPath } from "../../types/options.js";
|
|
4
|
+
interface Options extends Pick<UniqueHashPartialOptions, 'context'>, Pick<ComponentFactoryFileSystemOptions, 'rootPath' | 'doubleDirsForComponents' | 'prefixDirsForComponents' | 'sharedTypes'> {}
|
|
3
5
|
/**
|
|
4
6
|
* Generate component types filename based on options
|
|
5
7
|
*/
|
|
6
|
-
declare function getGeneratedComponentTypesFilename(icon: Pick<FactoryIconData, 'name' | 'prefix'>, content: string, options:
|
|
8
|
+
declare function getGeneratedComponentTypesFilename(icon: Pick<FactoryIconData, 'name' | 'prefix'>, content: string, options: Options): GeneratedAssetPath;
|
|
7
9
|
export { getGeneratedComponentTypesFilename };
|
|
@@ -7,6 +7,7 @@ import { getGeneratedComponentFilename } from "../../export/filename.js";
|
|
|
7
7
|
*/
|
|
8
8
|
function getGeneratedComponentTypesFilename(icon, content, options) {
|
|
9
9
|
if (options.sharedTypes) return getGeneratedAssetFilename(`types/${getUniqueHash(content, {
|
|
10
|
+
context: options.context,
|
|
10
11
|
css: true,
|
|
11
12
|
length: 8
|
|
12
13
|
})}.d.ts`, options.rootPath);
|
package/lib/components/jsx.js
CHANGED
|
@@ -52,7 +52,7 @@ function createJSXComponent(data, options) {
|
|
|
52
52
|
value: "props",
|
|
53
53
|
template: "...props,"
|
|
54
54
|
};
|
|
55
|
-
const getViewBox = (viewBox
|
|
55
|
+
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
56
56
|
if (hasComputedViewbox) {
|
|
57
57
|
componentExternalCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`);
|
|
58
58
|
componentInternalCode.push(`const viewBox = useMemo(() => square ? squareViewBox : baseViewBox, [square]);`);
|
|
@@ -9,7 +9,7 @@ interface Options extends ConvertSVGContentOptions {
|
|
|
9
9
|
/**
|
|
10
10
|
* Convert IconifyIcon data to FactoryIconData
|
|
11
11
|
*/
|
|
12
|
-
declare function convertIconifyIconToFactoryContent(icon: IconifyIcon, prefix: string, name: string, options
|
|
12
|
+
declare function convertIconifyIconToFactoryContent(icon: IconifyIcon, prefix: string, name: string, options: Options): FactoryIconData;
|
|
13
13
|
/**
|
|
14
14
|
* Create metadata assets for an icon set
|
|
15
15
|
*/
|
package/lib/components/svelte.js
CHANGED
|
@@ -39,7 +39,7 @@ function createSvelteComponent(data, options) {
|
|
|
39
39
|
const props = {};
|
|
40
40
|
if (!hasFallback) props.xmlns = "http://www.w3.org/2000/svg";
|
|
41
41
|
const viewBoxPropValue = `viewBox${hasComputedViewbox ? "Computed" : ""}`;
|
|
42
|
-
const getViewBox = (viewBox
|
|
42
|
+
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
43
43
|
if (hasComputedViewbox) componentCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`, `let ${viewBoxPropValue} = $derived(square ? squareViewBox : baseViewBox);`);
|
|
44
44
|
else componentCode.push(`const ${viewBoxPropValue} = ${getViewBox(viewBox)};`);
|
|
45
45
|
const ratioValue = getViewBoxRatio(viewBox);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { UniqueHashPartialOptions } from "../../helpers/hash/types.js";
|
|
1
2
|
import { CSSExportMode } from "./css.js";
|
|
2
3
|
/**
|
|
3
4
|
* Asset path, generated from configuration
|
|
@@ -31,5 +32,5 @@ interface ComponentFactoryRenderingOptions {
|
|
|
31
32
|
/**
|
|
32
33
|
* Options for component factory
|
|
33
34
|
*/
|
|
34
|
-
interface ComponentFactoryOptions extends ComponentFactoryFileSystemOptions, ComponentFactoryRenderingOptions {}
|
|
35
|
+
interface ComponentFactoryOptions extends ComponentFactoryFileSystemOptions, ComponentFactoryRenderingOptions, Pick<UniqueHashPartialOptions, 'context'> {}
|
|
35
36
|
export { ComponentFactoryFileSystemOptions, ComponentFactoryOptions, ComponentFactoryRenderingOptions, GeneratedAssetPath };
|
|
@@ -37,7 +37,7 @@ function createVueFunctionalComponent(data, options) {
|
|
|
37
37
|
const componentCode = [];
|
|
38
38
|
const props = {};
|
|
39
39
|
if (!hasFallback) props.xmlns = "http://www.w3.org/2000/svg";
|
|
40
|
-
const getViewBox = (viewBox
|
|
40
|
+
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
41
41
|
if (hasComputedViewbox) componentCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`, `const viewBox = computed(() => props.square ? squareViewBox : baseViewBox);`);
|
|
42
42
|
else componentCode.push(`const viewBox = ${getViewBox(viewBox)};`);
|
|
43
43
|
const ratioValue = getViewBoxRatio(viewBox);
|
package/lib/components/vue.js
CHANGED
|
@@ -37,7 +37,7 @@ function createVueComponent(data, options) {
|
|
|
37
37
|
const componentCode = [];
|
|
38
38
|
const props = {};
|
|
39
39
|
if (!hasFallback) props.xmlns = "http://www.w3.org/2000/svg";
|
|
40
|
-
const getViewBox = (viewBox
|
|
40
|
+
const getViewBox = (viewBox) => isStringViewBox ? `'${stringifyIconViewBox(viewBox)}'` : JSON.stringify(minifyViewBox(viewBox));
|
|
41
41
|
if (hasComputedViewbox) componentCode.push(`const baseViewBox = ${getViewBox(viewBox)};`, `const squareViewBox = ${getViewBox(makeSquareViewBox(viewBox))};`, `const viewBox = computed(() => props.square ? squareViewBox : baseViewBox);`);
|
|
42
42
|
else componentCode.push(`const viewBox = ${getViewBox(viewBox)};`);
|
|
43
43
|
const ratioValue = getViewBoxRatio(viewBox);
|
package/lib/css/hash.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import { CSSHashOptions, CSSRules } from "./types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Get class name for CSS rules
|
|
4
4
|
*/
|
|
5
|
-
declare function createCSSClassName(rules: CSSRules,
|
|
5
|
+
declare function createCSSClassName(rules: CSSRules, options: CSSHashOptions): string;
|
|
6
6
|
export { createCSSClassName };
|
package/lib/css/hash.js
CHANGED
|
@@ -1,15 +1,13 @@
|
|
|
1
1
|
import { sortObject } from "../helpers/misc/sort-object.js";
|
|
2
2
|
import { getUniqueHash } from "../helpers/hash/unique.js";
|
|
3
3
|
|
|
4
|
-
const length = 6;
|
|
5
4
|
/**
|
|
6
5
|
* Get class name for CSS rules
|
|
7
6
|
*/
|
|
8
|
-
function createCSSClassName(rules,
|
|
7
|
+
function createCSSClassName(rules, options) {
|
|
9
8
|
return getUniqueHash(sortObject(rules), {
|
|
10
9
|
css: true,
|
|
11
|
-
length,
|
|
12
|
-
prefix,
|
|
10
|
+
length: 6,
|
|
13
11
|
...options
|
|
14
12
|
});
|
|
15
13
|
}
|
package/lib/css/types.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { UniqueHashPartialOptions } from "../helpers/hash/types.js";
|
|
2
2
|
/**
|
|
3
3
|
* CSS rules
|
|
4
4
|
*/
|
|
@@ -17,5 +17,5 @@ interface CSSKeyframes {
|
|
|
17
17
|
/**
|
|
18
18
|
* Hash options
|
|
19
19
|
*/
|
|
20
|
-
type CSSHashOptions =
|
|
20
|
+
type CSSHashOptions = UniqueHashPartialOptions;
|
|
21
21
|
export { CSSHashOptions, CSSKeyframe, CSSKeyframes, CSSRules };
|
|
@@ -1,8 +1,28 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Context for hashing functions, used to ensure uniqueness
|
|
3
|
+
*/
|
|
4
|
+
interface HashContext {
|
|
5
|
+
cache?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Length option for hash
|
|
9
|
+
*/
|
|
10
|
+
type LengthOption = number | ((content: string) => number);
|
|
11
|
+
/**
|
|
12
|
+
* Partial options, used for extending type
|
|
13
|
+
*/
|
|
14
|
+
interface UniqueHashPartialOptions {
|
|
15
|
+
context: HashContext;
|
|
2
16
|
prefix?: string;
|
|
3
|
-
|
|
4
|
-
length: number | ((content: string) => number);
|
|
17
|
+
length?: LengthOption;
|
|
5
18
|
lengths?: Record<string, number>;
|
|
6
19
|
throwOnCollision?: boolean;
|
|
7
20
|
}
|
|
8
|
-
|
|
21
|
+
/**
|
|
22
|
+
* Options for unique hash generation
|
|
23
|
+
*/
|
|
24
|
+
interface UniqueHashOptions extends UniqueHashPartialOptions {
|
|
25
|
+
css: boolean;
|
|
26
|
+
length: LengthOption;
|
|
27
|
+
}
|
|
28
|
+
export { HashContext, UniqueHashOptions, UniqueHashPartialOptions };
|
|
@@ -2,8 +2,6 @@ import { sortObject } from "../misc/sort-object.js";
|
|
|
2
2
|
import { hashToString } from "./stringify.js";
|
|
3
3
|
import { hashString } from "./hash.js";
|
|
4
4
|
|
|
5
|
-
const uniqueHashes = Object.create(null);
|
|
6
|
-
const uniqueWithPrefixHashes = Object.create(null);
|
|
7
5
|
/**
|
|
8
6
|
* Hash an object, make sure hash is unique
|
|
9
7
|
*
|
|
@@ -19,14 +17,15 @@ const uniqueWithPrefixHashes = Object.create(null);
|
|
|
19
17
|
* 8 chars = 183t unique hashes
|
|
20
18
|
*/
|
|
21
19
|
function getUniqueHash(data, options) {
|
|
22
|
-
const { length, lengths, css } = options;
|
|
20
|
+
const { length, lengths, css, context } = options;
|
|
23
21
|
const prefix = options.prefix || "";
|
|
24
22
|
const str = typeof data === "string" ? data : JSON.stringify(sortObject(data));
|
|
25
23
|
const hasPrefix = !!prefix;
|
|
26
24
|
const values = hashString(str);
|
|
27
25
|
let hash = hashToString(values, css, hasPrefix, typeof length === "function" ? length(str) : length);
|
|
28
26
|
if (lengths?.[hash]) hash = hashToString(values, css, hasPrefix, lengths[hash]);
|
|
29
|
-
|
|
27
|
+
if (!context.cache) context.cache = Object.create(null);
|
|
28
|
+
const cache = context.cache;
|
|
30
29
|
const result = `${prefix}${hash}`;
|
|
31
30
|
if (!cache[result]) cache[result] = str;
|
|
32
31
|
else if (cache[result] !== str) {
|
package/lib/index.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { ClassProp, classProps, defaultClassProp } from "./classname/const.js";
|
|
2
2
|
import { splitClassName, toggleClassName } from "./classname/toggle.js";
|
|
3
|
-
import { UniqueHashOptions } from "./helpers/hash/types.js";
|
|
3
|
+
import { HashContext, UniqueHashOptions, UniqueHashPartialOptions } from "./helpers/hash/types.js";
|
|
4
4
|
import { ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement, StringifyXMLOptions } from "./xml/types.js";
|
|
5
5
|
import { BaseConvertSVGContentOptions, ConvertSVGContentOptions, ConvertedSVGContent } from "./svg-css/types.js";
|
|
6
6
|
import { createCSSClassName } from "./css/hash.js";
|
|
7
7
|
import { stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector } from "./css/stringify.js";
|
|
8
|
+
import { createUniqueHashContext } from "./helpers/hash/context.js";
|
|
8
9
|
import { hashString } from "./helpers/hash/hash.js";
|
|
9
10
|
import { hashToString } from "./helpers/hash/stringify.js";
|
|
10
11
|
import { getUniqueHash } from "./helpers/hash/unique.js";
|
|
@@ -16,7 +17,7 @@ import { sortObject } from "./helpers/misc/sort-object.js";
|
|
|
16
17
|
import { iterateXMLContent } from "./xml/iterate.js";
|
|
17
18
|
import { parseXMLContent } from "./xml/parse.js";
|
|
18
19
|
import { stringifyXMLContent } from "./xml/stringify.js";
|
|
19
|
-
import { ChangeIDResult } from "./svg/ids/types.js";
|
|
20
|
+
import { ChangeIDResult, UniqueIDOptions } from "./svg/ids/types.js";
|
|
20
21
|
import { changeIDInString } from "./svg/ids/string.js";
|
|
21
22
|
import { removeDuplicateIDs } from "./svg/ids/duplicate.js";
|
|
22
23
|
import { removeUnusedIDs } from "./svg/ids/unused.js";
|
|
@@ -24,4 +25,4 @@ import { changeSVGIDs } from "./svg/ids/change.js";
|
|
|
24
25
|
import { createUniqueIDs } from "./svg/ids/unique.js";
|
|
25
26
|
import { convertSVGRootToCSS } from "./svg-css/root.js";
|
|
26
27
|
import { convertSVGContentToCSSRules } from "./svg-css/content.js";
|
|
27
|
-
export { BaseConvertSVGContentOptions, ChangeIDResult, ClassProp, ComparisonKey, ConvertSVGContentOptions, ConvertedSVGContent, ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement, StringifyXMLOptions, UniqueHashOptions, changeIDInString, changeSVGIDs, classProps, cloneObject, compareKeys, compareSets, compareValues, convertSVGContentToCSSRules, convertSVGRootToCSS, createCSSClassName, createUniqueIDs, defaultClassProp, getUniqueHash, hashString, hashToString, iterateXMLContent, parseXMLContent, removeDuplicateIDs, removeUnusedIDs, sortObject, splitClassName, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector, stringifyXMLContent, toggleClassName, uniquePromise };
|
|
28
|
+
export { BaseConvertSVGContentOptions, ChangeIDResult, ClassProp, ComparisonKey, ConvertSVGContentOptions, ConvertedSVGContent, HashContext, ParsedXMLNode, ParsedXMLTagElement, ParsedXMLTextElement, StringifyXMLOptions, UniqueHashOptions, UniqueHashPartialOptions, UniqueIDOptions, changeIDInString, changeSVGIDs, classProps, cloneObject, compareKeys, compareSets, compareValues, convertSVGContentToCSSRules, convertSVGRootToCSS, createCSSClassName, createUniqueHashContext, createUniqueIDs, defaultClassProp, getUniqueHash, hashString, hashToString, iterateXMLContent, parseXMLContent, removeDuplicateIDs, removeUnusedIDs, sortObject, splitClassName, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector, stringifyXMLContent, toggleClassName, uniquePromise };
|
package/lib/index.js
CHANGED
|
@@ -3,6 +3,7 @@ import { sortObject } from "./helpers/misc/sort-object.js";
|
|
|
3
3
|
import { compareSets, compareValues } from "./helpers/misc/compare.js";
|
|
4
4
|
import { compareKeys } from "./helpers/misc/keys.js";
|
|
5
5
|
import { uniquePromise } from "./helpers/misc/promises.js";
|
|
6
|
+
import { createUniqueHashContext } from "./helpers/hash/context.js";
|
|
6
7
|
import { hashToString } from "./helpers/hash/stringify.js";
|
|
7
8
|
import { hashString } from "./helpers/hash/hash.js";
|
|
8
9
|
import { getUniqueHash } from "./helpers/hash/unique.js";
|
|
@@ -21,4 +22,4 @@ import { createUniqueIDs } from "./svg/ids/unique.js";
|
|
|
21
22
|
import { convertSVGRootToCSS } from "./svg-css/root.js";
|
|
22
23
|
import { convertSVGContentToCSSRules } from "./svg-css/content.js";
|
|
23
24
|
|
|
24
|
-
export { changeIDInString, changeSVGIDs, classProps, cloneObject, compareKeys, compareSets, compareValues, convertSVGContentToCSSRules, convertSVGRootToCSS, createCSSClassName, createUniqueIDs, defaultClassProp, getUniqueHash, hashString, hashToString, iterateXMLContent, parseXMLContent, removeDuplicateIDs, removeUnusedIDs, sortObject, splitClassName, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector, stringifyXMLContent, toggleClassName, uniquePromise };
|
|
25
|
+
export { changeIDInString, changeSVGIDs, classProps, cloneObject, compareKeys, compareSets, compareValues, convertSVGContentToCSSRules, convertSVGRootToCSS, createCSSClassName, createUniqueHashContext, createUniqueIDs, defaultClassProp, getUniqueHash, hashString, hashToString, iterateXMLContent, parseXMLContent, removeDuplicateIDs, removeUnusedIDs, sortObject, splitClassName, stringifyCSSKeyframes, stringifyCSSRules, stringifyCSSSelector, stringifyXMLContent, toggleClassName, uniquePromise };
|
package/lib/svg/ids/change.js
CHANGED
|
@@ -40,8 +40,8 @@ function changeSVGIDs(root, callback) {
|
|
|
40
40
|
attrib,
|
|
41
41
|
id
|
|
42
42
|
});
|
|
43
|
-
[node, ...stack].forEach((node
|
|
44
|
-
const parentID = idMap.get(node
|
|
43
|
+
[node, ...stack].forEach((node) => {
|
|
44
|
+
const parentID = idMap.get(node);
|
|
45
45
|
if (parentID) {
|
|
46
46
|
const nested = nestedIDs.get(parentID) || [];
|
|
47
47
|
if (!nested.includes(id)) {
|
package/lib/svg/ids/types.d.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
|
+
import { UniqueHashPartialOptions } from "../../helpers/hash/types.js";
|
|
1
2
|
import { ParsedXMLTagElement } from "../../xml/types.js";
|
|
2
3
|
interface ChangeIDResult {
|
|
3
4
|
map: Record<string, ParsedXMLTagElement[]>;
|
|
4
5
|
usage: Record<string, ParsedXMLTagElement[]>;
|
|
5
6
|
}
|
|
6
|
-
|
|
7
|
+
type UniqueIDOptions = UniqueHashPartialOptions;
|
|
8
|
+
export { ChangeIDResult, UniqueIDOptions };
|
package/lib/svg/ids/unique.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ParsedXMLTagElement } from "../../xml/types.js";
|
|
2
|
+
import { UniqueIDOptions } from "./types.js";
|
|
2
3
|
/**
|
|
3
4
|
* Create unique IDs for SVG elements
|
|
4
5
|
*/
|
|
5
|
-
declare function createUniqueIDs(root: ParsedXMLTagElement[],
|
|
6
|
+
declare function createUniqueIDs(root: ParsedXMLTagElement[], options: UniqueIDOptions): void;
|
|
6
7
|
export { createUniqueIDs };
|
package/lib/svg/ids/unique.js
CHANGED
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
import { getUniqueHash } from "../../helpers/hash/unique.js";
|
|
2
2
|
import { changeSVGIDs } from "./change.js";
|
|
3
3
|
|
|
4
|
-
const length = 8;
|
|
5
|
-
const lengths = {};
|
|
6
4
|
/**
|
|
7
5
|
* Create unique IDs for SVG elements
|
|
8
6
|
*/
|
|
9
|
-
function createUniqueIDs(root,
|
|
7
|
+
function createUniqueIDs(root, options) {
|
|
10
8
|
changeSVGIDs(root, (id, content) => getUniqueHash(content, {
|
|
11
9
|
css: false,
|
|
12
|
-
prefix,
|
|
13
|
-
length,
|
|
14
|
-
|
|
10
|
+
prefix: "SVG",
|
|
11
|
+
length: 8,
|
|
12
|
+
...options
|
|
15
13
|
}));
|
|
16
14
|
}
|
|
17
15
|
|
package/lib/svg-css/content.d.ts
CHANGED
|
@@ -2,5 +2,5 @@ import { ConvertSVGContentOptions, ConvertedSVGContent } from "./types.js";
|
|
|
2
2
|
/**
|
|
3
3
|
* Convert SVG content string to SVG+CSS
|
|
4
4
|
*/
|
|
5
|
-
declare function convertSVGContentToCSSRules(content: string, options
|
|
5
|
+
declare function convertSVGContentToCSSRules(content: string, options: ConvertSVGContentOptions): ConvertedSVGContent;
|
|
6
6
|
export { convertSVGContentToCSSRules };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { iterateXMLContent } from "../../xml/iterate.js";
|
|
2
2
|
import { convertSVGPropertyToCSS } from "./prop.js";
|
|
3
|
-
import { svgAnimateTransformTag, svgAnimationTag, svgSetTag } from "
|
|
3
|
+
import { svgAnimateTransformTag, svgAnimationTag, svgSetTag } from "./tags.js";
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Extract SVG tag properties that can be converted to CSS
|
package/lib/svg-css/root.d.ts
CHANGED
|
@@ -6,5 +6,5 @@ import { BaseConvertSVGContentOptions } from "./types.js";
|
|
|
6
6
|
*
|
|
7
7
|
* Returns used CSS class names with rules
|
|
8
8
|
*/
|
|
9
|
-
declare function convertSVGRootToCSS(root: ParsedXMLTagElement[], options
|
|
9
|
+
declare function convertSVGRootToCSS(root: ParsedXMLTagElement[], options: BaseConvertSVGContentOptions): Record<string, CSSRules>;
|
|
10
10
|
export { convertSVGRootToCSS };
|
package/lib/svg-css/root.js
CHANGED
|
@@ -8,15 +8,13 @@ import { extractSVGTagPropertiesForCSS } from "./props/props.js";
|
|
|
8
8
|
*
|
|
9
9
|
* Returns used CSS class names with rules
|
|
10
10
|
*/
|
|
11
|
-
function convertSVGRootToCSS(root, options
|
|
11
|
+
function convertSVGRootToCSS(root, options) {
|
|
12
12
|
const rules = Object.create(null);
|
|
13
|
-
const hashOptions = options.hashOptions || {};
|
|
14
|
-
const classNamePrefix = options.classNamePrefix || "";
|
|
15
13
|
iterateXMLContent(root, (node) => {
|
|
16
14
|
if (node.type === "tag") {
|
|
17
15
|
const props = extractSVGTagPropertiesForCSS(node, options.legacy);
|
|
18
16
|
if (props) {
|
|
19
|
-
const className = createCSSClassName(props.rules,
|
|
17
|
+
const className = createCSSClassName(props.rules, options);
|
|
20
18
|
toggleClassName(node.attribs, className, true);
|
|
21
19
|
rules[className] = props.rules;
|
|
22
20
|
}
|
package/lib/svg-css/types.d.ts
CHANGED
|
@@ -3,9 +3,7 @@ import { StringifyXMLOptions } from "../xml/types.js";
|
|
|
3
3
|
/**
|
|
4
4
|
* Options for converting SVG tags to SVG+CSS
|
|
5
5
|
*/
|
|
6
|
-
interface BaseConvertSVGContentOptions {
|
|
7
|
-
classNamePrefix?: string;
|
|
8
|
-
hashOptions?: CSSHashOptions;
|
|
6
|
+
interface BaseConvertSVGContentOptions extends CSSHashOptions {
|
|
9
7
|
legacy?: boolean;
|
|
10
8
|
}
|
|
11
9
|
/**
|
package/lib/xml/parse.js
CHANGED
|
@@ -16,9 +16,9 @@ function parseXMLContent(content, trim = true) {
|
|
|
16
16
|
return rootNodes;
|
|
17
17
|
}
|
|
18
18
|
if (content.slice(start, start + 4) === "<!--") {
|
|
19
|
-
const end
|
|
20
|
-
if (end
|
|
21
|
-
startIndex = end
|
|
19
|
+
const end = content.indexOf("-->", start);
|
|
20
|
+
if (end === -1) return null;
|
|
21
|
+
startIndex = end + 3;
|
|
22
22
|
continue;
|
|
23
23
|
}
|
|
24
24
|
const rawText = content.slice(startIndex, start);
|
|
@@ -34,8 +34,8 @@ function parseXMLContent(content, trim = true) {
|
|
|
34
34
|
let tagContent = content.slice(start + 1, end).trim();
|
|
35
35
|
if (tagContent.startsWith("/")) {
|
|
36
36
|
if (!parentNode) return null;
|
|
37
|
-
const tagNameMatch
|
|
38
|
-
if (parentNode.tag !== tagNameMatch
|
|
37
|
+
const tagNameMatch = tagContent.slice(1).match(/^[^\s]+/);
|
|
38
|
+
if (parentNode.tag !== tagNameMatch?.[0]) return null;
|
|
39
39
|
stack.pop();
|
|
40
40
|
parentNode = stack.length ? stack[stack.length - 1] : null;
|
|
41
41
|
startIndex = end + 1;
|
|
@@ -65,16 +65,16 @@ function parseXMLContent(content, trim = true) {
|
|
|
65
65
|
}
|
|
66
66
|
startIndex = end + 1;
|
|
67
67
|
if (tagName === "style" && !selfClosing) {
|
|
68
|
-
const end
|
|
69
|
-
if (end
|
|
70
|
-
const css = content.slice(startIndex, end
|
|
68
|
+
const end = content.indexOf("</style>", startIndex);
|
|
69
|
+
if (end === -1) return null;
|
|
70
|
+
const css = content.slice(startIndex, end).trim();
|
|
71
71
|
if (css.length) parentNode.children.push({
|
|
72
72
|
type: "text",
|
|
73
73
|
content: css
|
|
74
74
|
});
|
|
75
75
|
stack.pop();
|
|
76
76
|
parentNode = stack.length ? stack[stack.length - 1] : null;
|
|
77
|
-
startIndex = end
|
|
77
|
+
startIndex = end + 8;
|
|
78
78
|
}
|
|
79
79
|
} while (true);
|
|
80
80
|
}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"type": "module",
|
|
4
4
|
"description": "Common functions for working with SVG used by various packages.",
|
|
5
5
|
"author": "Vjacheslav Trushkin",
|
|
6
|
-
"version": "1.
|
|
6
|
+
"version": "1.1.1",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"bugs": "https://github.com/cyberalien/svg-utils/issues",
|
|
9
9
|
"homepage": "https://cyberalien.dev/",
|
|
@@ -23,18 +23,18 @@
|
|
|
23
23
|
"@iconify/types": "^2.0.0"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@eslint/eslintrc": "^3.3.
|
|
27
|
-
"@eslint/js": "^9.39.
|
|
28
|
-
"@iconify-json/ri": "^1.2.
|
|
26
|
+
"@eslint/eslintrc": "^3.3.3",
|
|
27
|
+
"@eslint/js": "^9.39.2",
|
|
28
|
+
"@iconify-json/ri": "^1.2.8",
|
|
29
29
|
"@types/jest": "^30.0.0",
|
|
30
|
-
"@types/node": "^
|
|
31
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
32
|
-
"@typescript-eslint/parser": "^8.
|
|
33
|
-
"eslint": "^9.39.
|
|
34
|
-
"globals": "^
|
|
35
|
-
"tsdown": "^0.
|
|
30
|
+
"@types/node": "^25.1.0",
|
|
31
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
32
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
33
|
+
"eslint": "^9.39.2",
|
|
34
|
+
"globals": "^17.2.0",
|
|
35
|
+
"tsdown": "^0.20.1",
|
|
36
36
|
"typescript": "^5.9.3",
|
|
37
|
-
"vitest": "^4.0.
|
|
37
|
+
"vitest": "^4.0.18"
|
|
38
38
|
},
|
|
39
39
|
"scripts": {
|
|
40
40
|
"lint": "eslint --fix src/**/*.ts && tsc --noemit",
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { ParsedXMLTagElement } from "../../xml/types.js";
|
|
2
|
-
import { getSVGPropertyType } from "../props/prop.js";
|
|
3
|
-
interface CheckResult {
|
|
4
|
-
attributeName: string;
|
|
5
|
-
type: ReturnType<typeof getSVGPropertyType>;
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* Get animated attribute name and type
|
|
9
|
-
*/
|
|
10
|
-
declare function getAnimatedAttributeData(node: ParsedXMLTagElement, stack: ParsedXMLTagElement[], supportLegacyBrowsers?: boolean): undefined | CheckResult;
|
|
11
|
-
export { getAnimatedAttributeData };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { getSVGPropertyType } from "../props/prop.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Get animated attribute name and type
|
|
5
|
-
*/
|
|
6
|
-
function getAnimatedAttributeData(node, stack, supportLegacyBrowsers) {
|
|
7
|
-
const parentNode = stack[stack.length - 1];
|
|
8
|
-
if (!parentNode) return;
|
|
9
|
-
const parentTag = parentNode.tag;
|
|
10
|
-
const attributeName = node.attribs.attributeName;
|
|
11
|
-
if (typeof attributeName !== "string") return;
|
|
12
|
-
const type = getSVGPropertyType(parentTag, attributeName, supportLegacyBrowsers);
|
|
13
|
-
return type ? {
|
|
14
|
-
attributeName,
|
|
15
|
-
type
|
|
16
|
-
} : void 0;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export { getAnimatedAttributeData };
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { ParsedXMLTagElement } from "../../xml/types.js";
|
|
2
|
-
/**
|
|
3
|
-
* Check for common failures
|
|
4
|
-
*
|
|
5
|
-
* Returns true on success
|
|
6
|
-
*/
|
|
7
|
-
declare function checkAnimationTagForCompatibility(node: ParsedXMLTagElement): boolean | undefined;
|
|
8
|
-
export { checkAnimationTagForCompatibility };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
const supportedValues = {
|
|
2
|
-
additive: "replace",
|
|
3
|
-
accumulate: "none"
|
|
4
|
-
};
|
|
5
|
-
/**
|
|
6
|
-
* Check for common failures
|
|
7
|
-
*
|
|
8
|
-
* Returns true on success
|
|
9
|
-
*/
|
|
10
|
-
function checkAnimationTagForCompatibility(node) {
|
|
11
|
-
if (node.children.length) return;
|
|
12
|
-
const attribs = node.attribs;
|
|
13
|
-
for (const attr in supportedValues) if (attribs[attr] && attribs[attr] !== supportedValues[attr]) return;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { checkAnimationTagForCompatibility };
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { ParsedXMLTagElement } from "../../xml/types.js";
|
|
2
|
-
import { FindSVGAnimationsOptions, SVGAnimationsContext } from "./types.js";
|
|
3
|
-
/**
|
|
4
|
-
* Find all animations in SVG tree
|
|
5
|
-
*
|
|
6
|
-
* @todo Implement this
|
|
7
|
-
*/
|
|
8
|
-
declare function findAnimationsInSVGTree(root: ParsedXMLTagElement[], options: FindSVGAnimationsOptions): SVGAnimationsContext;
|
|
9
|
-
export { findAnimationsInSVGTree };
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { iterateXMLContent } from "../../xml/iterate.js";
|
|
2
|
-
import { svgAnimateMotionTag, svgAnimateTransformTag, svgAnimationTag, svgSetTag } from "./tags.js";
|
|
3
|
-
import { getAnimatedAttributeData } from "./attribute.js";
|
|
4
|
-
import { checkAnimationTagForCompatibility } from "./common.js";
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Find all animations in SVG tree
|
|
8
|
-
*
|
|
9
|
-
* @todo Implement this
|
|
10
|
-
*/
|
|
11
|
-
function findAnimationsInSVGTree(root, options) {
|
|
12
|
-
const animatedProperties = /* @__PURE__ */ new Map();
|
|
13
|
-
let failed = false;
|
|
14
|
-
const context = {
|
|
15
|
-
failed,
|
|
16
|
-
animatedProperties
|
|
17
|
-
};
|
|
18
|
-
iterateXMLContent(root, (node, stack) => {
|
|
19
|
-
if (context.failed || node.type !== "tag") return;
|
|
20
|
-
switch (node.tag) {
|
|
21
|
-
case svgAnimateMotionTag:
|
|
22
|
-
failed = true;
|
|
23
|
-
return "abort";
|
|
24
|
-
case svgAnimateTransformTag:
|
|
25
|
-
if (!checkAnimationTagForCompatibility(node)) {
|
|
26
|
-
failed = true;
|
|
27
|
-
return "abort";
|
|
28
|
-
}
|
|
29
|
-
failed = true;
|
|
30
|
-
return "abort";
|
|
31
|
-
case svgSetTag:
|
|
32
|
-
case svgAnimationTag:
|
|
33
|
-
if (!checkAnimationTagForCompatibility(node)) {
|
|
34
|
-
failed = true;
|
|
35
|
-
return "abort";
|
|
36
|
-
}
|
|
37
|
-
break;
|
|
38
|
-
default: return;
|
|
39
|
-
}
|
|
40
|
-
if (!getAnimatedAttributeData(node, stack, options.supportLegacyBrowsers)) {
|
|
41
|
-
failed = true;
|
|
42
|
-
return "abort";
|
|
43
|
-
}
|
|
44
|
-
});
|
|
45
|
-
return failed ? { failed: true } : context;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export { findAnimationsInSVGTree };
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { ParsedXMLTagElement } from "../../xml/types.js";
|
|
2
|
-
/**
|
|
3
|
-
* SVG animations context
|
|
4
|
-
*/
|
|
5
|
-
interface FailedSVGAnimationsContext {
|
|
6
|
-
failed: true;
|
|
7
|
-
}
|
|
8
|
-
interface SuccessfulSVGAnimationsContext {
|
|
9
|
-
failed: false;
|
|
10
|
-
animatedProperties: Map<ParsedXMLTagElement, Set<string>>;
|
|
11
|
-
}
|
|
12
|
-
type SVGAnimationsContext = FailedSVGAnimationsContext | SuccessfulSVGAnimationsContext;
|
|
13
|
-
/**
|
|
14
|
-
* Options for finding animations in SVG tree
|
|
15
|
-
*/
|
|
16
|
-
interface FindSVGAnimationsOptions {
|
|
17
|
-
supportLegacyBrowsers?: boolean;
|
|
18
|
-
}
|
|
19
|
-
export { FindSVGAnimationsOptions, SVGAnimationsContext };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { };
|
|
File without changes
|
|
File without changes
|