svg-toolbox 1.1.11 → 1.2.0
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/README.md +156 -118
- package/es/analyze/__tests__/colors.test.d.ts +1 -0
- package/es/analyze/__tests__/colors.test.js +44 -0
- package/es/analyze/__tests__/colors.test.js.map +1 -0
- package/es/analyze/__tests__/paths.test.d.ts +1 -0
- package/es/analyze/__tests__/paths.test.js +71 -0
- package/es/analyze/__tests__/paths.test.js.map +1 -0
- package/es/analyze/colors.d.ts +8 -0
- package/es/analyze/colors.js +55 -0
- package/es/analyze/colors.js.map +1 -0
- package/es/analyze/paths.d.ts +20 -0
- package/es/analyze/paths.js +92 -0
- package/es/analyze/paths.js.map +1 -0
- package/es/compare/__tests__/diff.test.d.ts +1 -0
- package/es/compare/__tests__/diff.test.js +64 -0
- package/es/compare/__tests__/diff.test.js.map +1 -0
- package/es/compare/diff.d.ts +18 -0
- package/es/compare/diff.js +70 -0
- package/es/compare/diff.js.map +1 -0
- package/es/convert/__tests__/base64.test.d.ts +1 -0
- package/es/convert/__tests__/base64.test.js +49 -0
- package/es/convert/__tests__/base64.test.js.map +1 -0
- package/es/convert/base64.d.ts +11 -0
- package/es/convert/base64.js +38 -0
- package/es/convert/base64.js.map +1 -0
- package/es/convert/image.d.ts +18 -0
- package/es/convert/image.js +63 -0
- package/es/convert/image.js.map +1 -0
- package/es/core/__tests__/dimensions.test.d.ts +1 -0
- package/es/core/__tests__/dimensions.test.js +40 -0
- package/es/core/__tests__/dimensions.test.js.map +1 -0
- package/es/core/__tests__/element.test.d.ts +1 -0
- package/es/core/__tests__/element.test.js +79 -0
- package/es/core/__tests__/element.test.js.map +1 -0
- package/es/core/dimensions.d.ts +8 -0
- package/es/core/dimensions.js +34 -0
- package/es/core/dimensions.js.map +1 -0
- package/es/core/element.d.ts +24 -0
- package/es/core/element.js +52 -0
- package/es/core/element.js.map +1 -0
- package/es/index.d.ts +15 -10
- package/es/index.js +21 -10
- package/es/index.js.map +1 -1
- package/es/optimize/__tests__/cleanup.test.d.ts +1 -0
- package/es/optimize/__tests__/cleanup.test.js +95 -0
- package/es/optimize/__tests__/cleanup.test.js.map +1 -0
- package/es/optimize/__tests__/path.test.d.ts +1 -0
- package/es/optimize/__tests__/path.test.js +41 -0
- package/es/optimize/__tests__/path.test.js.map +1 -0
- package/es/optimize/cleanup.d.ts +27 -0
- package/es/optimize/cleanup.js +100 -0
- package/es/optimize/cleanup.js.map +1 -0
- package/es/optimize/path.d.ts +7 -0
- package/es/optimize/path.js +58 -0
- package/es/optimize/path.js.map +1 -0
- package/es/types/index.d.ts +31 -0
- package/es/types/index.js +5 -0
- package/es/types/index.js.map +1 -0
- package/es/utils/__tests__/path-validation.test.d.ts +1 -0
- package/es/utils/__tests__/path-validation.test.js +64 -0
- package/es/utils/__tests__/path-validation.test.js.map +1 -0
- package/es/utils/__tests__/validation.test.d.ts +1 -0
- package/es/utils/__tests__/validation.test.js +42 -0
- package/es/utils/__tests__/validation.test.js.map +1 -0
- package/es/utils/dom.d.ts +23 -0
- package/es/utils/dom.js +25 -0
- package/es/utils/dom.js.map +1 -0
- package/es/utils/path-validation.d.ts +29 -0
- package/es/utils/path-validation.js +101 -0
- package/es/utils/path-validation.js.map +1 -0
- package/es/utils/validation.d.ts +11 -0
- package/es/utils/validation.js +30 -0
- package/es/utils/validation.js.map +1 -0
- package/lib/analyze/__tests__/colors.test.d.ts +1 -0
- package/lib/analyze/__tests__/colors.test.js +46 -0
- package/lib/analyze/__tests__/colors.test.js.map +1 -0
- package/lib/analyze/__tests__/paths.test.d.ts +1 -0
- package/lib/analyze/__tests__/paths.test.js +73 -0
- package/lib/analyze/__tests__/paths.test.js.map +1 -0
- package/lib/analyze/colors.d.ts +8 -0
- package/lib/analyze/colors.js +58 -0
- package/lib/analyze/colors.js.map +1 -0
- package/lib/analyze/paths.d.ts +20 -0
- package/lib/analyze/paths.js +97 -0
- package/lib/analyze/paths.js.map +1 -0
- package/lib/compare/__tests__/diff.test.d.ts +1 -0
- package/lib/compare/__tests__/diff.test.js +128 -0
- package/lib/compare/__tests__/diff.test.js.map +1 -0
- package/lib/compare/diff.d.ts +18 -0
- package/lib/compare/diff.js +134 -0
- package/lib/compare/diff.js.map +1 -0
- package/lib/convert/__tests__/base64.test.d.ts +1 -0
- package/lib/convert/__tests__/base64.test.js +51 -0
- package/lib/convert/__tests__/base64.test.js.map +1 -0
- package/lib/convert/base64.d.ts +11 -0
- package/lib/convert/base64.js +42 -0
- package/lib/convert/base64.js.map +1 -0
- package/lib/convert/image.d.ts +18 -0
- package/lib/{extra-apply/applySvg2Png.js → convert/image.js} +62 -53
- package/lib/convert/image.js.map +1 -0
- package/lib/core/__tests__/dimensions.test.d.ts +1 -0
- package/lib/core/__tests__/dimensions.test.js +42 -0
- package/lib/core/__tests__/dimensions.test.js.map +1 -0
- package/lib/core/__tests__/element.test.d.ts +1 -0
- package/lib/core/__tests__/element.test.js +81 -0
- package/lib/core/__tests__/element.test.js.map +1 -0
- package/lib/core/dimensions.d.ts +8 -0
- package/lib/core/dimensions.js +37 -0
- package/lib/core/dimensions.js.map +1 -0
- package/lib/core/element.d.ts +24 -0
- package/lib/core/element.js +58 -0
- package/lib/core/element.js.map +1 -0
- package/lib/index.d.ts +15 -10
- package/lib/index.js +48 -20
- package/lib/index.js.map +1 -1
- package/lib/optimize/__tests__/cleanup.test.d.ts +1 -0
- package/lib/optimize/__tests__/cleanup.test.js +97 -0
- package/lib/optimize/__tests__/cleanup.test.js.map +1 -0
- package/lib/optimize/__tests__/path.test.d.ts +1 -0
- package/lib/optimize/__tests__/path.test.js +43 -0
- package/lib/optimize/__tests__/path.test.js.map +1 -0
- package/lib/optimize/cleanup.d.ts +27 -0
- package/lib/optimize/cleanup.js +106 -0
- package/lib/optimize/cleanup.js.map +1 -0
- package/lib/optimize/path.d.ts +7 -0
- package/lib/optimize/path.js +63 -0
- package/lib/optimize/path.js.map +1 -0
- package/lib/types/index.d.ts +31 -0
- package/lib/types/index.js +6 -0
- package/lib/types/index.js.map +1 -0
- package/lib/utils/__tests__/path-validation.test.d.ts +1 -0
- package/lib/utils/__tests__/path-validation.test.js +69 -0
- package/lib/utils/__tests__/path-validation.test.js.map +1 -0
- package/lib/utils/__tests__/validation.test.d.ts +1 -0
- package/lib/utils/__tests__/validation.test.js +44 -0
- package/lib/utils/__tests__/validation.test.js.map +1 -0
- package/lib/utils/dom.d.ts +23 -0
- package/lib/utils/dom.js +31 -0
- package/lib/utils/dom.js.map +1 -0
- package/lib/utils/path-validation.d.ts +29 -0
- package/lib/utils/path-validation.js +109 -0
- package/lib/utils/path-validation.js.map +1 -0
- package/lib/utils/validation.d.ts +11 -0
- package/lib/utils/validation.js +35 -0
- package/lib/utils/validation.js.map +1 -0
- package/package.json +17 -4
- package/es/common.d.ts +0 -68
- package/es/common.js +0 -110
- package/es/common.js.map +0 -1
- package/es/extra-apply/applyDiffSvg.d.ts +0 -11
- package/es/extra-apply/applyDiffSvg.js +0 -63
- package/es/extra-apply/applyDiffSvg.js.map +0 -1
- package/es/extra-apply/applyRemoveNanCoordinates.d.ts +0 -6
- package/es/extra-apply/applyRemoveNanCoordinates.js +0 -75
- package/es/extra-apply/applyRemoveNanCoordinates.js.map +0 -1
- package/es/extra-apply/applySvg2Png.d.ts +0 -16
- package/es/extra-apply/applySvg2Png.js +0 -64
- package/es/extra-apply/applySvg2Png.js.map +0 -1
- package/es/utils/pixelLevelDiffPng.d.ts +0 -4
- package/es/utils/pixelLevelDiffPng.js +0 -29
- package/es/utils/pixelLevelDiffPng.js.map +0 -1
- package/es/validate.d.ts +0 -14
- package/es/validate.js +0 -44
- package/es/validate.js.map +0 -1
- package/lib/common.d.ts +0 -68
- package/lib/common.js +0 -117
- package/lib/common.js.map +0 -1
- package/lib/extra-apply/applyDiffSvg.d.ts +0 -11
- package/lib/extra-apply/applyDiffSvg.js +0 -116
- package/lib/extra-apply/applyDiffSvg.js.map +0 -1
- package/lib/extra-apply/applyRemoveNanCoordinates.d.ts +0 -6
- package/lib/extra-apply/applyRemoveNanCoordinates.js +0 -78
- package/lib/extra-apply/applyRemoveNanCoordinates.js.map +0 -1
- package/lib/extra-apply/applySvg2Png.d.ts +0 -16
- package/lib/extra-apply/applySvg2Png.js.map +0 -1
- package/lib/utils/pixelLevelDiffPng.d.ts +0 -4
- package/lib/utils/pixelLevelDiffPng.js +0 -36
- package/lib/utils/pixelLevelDiffPng.js.map +0 -1
- package/lib/validate.d.ts +0 -14
- package/lib/validate.js +0 -48
- package/lib/validate.js.map +0 -1
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG dimensions and viewBox utilities
|
|
3
|
+
*/
|
|
4
|
+
import { isValidSvgString } from '../utils/validation';
|
|
5
|
+
import { serializeSVG } from './element';
|
|
6
|
+
/**
|
|
7
|
+
* Extracts dimensions from an SVG element or string
|
|
8
|
+
*/
|
|
9
|
+
export function getSVGDimensions(svgContent) {
|
|
10
|
+
const svgString = isValidSvgString(svgContent)
|
|
11
|
+
? svgContent
|
|
12
|
+
: serializeSVG(svgContent);
|
|
13
|
+
const viewBoxRegex = /viewBox=["']?(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)\s+(\d+(?:\.\d+)?)["']?/i;
|
|
14
|
+
const widthRegex = /width=["']?(\d+(?:\.\d+)?)/i;
|
|
15
|
+
const heightRegex = /height=["']?(\d+(?:\.\d+)?)/i;
|
|
16
|
+
const viewBoxMatch = svgString.match(viewBoxRegex);
|
|
17
|
+
const widthMatch = svgString.match(widthRegex);
|
|
18
|
+
const heightMatch = svgString.match(heightRegex);
|
|
19
|
+
let width;
|
|
20
|
+
let height;
|
|
21
|
+
let viewBox;
|
|
22
|
+
if (viewBoxMatch) {
|
|
23
|
+
const [, x, y, w, h] = viewBoxMatch.map(Number);
|
|
24
|
+
viewBox = { x, y, width: w, height: h };
|
|
25
|
+
width = w;
|
|
26
|
+
height = h;
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
width = widthMatch ? Number(widthMatch[1]) : 0;
|
|
30
|
+
height = heightMatch ? Number(heightMatch[1]) : 0;
|
|
31
|
+
}
|
|
32
|
+
return { width, height, viewBox };
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=dimensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dimensions.js","sourceRoot":"","sources":["../../src/core/dimensions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAqB,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAA4B;IAC3D,MAAM,SAAS,GAAG,gBAAgB,CAAC,UAAU,CAAC;QAC5C,CAAC,CAAC,UAAU;QACZ,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC;IAE7B,MAAM,YAAY,GAAG,0FAA0F,CAAC;IAChH,MAAM,UAAU,GAAG,6BAA6B,CAAC;IACjD,MAAM,WAAW,GAAG,8BAA8B,CAAC;IAEnD,MAAM,YAAY,GAAG,SAAS,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IAC/C,MAAM,WAAW,GAAG,SAAS,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;IAEjD,IAAI,KAAa,CAAC;IAClB,IAAI,MAAc,CAAC;IACnB,IAAI,OAAiC,CAAC;IAEtC,IAAI,YAAY,EAAE,CAAC;QACjB,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAChD,OAAO,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC;QACxC,KAAK,GAAG,CAAC,CAAC;QACV,MAAM,GAAG,CAAC,CAAC;IACb,CAAC;SAAM,CAAC;QACN,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AACpC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core SVG element manipulation functions
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Creates an SVG element from a given SVG content string
|
|
6
|
+
*/
|
|
7
|
+
export declare function createSVGElement(svgContent: string): Element;
|
|
8
|
+
/**
|
|
9
|
+
* Clones an SVG element deeply
|
|
10
|
+
*
|
|
11
|
+
* This function serializes the SVG element to a string, then parses it back
|
|
12
|
+
* to create a deep clone, ensuring all attributes and child nodes are duplicated.
|
|
13
|
+
*/
|
|
14
|
+
export declare function cloneSVGElement(element: Element): Element;
|
|
15
|
+
/**
|
|
16
|
+
* Merges multiple SVG elements into a single SVG element
|
|
17
|
+
*
|
|
18
|
+
* Creates a new SVG element and appends clones of the provided elements to it.
|
|
19
|
+
*/
|
|
20
|
+
export declare function mergeSVGElements(elements: Element[]): Element;
|
|
21
|
+
/**
|
|
22
|
+
* Serializes an SVG element or string to a string representation
|
|
23
|
+
*/
|
|
24
|
+
export declare function serializeSVG(svgContent: Element | string): string;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core SVG element manipulation functions
|
|
3
|
+
*/
|
|
4
|
+
import { createDOMParser, createXMLSerializer, SVG_NAMESPACE, document } from '../utils/dom';
|
|
5
|
+
import { isValidSvgString, isValidSvgElement } from '../utils/validation';
|
|
6
|
+
/**
|
|
7
|
+
* Creates an SVG element from a given SVG content string
|
|
8
|
+
*/
|
|
9
|
+
export function createSVGElement(svgContent) {
|
|
10
|
+
const parser = createDOMParser();
|
|
11
|
+
const svgElement = parser.parseFromString(svgContent, 'image/svg+xml').documentElement;
|
|
12
|
+
return svgElement;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Clones an SVG element deeply
|
|
16
|
+
*
|
|
17
|
+
* This function serializes the SVG element to a string, then parses it back
|
|
18
|
+
* to create a deep clone, ensuring all attributes and child nodes are duplicated.
|
|
19
|
+
*/
|
|
20
|
+
export function cloneSVGElement(element) {
|
|
21
|
+
const serializer = createXMLSerializer();
|
|
22
|
+
const sourceCode = serializer.serializeToString(element);
|
|
23
|
+
const parser = createDOMParser();
|
|
24
|
+
const doc = parser.parseFromString(sourceCode, 'image/svg+xml');
|
|
25
|
+
return doc.documentElement;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Merges multiple SVG elements into a single SVG element
|
|
29
|
+
*
|
|
30
|
+
* Creates a new SVG element and appends clones of the provided elements to it.
|
|
31
|
+
*/
|
|
32
|
+
export function mergeSVGElements(elements) {
|
|
33
|
+
const mergedSVG = document.createElementNS(SVG_NAMESPACE, 'svg');
|
|
34
|
+
elements.forEach((element) => {
|
|
35
|
+
mergedSVG.appendChild(cloneSVGElement(element));
|
|
36
|
+
});
|
|
37
|
+
return mergedSVG;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Serializes an SVG element or string to a string representation
|
|
41
|
+
*/
|
|
42
|
+
export function serializeSVG(svgContent) {
|
|
43
|
+
if (isValidSvgString(svgContent)) {
|
|
44
|
+
return svgContent;
|
|
45
|
+
}
|
|
46
|
+
if (isValidSvgElement(svgContent)) {
|
|
47
|
+
const serializer = createXMLSerializer();
|
|
48
|
+
return serializer.serializeToString(svgContent);
|
|
49
|
+
}
|
|
50
|
+
throw new Error('The provided content is not a valid SVG string or SVG element.');
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=element.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"element.js","sourceRoot":"","sources":["../../src/core/element.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7F,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAE1E;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,UAAkB;IACjD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,UAAU,GAAG,MAAM,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,eAAe,CAAC;IACvF,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAAC,OAAgB;IAC9C,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;IACzC,MAAM,UAAU,GAAG,UAAU,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,MAAM,GAAG,eAAe,EAAE,CAAC;IACjC,MAAM,GAAG,GAAG,MAAM,CAAC,eAAe,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;IAChE,OAAO,GAAG,CAAC,eAAe,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,QAAmB;IAClD,MAAM,SAAS,GAAG,QAAQ,CAAC,eAAe,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC;IACjE,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC3B,SAAS,CAAC,WAAW,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IACH,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,UAA4B;IACvD,IAAI,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC;QACjC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,mBAAmB,EAAE,CAAC;QACzC,OAAO,UAAU,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IAClD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;AACpF,CAAC"}
|
package/es/index.d.ts
CHANGED
|
@@ -1,12 +1,17 @@
|
|
|
1
|
-
import svg2Png from './extra-apply/applySvg2Png';
|
|
2
|
-
import diffSvg from './extra-apply/applyDiffSvg';
|
|
3
|
-
import removeNanCoordinates from './extra-apply/applyRemoveNanCoordinates';
|
|
4
|
-
import { createSVGElement, cloneSVGElement, mergeSVGElements, convertSVGToBase64, convertBase64ToSVG } from './common';
|
|
5
|
-
import pixelLevelDiffPng from './utils/pixelLevelDiffPng';
|
|
6
|
-
declare const removeEmptyCoordinates: typeof removeNanCoordinates;
|
|
7
|
-
export { svg2Png, diffSvg,
|
|
8
1
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
2
|
+
* SVG Toolbox - A comprehensive library for SVG manipulation and analysis
|
|
3
|
+
*
|
|
4
|
+
* @module svg-toolbox
|
|
11
5
|
*/
|
|
12
|
-
|
|
6
|
+
export { createSVGElement, cloneSVGElement, mergeSVGElements, serializeSVG } from './core/element';
|
|
7
|
+
export { getSVGDimensions } from './core/dimensions';
|
|
8
|
+
export { convertSVGToBase64, convertBase64ToSVG } from './convert/base64';
|
|
9
|
+
export { svgToImage, svg2Png } from './convert/image';
|
|
10
|
+
export { pixelLevelDiff, diffImages, diffSvg } from './compare/diff';
|
|
11
|
+
export { removeNanCoordinates } from './optimize/path';
|
|
12
|
+
export { removeEmptyAttributes, removeComments, normalizeWhitespace, optimizeSVG } from './optimize/cleanup';
|
|
13
|
+
export { extractColors } from './analyze/colors';
|
|
14
|
+
export { parsePathData, analyzePaths, getPathStatistics } from './analyze/paths';
|
|
15
|
+
export { isValidSvgString, isValidSvgElement } from './utils/validation';
|
|
16
|
+
export type { SVGDimensions, DiffResult, ConversionOptions, PathCommand, SVGColor } from './types';
|
|
17
|
+
export { removeNanCoordinates as removeEmptyCoordinates } from './optimize/path';
|
package/es/index.js
CHANGED
|
@@ -1,13 +1,24 @@
|
|
|
1
|
-
import svg2Png from './extra-apply/applySvg2Png';
|
|
2
|
-
import diffSvg from './extra-apply/applyDiffSvg';
|
|
3
|
-
import removeNanCoordinates from './extra-apply/applyRemoveNanCoordinates';
|
|
4
|
-
import { createSVGElement, cloneSVGElement, mergeSVGElements, convertSVGToBase64, convertBase64ToSVG } from './common';
|
|
5
|
-
import pixelLevelDiffPng from './utils/pixelLevelDiffPng';
|
|
6
|
-
const removeEmptyCoordinates = removeNanCoordinates;
|
|
7
|
-
export { svg2Png, diffSvg,
|
|
8
1
|
/**
|
|
9
|
-
*
|
|
10
|
-
*
|
|
2
|
+
* SVG Toolbox - A comprehensive library for SVG manipulation and analysis
|
|
3
|
+
*
|
|
4
|
+
* @module svg-toolbox
|
|
11
5
|
*/
|
|
12
|
-
|
|
6
|
+
// Core element manipulation
|
|
7
|
+
export { createSVGElement, cloneSVGElement, mergeSVGElements, serializeSVG } from './core/element';
|
|
8
|
+
export { getSVGDimensions } from './core/dimensions';
|
|
9
|
+
// Conversion utilities
|
|
10
|
+
export { convertSVGToBase64, convertBase64ToSVG } from './convert/base64';
|
|
11
|
+
export { svgToImage, svg2Png } from './convert/image';
|
|
12
|
+
// Comparison utilities
|
|
13
|
+
export { pixelLevelDiff, diffImages, diffSvg } from './compare/diff';
|
|
14
|
+
// Optimization utilities
|
|
15
|
+
export { removeNanCoordinates } from './optimize/path';
|
|
16
|
+
export { removeEmptyAttributes, removeComments, normalizeWhitespace, optimizeSVG } from './optimize/cleanup';
|
|
17
|
+
// Analysis utilities
|
|
18
|
+
export { extractColors } from './analyze/colors';
|
|
19
|
+
export { parsePathData, analyzePaths, getPathStatistics } from './analyze/paths';
|
|
20
|
+
// Validation utilities
|
|
21
|
+
export { isValidSvgString, isValidSvgElement } from './utils/validation';
|
|
22
|
+
// Legacy exports for backward compatibility
|
|
23
|
+
export { removeNanCoordinates as removeEmptyCoordinates } from './optimize/path';
|
|
13
24
|
//# sourceMappingURL=index.js.map
|
package/es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,4BAA4B;AAC5B,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,YAAY,EACb,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,uBAAuB;AACvB,OAAO,EACL,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,UAAU,EACV,OAAO,EACR,MAAM,iBAAiB,CAAC;AAEzB,uBAAuB;AACvB,OAAO,EACL,cAAc,EACd,UAAU,EACV,OAAO,EACR,MAAM,gBAAgB,CAAC;AAExB,yBAAyB;AACzB,OAAO,EACL,oBAAoB,EACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,qBAAqB,EACrB,cAAc,EACd,mBAAmB,EACnB,WAAW,EACZ,MAAM,oBAAoB,CAAC;AAE5B,qBAAqB;AACrB,OAAO,EACL,aAAa,EACd,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,uBAAuB;AACvB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,oBAAoB,CAAC;AAW5B,4CAA4C;AAC5C,OAAO,EAAE,oBAAoB,IAAI,sBAAsB,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { removeEmptyAttributes, removeComments, normalizeWhitespace, optimizeSVG } from '../cleanup';
|
|
2
|
+
import { createSVGElement } from '../../core/element';
|
|
3
|
+
describe('SVG Cleanup', () => {
|
|
4
|
+
describe('removeEmptyAttributes', () => {
|
|
5
|
+
it('should remove empty attributes', () => {
|
|
6
|
+
const svgContent = '<svg><circle cx="50" cy="50" r="" fill="red" stroke="" /></svg>';
|
|
7
|
+
const result = removeEmptyAttributes(svgContent);
|
|
8
|
+
expect(result).toContain('cx="50"');
|
|
9
|
+
expect(result).toContain('fill="red"');
|
|
10
|
+
expect(result).not.toContain('r=""');
|
|
11
|
+
expect(result).not.toContain('stroke=""');
|
|
12
|
+
});
|
|
13
|
+
it('should work with SVG element input', () => {
|
|
14
|
+
const svgContent = '<svg><rect x="10" y="" width="100" height="50" /></svg>';
|
|
15
|
+
const element = createSVGElement(svgContent);
|
|
16
|
+
const result = removeEmptyAttributes(element);
|
|
17
|
+
expect(result).toContain('x="10"');
|
|
18
|
+
expect(result).not.toContain('y=""');
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
describe('removeComments', () => {
|
|
22
|
+
it('should remove HTML comments', () => {
|
|
23
|
+
const svgContent = '<svg><!-- This is a comment --><circle cx="50" cy="50" r="40" /></svg>';
|
|
24
|
+
const result = removeComments(svgContent);
|
|
25
|
+
expect(result).not.toContain('<!--');
|
|
26
|
+
expect(result).not.toContain('-->');
|
|
27
|
+
expect(result).toContain('circle');
|
|
28
|
+
});
|
|
29
|
+
it('should handle multiple comments', () => {
|
|
30
|
+
const svgContent = '<svg><!-- Comment 1 --><circle /><!-- Comment 2 --></svg>';
|
|
31
|
+
const result = removeComments(svgContent);
|
|
32
|
+
expect(result).not.toContain('Comment');
|
|
33
|
+
});
|
|
34
|
+
it('should handle nested comments correctly', () => {
|
|
35
|
+
// This tests the incomplete sanitization fix
|
|
36
|
+
// Input: "<!--<!-- comment -->-->" should become "" not "<!-- comment -->"
|
|
37
|
+
const svgContent = '<svg><!--<!-- nested comment -->--><circle /></svg>';
|
|
38
|
+
const result = removeComments(svgContent);
|
|
39
|
+
expect(result).not.toContain('<!--');
|
|
40
|
+
expect(result).not.toContain('-->');
|
|
41
|
+
expect(result).not.toContain('nested comment');
|
|
42
|
+
expect(result).toContain('circle');
|
|
43
|
+
});
|
|
44
|
+
it('should handle deeply nested comments', () => {
|
|
45
|
+
const svgContent = '<svg><!--<!--<!-- triple nested -->-->--><circle /></svg>';
|
|
46
|
+
const result = removeComments(svgContent);
|
|
47
|
+
expect(result).not.toContain('<!--');
|
|
48
|
+
expect(result).not.toContain('-->');
|
|
49
|
+
expect(result).toContain('circle');
|
|
50
|
+
});
|
|
51
|
+
it('should throw error for content exceeding maximum length', () => {
|
|
52
|
+
const largeContent = '<!--' + 'x'.repeat(10000001) + '-->';
|
|
53
|
+
expect(() => removeComments(largeContent)).toThrow('exceeds maximum allowed length');
|
|
54
|
+
});
|
|
55
|
+
it('should handle comments with newlines', () => {
|
|
56
|
+
const svgContent = '<svg><!--\nMulti-line\ncomment\n--><circle /></svg>';
|
|
57
|
+
const result = removeComments(svgContent);
|
|
58
|
+
expect(result).not.toContain('<!--');
|
|
59
|
+
expect(result).not.toContain('-->');
|
|
60
|
+
expect(result).not.toContain('Multi-line');
|
|
61
|
+
expect(result).toContain('circle');
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
describe('normalizeWhitespace', () => {
|
|
65
|
+
it('should normalize whitespace', () => {
|
|
66
|
+
const svgContent = '<svg> <circle cx="50" cy="50" /> </svg>';
|
|
67
|
+
const result = normalizeWhitespace(svgContent);
|
|
68
|
+
expect(result).toContain('<circle');
|
|
69
|
+
expect(result).not.toMatch(/\s{2,}/);
|
|
70
|
+
});
|
|
71
|
+
it('should remove whitespace between tags', () => {
|
|
72
|
+
const svgContent = '<svg>\n <circle />\n <rect />\n</svg>';
|
|
73
|
+
const result = normalizeWhitespace(svgContent);
|
|
74
|
+
expect(result).toMatch(/><circle/);
|
|
75
|
+
expect(result).toMatch(/><rect/);
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
describe('optimizeSVG', () => {
|
|
79
|
+
it('should apply all optimizations', () => {
|
|
80
|
+
const svgContent = '<svg><!-- Comment --><circle cx="50" cy="" r="40" fill="red" /> </svg>';
|
|
81
|
+
const result = optimizeSVG(svgContent);
|
|
82
|
+
expect(result).not.toContain('<!--');
|
|
83
|
+
expect(result).not.toContain('cy=""');
|
|
84
|
+
expect(result).toContain('circle');
|
|
85
|
+
expect(result).toContain('fill="red"');
|
|
86
|
+
});
|
|
87
|
+
it('should work with SVG element input', () => {
|
|
88
|
+
const svgContent = '<svg><rect x="10" y="20" width="100" /></svg>';
|
|
89
|
+
const element = createSVGElement(svgContent);
|
|
90
|
+
const result = optimizeSVG(element);
|
|
91
|
+
expect(result).toContain('rect');
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
//# sourceMappingURL=cleanup.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.test.js","sourceRoot":"","sources":["../../../src/optimize/__tests__/cleanup.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { removeNanCoordinates } from '../path';
|
|
2
|
+
describe('Path Optimization', () => {
|
|
3
|
+
describe('removeNanCoordinates', () => {
|
|
4
|
+
it('should remove NaN values from path data', () => {
|
|
5
|
+
const svgContent = '<svg><path d="M 10,20 nan L 30,40 -nan Z" /></svg>';
|
|
6
|
+
const result = removeNanCoordinates(svgContent);
|
|
7
|
+
expect(result).not.toContain('nan');
|
|
8
|
+
expect(result).not.toContain('-nan');
|
|
9
|
+
expect(result).toContain('path');
|
|
10
|
+
});
|
|
11
|
+
it('should preserve valid path commands', () => {
|
|
12
|
+
const svgContent = '<svg><path d="M 10,20 L 30,40 Z" /></svg>';
|
|
13
|
+
const result = removeNanCoordinates(svgContent);
|
|
14
|
+
expect(result).toContain('M10');
|
|
15
|
+
expect(result).toContain('20');
|
|
16
|
+
expect(result).toContain('L30');
|
|
17
|
+
expect(result).toContain('40');
|
|
18
|
+
expect(result).toContain('Z');
|
|
19
|
+
});
|
|
20
|
+
it('should handle multiple paths', () => {
|
|
21
|
+
const svgContent = '<svg><path d="M 10,20 nan L 30,40" /><path d="M 50,60 L 70,80" /></svg>';
|
|
22
|
+
const result = removeNanCoordinates(svgContent);
|
|
23
|
+
expect(result).not.toContain('nan');
|
|
24
|
+
expect(result.split('path').length - 1).toBe(2);
|
|
25
|
+
});
|
|
26
|
+
it('should handle paths without d attribute', () => {
|
|
27
|
+
const svgContent = '<svg><path /><path d="M 10,20 L 30,40" /></svg>';
|
|
28
|
+
const result = removeNanCoordinates(svgContent);
|
|
29
|
+
expect(result).toContain('path');
|
|
30
|
+
});
|
|
31
|
+
it('should throw error if no SVG element found', () => {
|
|
32
|
+
expect(() => removeNanCoordinates('<div></div>')).toThrow('No SVG element found');
|
|
33
|
+
});
|
|
34
|
+
it('should handle case-insensitive NaN', () => {
|
|
35
|
+
const svgContent = '<svg><path d="M 10,20 NaN L 30,40 NAN Z" /></svg>';
|
|
36
|
+
const result = removeNanCoordinates(svgContent);
|
|
37
|
+
expect(result.toLowerCase()).not.toContain('nan');
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
//# sourceMappingURL=path.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.test.js","sourceRoot":"","sources":["../../../src/optimize/__tests__/path.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAE/C,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;QACpC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,UAAU,GAAG,oDAAoD,CAAC;YACxE,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;YAEhD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,qCAAqC,EAAE,GAAG,EAAE;YAC7C,MAAM,UAAU,GAAG,2CAA2C,CAAC;YAC/D,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;YAEhD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC/B,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,8BAA8B,EAAE,GAAG,EAAE;YACtC,MAAM,UAAU,GAAG,yEAAyE,CAAC;YAC7F,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;YAEhD,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YACpC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;YACjD,MAAM,UAAU,GAAG,iDAAiD,CAAC;YACrE,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;YAEhD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE,GAAG,EAAE;YACpD,MAAM,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;YAC5C,MAAM,UAAU,GAAG,mDAAmD,CAAC;YACvE,MAAM,MAAM,GAAG,oBAAoB,CAAC,UAAU,CAAC,CAAC;YAEhD,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG cleanup and optimization utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Removes empty attributes from SVG elements
|
|
6
|
+
*/
|
|
7
|
+
export declare function removeEmptyAttributes(svgContent: Element | string): string;
|
|
8
|
+
/**
|
|
9
|
+
* Removes comments from SVG content
|
|
10
|
+
*
|
|
11
|
+
* This function uses iterative replacement to handle nested comments correctly
|
|
12
|
+
* and includes input length validation to prevent ReDoS attacks.
|
|
13
|
+
*
|
|
14
|
+
* The function handles cases like:
|
|
15
|
+
* - Simple comments: <!-- comment -->
|
|
16
|
+
* - Nested comments: <!--<!-- inner -->-->
|
|
17
|
+
* - Multiple comments: <!-- one --><!-- two -->
|
|
18
|
+
*/
|
|
19
|
+
export declare function removeComments(svgContent: string): string;
|
|
20
|
+
/**
|
|
21
|
+
* Normalizes whitespace in SVG content
|
|
22
|
+
*/
|
|
23
|
+
export declare function normalizeWhitespace(svgContent: string): string;
|
|
24
|
+
/**
|
|
25
|
+
* Optimizes SVG by removing empty attributes, comments, and normalizing whitespace
|
|
26
|
+
*/
|
|
27
|
+
export declare function optimizeSVG(svgContent: Element | string): string;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG cleanup and optimization utilities
|
|
3
|
+
*/
|
|
4
|
+
import { JSDOM } from 'jsdom';
|
|
5
|
+
import { serializeSVG } from '../core/element';
|
|
6
|
+
import { isValidSvgString } from '../utils/validation';
|
|
7
|
+
/**
|
|
8
|
+
* Removes empty attributes from SVG elements
|
|
9
|
+
*/
|
|
10
|
+
export function removeEmptyAttributes(svgContent) {
|
|
11
|
+
const svgString = isValidSvgString(svgContent)
|
|
12
|
+
? svgContent
|
|
13
|
+
: serializeSVG(svgContent);
|
|
14
|
+
const dom = new JSDOM(svgString, {
|
|
15
|
+
contentType: 'image/svg+xml'
|
|
16
|
+
});
|
|
17
|
+
const document = dom.window.document;
|
|
18
|
+
const svgElement = document.querySelector('svg');
|
|
19
|
+
if (!svgElement) {
|
|
20
|
+
throw new Error('No SVG element found in the provided content.');
|
|
21
|
+
}
|
|
22
|
+
function removeEmptyAttrs(element) {
|
|
23
|
+
const attrs = Array.from(element.attributes);
|
|
24
|
+
attrs.forEach(attr => {
|
|
25
|
+
if (!attr.value || attr.value.trim() === '') {
|
|
26
|
+
element.removeAttribute(attr.name);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
Array.from(element.children).forEach(child => {
|
|
30
|
+
removeEmptyAttrs(child);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
removeEmptyAttrs(svgElement);
|
|
34
|
+
return svgElement.outerHTML.trim();
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Maximum allowed SVG content length to prevent ReDoS attacks
|
|
38
|
+
*/
|
|
39
|
+
const MAX_SVG_CONTENT_LENGTH = 10000000; // 10MB should be sufficient for most SVG files
|
|
40
|
+
/**
|
|
41
|
+
* Removes comments from SVG content
|
|
42
|
+
*
|
|
43
|
+
* This function uses iterative replacement to handle nested comments correctly
|
|
44
|
+
* and includes input length validation to prevent ReDoS attacks.
|
|
45
|
+
*
|
|
46
|
+
* The function handles cases like:
|
|
47
|
+
* - Simple comments: <!-- comment -->
|
|
48
|
+
* - Nested comments: <!--<!-- inner -->-->
|
|
49
|
+
* - Multiple comments: <!-- one --><!-- two -->
|
|
50
|
+
*/
|
|
51
|
+
export function removeComments(svgContent) {
|
|
52
|
+
// Validate input length to prevent ReDoS attacks
|
|
53
|
+
if (svgContent.length > MAX_SVG_CONTENT_LENGTH) {
|
|
54
|
+
throw new Error(`SVG content length exceeds maximum allowed length of ${MAX_SVG_CONTENT_LENGTH} characters`);
|
|
55
|
+
}
|
|
56
|
+
// Use iterative replacement to handle nested comments
|
|
57
|
+
// This prevents incomplete sanitization where nested comments could reappear
|
|
58
|
+
// Example: "<!--<!-- comment -->-->" should become "" not "<!-- comment -->"
|
|
59
|
+
let previous;
|
|
60
|
+
let result = svgContent;
|
|
61
|
+
let iterations = 0;
|
|
62
|
+
const MAX_ITERATIONS = 1000; // Prevent infinite loops
|
|
63
|
+
do {
|
|
64
|
+
previous = result;
|
|
65
|
+
// Match HTML comments and standalone delimiters:
|
|
66
|
+
// - Full comments: <!-- ... --> or <!-- ... --!>
|
|
67
|
+
// - Orphaned starts: <!--
|
|
68
|
+
// - Orphaned ends: --> or --!>
|
|
69
|
+
// The regex uses non-greedy matching (*?) to match the shortest possible comment
|
|
70
|
+
// and is applied iteratively until no further matches remain.
|
|
71
|
+
result = result.replace(/<!--[\s\S]*?--!?>|<!--|--!?>(?=[^>]|$)/g, '');
|
|
72
|
+
iterations++;
|
|
73
|
+
if (iterations > MAX_ITERATIONS) {
|
|
74
|
+
throw new Error('Comment removal exceeded maximum iterations. SVG content may be malformed.');
|
|
75
|
+
}
|
|
76
|
+
} while (result !== previous);
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Normalizes whitespace in SVG content
|
|
81
|
+
*/
|
|
82
|
+
export function normalizeWhitespace(svgContent) {
|
|
83
|
+
return svgContent
|
|
84
|
+
.replace(/\s+/g, ' ')
|
|
85
|
+
.replace(/>\s+</g, '><')
|
|
86
|
+
.trim();
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Optimizes SVG by removing empty attributes, comments, and normalizing whitespace
|
|
90
|
+
*/
|
|
91
|
+
export function optimizeSVG(svgContent) {
|
|
92
|
+
let svgString = isValidSvgString(svgContent)
|
|
93
|
+
? svgContent
|
|
94
|
+
: serializeSVG(svgContent);
|
|
95
|
+
svgString = removeComments(svgString);
|
|
96
|
+
svgString = removeEmptyAttributes(svgString);
|
|
97
|
+
svgString = normalizeWhitespace(svgString);
|
|
98
|
+
return svgString;
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=cleanup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cleanup.js","sourceRoot":"","sources":["../../src/optimize/cleanup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SVG path optimization utilities
|
|
3
|
+
*/
|
|
4
|
+
import { JSDOM } from 'jsdom';
|
|
5
|
+
const PATH_COMMANDS_WITHOUT_PARAMS = ['z', 'Z'];
|
|
6
|
+
/**
|
|
7
|
+
* Removes NaN and invalid coordinates from SVG path elements
|
|
8
|
+
*/
|
|
9
|
+
export function removeNanCoordinates(svgContent) {
|
|
10
|
+
const dom = new JSDOM(svgContent, {
|
|
11
|
+
contentType: 'image/svg+xml'
|
|
12
|
+
});
|
|
13
|
+
const document = dom.window.document;
|
|
14
|
+
const svgElement = document.querySelector('svg');
|
|
15
|
+
if (!svgElement) {
|
|
16
|
+
throw new Error('No SVG element found in the provided content.');
|
|
17
|
+
}
|
|
18
|
+
const paths = svgElement.querySelectorAll('path');
|
|
19
|
+
Array.from(paths).forEach((path) => {
|
|
20
|
+
const d = path.getAttribute('d');
|
|
21
|
+
if (d === null) {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
// Remove NaN values and split into commands
|
|
25
|
+
const commands = d
|
|
26
|
+
.replace(/nan|-nan/gi, ' ')
|
|
27
|
+
.split(/(?=[MmLlHhVvCcSsQqTtAaZz])/)
|
|
28
|
+
.map((command) => {
|
|
29
|
+
const type = command[0];
|
|
30
|
+
const isCommandWithoutParams = PATH_COMMANDS_WITHOUT_PARAMS.includes(type);
|
|
31
|
+
if (!isCommandWithoutParams) {
|
|
32
|
+
const params = command
|
|
33
|
+
.slice(1)
|
|
34
|
+
.split(/[\s,]+/)
|
|
35
|
+
.filter(param => param.trim() !== '')
|
|
36
|
+
.map(Number);
|
|
37
|
+
// Check if all parameters are valid numbers
|
|
38
|
+
const allValid = params.every(param => !isNaN(param) && isFinite(param));
|
|
39
|
+
if (allValid && params.length > 0) {
|
|
40
|
+
return { type, params };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
return { type, params: [] };
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
})
|
|
48
|
+
.filter((item) => item !== null)
|
|
49
|
+
.filter((command) => PATH_COMMANDS_WITHOUT_PARAMS.includes(command.type) || command.params.length > 0);
|
|
50
|
+
// Reconstruct the 'd' attribute
|
|
51
|
+
const modifiedD = commands
|
|
52
|
+
.map((command) => command.type + command.params.join(' '))
|
|
53
|
+
.join('');
|
|
54
|
+
path.setAttribute('d', modifiedD);
|
|
55
|
+
});
|
|
56
|
+
return svgElement.outerHTML.trim();
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/optimize/path.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,MAAM,4BAA4B,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;AAEhD;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,UAAkB;IACrD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE;QAChC,WAAW,EAAE,eAAe;KAC7B,CAAC,CAAC;IAEH,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;IACrC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAEjD,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IAED,MAAM,KAAK,GAAG,UAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAElD,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;QACjC,MAAM,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACf,OAAO;QACT,CAAC;QAED,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,CAAC;aACf,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC;aAC1B,KAAK,CAAC,4BAA4B,CAAC;aACnC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACf,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;YACxB,MAAM,sBAAsB,GAAG,4BAA4B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;YAE3E,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBAC5B,MAAM,MAAM,GAAG,OAAO;qBACnB,KAAK,CAAC,CAAC,CAAC;qBACR,KAAK,CAAC,QAAQ,CAAC;qBACf,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;qBACpC,GAAG,CAAC,MAAM,CAAC,CAAC;gBAEf,4CAA4C;gBAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;gBAEzE,IAAI,QAAQ,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAClC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBAC1B,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;YAC9B,CAAC;YAED,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;aACD,MAAM,CAAC,CAAC,IAAI,EAA8C,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC;aAC3E,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAClB,4BAA4B,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CACjF,CAAC;QAEJ,gCAAgC;QAChC,MAAM,SAAS,GAAG,QAAQ;aACvB,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;aACzD,IAAI,CAAC,EAAE,CAAC,CAAC;QAEZ,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,OAAO,UAAU,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AACrC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Type definitions for SVG Toolbox
|
|
3
|
+
*/
|
|
4
|
+
export interface SVGDimensions {
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
viewBox?: {
|
|
8
|
+
x: number;
|
|
9
|
+
y: number;
|
|
10
|
+
width: number;
|
|
11
|
+
height: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface DiffResult {
|
|
15
|
+
diffPngBuffer: Buffer;
|
|
16
|
+
numDiffPixels: number;
|
|
17
|
+
}
|
|
18
|
+
export interface ConversionOptions {
|
|
19
|
+
scale?: number;
|
|
20
|
+
format?: 'png' | 'jpg' | 'jpeg' | 'webp';
|
|
21
|
+
quality?: number;
|
|
22
|
+
}
|
|
23
|
+
export interface PathCommand {
|
|
24
|
+
type: string;
|
|
25
|
+
params: number[];
|
|
26
|
+
}
|
|
27
|
+
export interface SVGColor {
|
|
28
|
+
fill?: string;
|
|
29
|
+
stroke?: string;
|
|
30
|
+
opacity?: number;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|