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,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var cleanup_1 = require("../cleanup");
|
|
4
|
+
var element_1 = require("../../core/element");
|
|
5
|
+
describe('SVG Cleanup', function () {
|
|
6
|
+
describe('removeEmptyAttributes', function () {
|
|
7
|
+
it('should remove empty attributes', function () {
|
|
8
|
+
var svgContent = '<svg><circle cx="50" cy="50" r="" fill="red" stroke="" /></svg>';
|
|
9
|
+
var result = (0, cleanup_1.removeEmptyAttributes)(svgContent);
|
|
10
|
+
expect(result).toContain('cx="50"');
|
|
11
|
+
expect(result).toContain('fill="red"');
|
|
12
|
+
expect(result).not.toContain('r=""');
|
|
13
|
+
expect(result).not.toContain('stroke=""');
|
|
14
|
+
});
|
|
15
|
+
it('should work with SVG element input', function () {
|
|
16
|
+
var svgContent = '<svg><rect x="10" y="" width="100" height="50" /></svg>';
|
|
17
|
+
var element = (0, element_1.createSVGElement)(svgContent);
|
|
18
|
+
var result = (0, cleanup_1.removeEmptyAttributes)(element);
|
|
19
|
+
expect(result).toContain('x="10"');
|
|
20
|
+
expect(result).not.toContain('y=""');
|
|
21
|
+
});
|
|
22
|
+
});
|
|
23
|
+
describe('removeComments', function () {
|
|
24
|
+
it('should remove HTML comments', function () {
|
|
25
|
+
var svgContent = '<svg><!-- This is a comment --><circle cx="50" cy="50" r="40" /></svg>';
|
|
26
|
+
var result = (0, cleanup_1.removeComments)(svgContent);
|
|
27
|
+
expect(result).not.toContain('<!--');
|
|
28
|
+
expect(result).not.toContain('-->');
|
|
29
|
+
expect(result).toContain('circle');
|
|
30
|
+
});
|
|
31
|
+
it('should handle multiple comments', function () {
|
|
32
|
+
var svgContent = '<svg><!-- Comment 1 --><circle /><!-- Comment 2 --></svg>';
|
|
33
|
+
var result = (0, cleanup_1.removeComments)(svgContent);
|
|
34
|
+
expect(result).not.toContain('Comment');
|
|
35
|
+
});
|
|
36
|
+
it('should handle nested comments correctly', function () {
|
|
37
|
+
// This tests the incomplete sanitization fix
|
|
38
|
+
// Input: "<!--<!-- comment -->-->" should become "" not "<!-- comment -->"
|
|
39
|
+
var svgContent = '<svg><!--<!-- nested comment -->--><circle /></svg>';
|
|
40
|
+
var result = (0, cleanup_1.removeComments)(svgContent);
|
|
41
|
+
expect(result).not.toContain('<!--');
|
|
42
|
+
expect(result).not.toContain('-->');
|
|
43
|
+
expect(result).not.toContain('nested comment');
|
|
44
|
+
expect(result).toContain('circle');
|
|
45
|
+
});
|
|
46
|
+
it('should handle deeply nested comments', function () {
|
|
47
|
+
var svgContent = '<svg><!--<!--<!-- triple nested -->-->--><circle /></svg>';
|
|
48
|
+
var result = (0, cleanup_1.removeComments)(svgContent);
|
|
49
|
+
expect(result).not.toContain('<!--');
|
|
50
|
+
expect(result).not.toContain('-->');
|
|
51
|
+
expect(result).toContain('circle');
|
|
52
|
+
});
|
|
53
|
+
it('should throw error for content exceeding maximum length', function () {
|
|
54
|
+
var largeContent = '<!--' + 'x'.repeat(10000001) + '-->';
|
|
55
|
+
expect(function () { return (0, cleanup_1.removeComments)(largeContent); }).toThrow('exceeds maximum allowed length');
|
|
56
|
+
});
|
|
57
|
+
it('should handle comments with newlines', function () {
|
|
58
|
+
var svgContent = '<svg><!--\nMulti-line\ncomment\n--><circle /></svg>';
|
|
59
|
+
var result = (0, cleanup_1.removeComments)(svgContent);
|
|
60
|
+
expect(result).not.toContain('<!--');
|
|
61
|
+
expect(result).not.toContain('-->');
|
|
62
|
+
expect(result).not.toContain('Multi-line');
|
|
63
|
+
expect(result).toContain('circle');
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
describe('normalizeWhitespace', function () {
|
|
67
|
+
it('should normalize whitespace', function () {
|
|
68
|
+
var svgContent = '<svg> <circle cx="50" cy="50" /> </svg>';
|
|
69
|
+
var result = (0, cleanup_1.normalizeWhitespace)(svgContent);
|
|
70
|
+
expect(result).toContain('<circle');
|
|
71
|
+
expect(result).not.toMatch(/\s{2,}/);
|
|
72
|
+
});
|
|
73
|
+
it('should remove whitespace between tags', function () {
|
|
74
|
+
var svgContent = '<svg>\n <circle />\n <rect />\n</svg>';
|
|
75
|
+
var result = (0, cleanup_1.normalizeWhitespace)(svgContent);
|
|
76
|
+
expect(result).toMatch(/><circle/);
|
|
77
|
+
expect(result).toMatch(/><rect/);
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
describe('optimizeSVG', function () {
|
|
81
|
+
it('should apply all optimizations', function () {
|
|
82
|
+
var svgContent = '<svg><!-- Comment --><circle cx="50" cy="" r="40" fill="red" /> </svg>';
|
|
83
|
+
var result = (0, cleanup_1.optimizeSVG)(svgContent);
|
|
84
|
+
expect(result).not.toContain('<!--');
|
|
85
|
+
expect(result).not.toContain('cy=""');
|
|
86
|
+
expect(result).toContain('circle');
|
|
87
|
+
expect(result).toContain('fill="red"');
|
|
88
|
+
});
|
|
89
|
+
it('should work with SVG element input', function () {
|
|
90
|
+
var svgContent = '<svg><rect x="10" y="20" width="100" /></svg>';
|
|
91
|
+
var element = (0, element_1.createSVGElement)(svgContent);
|
|
92
|
+
var result = (0, cleanup_1.optimizeSVG)(element);
|
|
93
|
+
expect(result).toContain('rect');
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
//# 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,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var path_1 = require("../path");
|
|
4
|
+
describe('Path Optimization', function () {
|
|
5
|
+
describe('removeNanCoordinates', function () {
|
|
6
|
+
it('should remove NaN values from path data', function () {
|
|
7
|
+
var svgContent = '<svg><path d="M 10,20 nan L 30,40 -nan Z" /></svg>';
|
|
8
|
+
var result = (0, path_1.removeNanCoordinates)(svgContent);
|
|
9
|
+
expect(result).not.toContain('nan');
|
|
10
|
+
expect(result).not.toContain('-nan');
|
|
11
|
+
expect(result).toContain('path');
|
|
12
|
+
});
|
|
13
|
+
it('should preserve valid path commands', function () {
|
|
14
|
+
var svgContent = '<svg><path d="M 10,20 L 30,40 Z" /></svg>';
|
|
15
|
+
var result = (0, path_1.removeNanCoordinates)(svgContent);
|
|
16
|
+
expect(result).toContain('M10');
|
|
17
|
+
expect(result).toContain('20');
|
|
18
|
+
expect(result).toContain('L30');
|
|
19
|
+
expect(result).toContain('40');
|
|
20
|
+
expect(result).toContain('Z');
|
|
21
|
+
});
|
|
22
|
+
it('should handle multiple paths', function () {
|
|
23
|
+
var svgContent = '<svg><path d="M 10,20 nan L 30,40" /><path d="M 50,60 L 70,80" /></svg>';
|
|
24
|
+
var result = (0, path_1.removeNanCoordinates)(svgContent);
|
|
25
|
+
expect(result).not.toContain('nan');
|
|
26
|
+
expect(result.split('path').length - 1).toBe(2);
|
|
27
|
+
});
|
|
28
|
+
it('should handle paths without d attribute', function () {
|
|
29
|
+
var svgContent = '<svg><path /><path d="M 10,20 L 30,40" /></svg>';
|
|
30
|
+
var result = (0, path_1.removeNanCoordinates)(svgContent);
|
|
31
|
+
expect(result).toContain('path');
|
|
32
|
+
});
|
|
33
|
+
it('should throw error if no SVG element found', function () {
|
|
34
|
+
expect(function () { return (0, path_1.removeNanCoordinates)('<div></div>'); }).toThrow('No SVG element found');
|
|
35
|
+
});
|
|
36
|
+
it('should handle case-insensitive NaN', function () {
|
|
37
|
+
var svgContent = '<svg><path d="M 10,20 NaN L 30,40 NAN Z" /></svg>';
|
|
38
|
+
var result = (0, path_1.removeNanCoordinates)(svgContent);
|
|
39
|
+
expect(result.toLowerCase()).not.toContain('nan');
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
//# 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,gCAA+C;AAE/C,QAAQ,CAAC,mBAAmB,EAAE;IAC5B,QAAQ,CAAC,sBAAsB,EAAE;QAC/B,EAAE,CAAC,yCAAyC,EAAE;YAC5C,IAAM,UAAU,GAAG,oDAAoD,CAAC;YACxE,IAAM,MAAM,GAAG,IAAA,2BAAoB,EAAC,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;YACxC,IAAM,UAAU,GAAG,2CAA2C,CAAC;YAC/D,IAAM,MAAM,GAAG,IAAA,2BAAoB,EAAC,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;YACjC,IAAM,UAAU,GAAG,yEAAyE,CAAC;YAC7F,IAAM,MAAM,GAAG,IAAA,2BAAoB,EAAC,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;YAC5C,IAAM,UAAU,GAAG,iDAAiD,CAAC;YACrE,IAAM,MAAM,GAAG,IAAA,2BAAoB,EAAC,UAAU,CAAC,CAAC;YAEhD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE;YAC/C,MAAM,CAAC,cAAM,OAAA,IAAA,2BAAoB,EAAC,aAAa,CAAC,EAAnC,CAAmC,CAAC,CAAC,OAAO,CAAC,sBAAsB,CAAC,CAAC;QACpF,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,oCAAoC,EAAE;YACvC,IAAM,UAAU,GAAG,mDAAmD,CAAC;YACvE,IAAM,MAAM,GAAG,IAAA,2BAAoB,EAAC,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,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SVG cleanup and optimization utilities
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.removeEmptyAttributes = removeEmptyAttributes;
|
|
7
|
+
exports.removeComments = removeComments;
|
|
8
|
+
exports.normalizeWhitespace = normalizeWhitespace;
|
|
9
|
+
exports.optimizeSVG = optimizeSVG;
|
|
10
|
+
var jsdom_1 = require("jsdom");
|
|
11
|
+
var element_1 = require("../core/element");
|
|
12
|
+
var validation_1 = require("../utils/validation");
|
|
13
|
+
/**
|
|
14
|
+
* Removes empty attributes from SVG elements
|
|
15
|
+
*/
|
|
16
|
+
function removeEmptyAttributes(svgContent) {
|
|
17
|
+
var svgString = (0, validation_1.isValidSvgString)(svgContent)
|
|
18
|
+
? svgContent
|
|
19
|
+
: (0, element_1.serializeSVG)(svgContent);
|
|
20
|
+
var dom = new jsdom_1.JSDOM(svgString, {
|
|
21
|
+
contentType: 'image/svg+xml'
|
|
22
|
+
});
|
|
23
|
+
var document = dom.window.document;
|
|
24
|
+
var svgElement = document.querySelector('svg');
|
|
25
|
+
if (!svgElement) {
|
|
26
|
+
throw new Error('No SVG element found in the provided content.');
|
|
27
|
+
}
|
|
28
|
+
function removeEmptyAttrs(element) {
|
|
29
|
+
var attrs = Array.from(element.attributes);
|
|
30
|
+
attrs.forEach(function (attr) {
|
|
31
|
+
if (!attr.value || attr.value.trim() === '') {
|
|
32
|
+
element.removeAttribute(attr.name);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
Array.from(element.children).forEach(function (child) {
|
|
36
|
+
removeEmptyAttrs(child);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
removeEmptyAttrs(svgElement);
|
|
40
|
+
return svgElement.outerHTML.trim();
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Maximum allowed SVG content length to prevent ReDoS attacks
|
|
44
|
+
*/
|
|
45
|
+
var MAX_SVG_CONTENT_LENGTH = 10000000; // 10MB should be sufficient for most SVG files
|
|
46
|
+
/**
|
|
47
|
+
* Removes comments from SVG content
|
|
48
|
+
*
|
|
49
|
+
* This function uses iterative replacement to handle nested comments correctly
|
|
50
|
+
* and includes input length validation to prevent ReDoS attacks.
|
|
51
|
+
*
|
|
52
|
+
* The function handles cases like:
|
|
53
|
+
* - Simple comments: <!-- comment -->
|
|
54
|
+
* - Nested comments: <!--<!-- inner -->-->
|
|
55
|
+
* - Multiple comments: <!-- one --><!-- two -->
|
|
56
|
+
*/
|
|
57
|
+
function removeComments(svgContent) {
|
|
58
|
+
// Validate input length to prevent ReDoS attacks
|
|
59
|
+
if (svgContent.length > MAX_SVG_CONTENT_LENGTH) {
|
|
60
|
+
throw new Error("SVG content length exceeds maximum allowed length of ".concat(MAX_SVG_CONTENT_LENGTH, " characters"));
|
|
61
|
+
}
|
|
62
|
+
// Use iterative replacement to handle nested comments
|
|
63
|
+
// This prevents incomplete sanitization where nested comments could reappear
|
|
64
|
+
// Example: "<!--<!-- comment -->-->" should become "" not "<!-- comment -->"
|
|
65
|
+
var previous;
|
|
66
|
+
var result = svgContent;
|
|
67
|
+
var iterations = 0;
|
|
68
|
+
var MAX_ITERATIONS = 1000; // Prevent infinite loops
|
|
69
|
+
do {
|
|
70
|
+
previous = result;
|
|
71
|
+
// Match HTML comments and standalone delimiters:
|
|
72
|
+
// - Full comments: <!-- ... --> or <!-- ... --!>
|
|
73
|
+
// - Orphaned starts: <!--
|
|
74
|
+
// - Orphaned ends: --> or --!>
|
|
75
|
+
// The regex uses non-greedy matching (*?) to match the shortest possible comment
|
|
76
|
+
// and is applied iteratively until no further matches remain.
|
|
77
|
+
result = result.replace(/<!--[\s\S]*?--!?>|<!--|--!?>(?=[^>]|$)/g, '');
|
|
78
|
+
iterations++;
|
|
79
|
+
if (iterations > MAX_ITERATIONS) {
|
|
80
|
+
throw new Error('Comment removal exceeded maximum iterations. SVG content may be malformed.');
|
|
81
|
+
}
|
|
82
|
+
} while (result !== previous);
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Normalizes whitespace in SVG content
|
|
87
|
+
*/
|
|
88
|
+
function normalizeWhitespace(svgContent) {
|
|
89
|
+
return svgContent
|
|
90
|
+
.replace(/\s+/g, ' ')
|
|
91
|
+
.replace(/>\s+</g, '><')
|
|
92
|
+
.trim();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Optimizes SVG by removing empty attributes, comments, and normalizing whitespace
|
|
96
|
+
*/
|
|
97
|
+
function optimizeSVG(svgContent) {
|
|
98
|
+
var svgString = (0, validation_1.isValidSvgString)(svgContent)
|
|
99
|
+
? svgContent
|
|
100
|
+
: (0, element_1.serializeSVG)(svgContent);
|
|
101
|
+
svgString = removeComments(svgString);
|
|
102
|
+
svgString = removeEmptyAttributes(svgString);
|
|
103
|
+
svgString = normalizeWhitespace(svgString);
|
|
104
|
+
return svgString;
|
|
105
|
+
}
|
|
106
|
+
//# 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,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* SVG path optimization utilities
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.removeNanCoordinates = removeNanCoordinates;
|
|
7
|
+
var jsdom_1 = require("jsdom");
|
|
8
|
+
var PATH_COMMANDS_WITHOUT_PARAMS = ['z', 'Z'];
|
|
9
|
+
/**
|
|
10
|
+
* Removes NaN and invalid coordinates from SVG path elements
|
|
11
|
+
*/
|
|
12
|
+
function removeNanCoordinates(svgContent) {
|
|
13
|
+
var dom = new jsdom_1.JSDOM(svgContent, {
|
|
14
|
+
contentType: 'image/svg+xml'
|
|
15
|
+
});
|
|
16
|
+
var document = dom.window.document;
|
|
17
|
+
var svgElement = document.querySelector('svg');
|
|
18
|
+
if (!svgElement) {
|
|
19
|
+
throw new Error('No SVG element found in the provided content.');
|
|
20
|
+
}
|
|
21
|
+
var paths = svgElement.querySelectorAll('path');
|
|
22
|
+
Array.from(paths).forEach(function (path) {
|
|
23
|
+
var d = path.getAttribute('d');
|
|
24
|
+
if (d === null) {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
// Remove NaN values and split into commands
|
|
28
|
+
var commands = d
|
|
29
|
+
.replace(/nan|-nan/gi, ' ')
|
|
30
|
+
.split(/(?=[MmLlHhVvCcSsQqTtAaZz])/)
|
|
31
|
+
.map(function (command) {
|
|
32
|
+
var type = command[0];
|
|
33
|
+
var isCommandWithoutParams = PATH_COMMANDS_WITHOUT_PARAMS.includes(type);
|
|
34
|
+
if (!isCommandWithoutParams) {
|
|
35
|
+
var params = command
|
|
36
|
+
.slice(1)
|
|
37
|
+
.split(/[\s,]+/)
|
|
38
|
+
.filter(function (param) { return param.trim() !== ''; })
|
|
39
|
+
.map(Number);
|
|
40
|
+
// Check if all parameters are valid numbers
|
|
41
|
+
var allValid = params.every(function (param) { return !isNaN(param) && isFinite(param); });
|
|
42
|
+
if (allValid && params.length > 0) {
|
|
43
|
+
return { type: type, params: params };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
return { type: type, params: [] };
|
|
48
|
+
}
|
|
49
|
+
return null;
|
|
50
|
+
})
|
|
51
|
+
.filter(function (item) { return item !== null; })
|
|
52
|
+
.filter(function (command) {
|
|
53
|
+
return PATH_COMMANDS_WITHOUT_PARAMS.includes(command.type) || command.params.length > 0;
|
|
54
|
+
});
|
|
55
|
+
// Reconstruct the 'd' attribute
|
|
56
|
+
var modifiedD = commands
|
|
57
|
+
.map(function (command) { return command.type + command.params.join(' '); })
|
|
58
|
+
.join('');
|
|
59
|
+
path.setAttribute('d', modifiedD);
|
|
60
|
+
});
|
|
61
|
+
return svgElement.outerHTML.trim();
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.js","sourceRoot":"","sources":["../../src/optimize/path.ts"],"names":[],"mappings":"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"}
|
|
@@ -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 {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
var path_validation_1 = require("../path-validation");
|
|
7
|
+
var path_1 = __importDefault(require("path"));
|
|
8
|
+
var fs_1 = __importDefault(require("fs"));
|
|
9
|
+
var os_1 = __importDefault(require("os"));
|
|
10
|
+
describe('Path Validation', function () {
|
|
11
|
+
var tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'svg-toolbox-test-'));
|
|
12
|
+
afterAll(function () {
|
|
13
|
+
fs_1.default.rmSync(tempDir, { recursive: true, force: true });
|
|
14
|
+
});
|
|
15
|
+
describe('validateFilePath', function () {
|
|
16
|
+
it('should normalize valid paths', function () {
|
|
17
|
+
var result = (0, path_validation_1.validateFilePath)('./test.svg');
|
|
18
|
+
expect(path_1.default.isAbsolute(result)).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
it('should reject paths with .. traversal', function () {
|
|
21
|
+
expect(function () { return (0, path_validation_1.validateFilePath)('../etc/passwd'); }).toThrow('Path traversal detected');
|
|
22
|
+
expect(function () { return (0, path_validation_1.validateFilePath)('../../secret'); }).toThrow('Path traversal detected');
|
|
23
|
+
});
|
|
24
|
+
it('should reject empty paths', function () {
|
|
25
|
+
expect(function () { return (0, path_validation_1.validateFilePath)(''); }).toThrow('File path must be a non-empty string');
|
|
26
|
+
expect(function () { return (0, path_validation_1.validateFilePath)(null); }).toThrow('File path must be a non-empty string');
|
|
27
|
+
});
|
|
28
|
+
it('should restrict paths to base directory when provided', function () {
|
|
29
|
+
var baseDir = tempDir;
|
|
30
|
+
var validPath = path_1.default.join(baseDir, 'test.svg');
|
|
31
|
+
expect(function () { return (0, path_validation_1.validateFilePath)(validPath, baseDir); }).not.toThrow();
|
|
32
|
+
expect(function () { return (0, path_validation_1.validateFilePath)('/etc/passwd', baseDir); }).toThrow('Path is outside the allowed directory');
|
|
33
|
+
});
|
|
34
|
+
});
|
|
35
|
+
describe('validateReadPath', function () {
|
|
36
|
+
it('should validate file extensions', function () {
|
|
37
|
+
expect(function () { return (0, path_validation_1.validateReadPath)('test.svg', ['.svg']); }).not.toThrow();
|
|
38
|
+
expect(function () { return (0, path_validation_1.validateReadPath)('test.png', ['.svg']); }).toThrow('File extension .png is not allowed');
|
|
39
|
+
});
|
|
40
|
+
it('should accept multiple allowed extensions', function () {
|
|
41
|
+
expect(function () { return (0, path_validation_1.validateReadPath)('test.svg', ['.svg', '.png']); }).not.toThrow();
|
|
42
|
+
expect(function () { return (0, path_validation_1.validateReadPath)('test.png', ['.svg', '.png']); }).not.toThrow();
|
|
43
|
+
});
|
|
44
|
+
it('should be case-insensitive for extensions', function () {
|
|
45
|
+
expect(function () { return (0, path_validation_1.validateReadPath)('test.SVG', ['.svg']); }).not.toThrow();
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
describe('validateWritePath', function () {
|
|
49
|
+
it('should validate file extensions', function () {
|
|
50
|
+
var writePath = path_1.default.join(tempDir, 'test.png');
|
|
51
|
+
expect(function () { return (0, path_validation_1.validateWritePath)(writePath, ['.png']); }).not.toThrow();
|
|
52
|
+
expect(function () { return (0, path_validation_1.validateWritePath)(writePath, ['.svg']); }).toThrow('File extension .png is not allowed');
|
|
53
|
+
});
|
|
54
|
+
it('should create directory if it does not exist', function () {
|
|
55
|
+
var newDir = path_1.default.join(tempDir, 'new-dir');
|
|
56
|
+
var writePath = path_1.default.join(newDir, 'test.png');
|
|
57
|
+
expect(fs_1.default.existsSync(newDir)).toBe(false);
|
|
58
|
+
(0, path_validation_1.validateWritePath)(writePath, ['.png']);
|
|
59
|
+
expect(fs_1.default.existsSync(newDir)).toBe(true);
|
|
60
|
+
});
|
|
61
|
+
it('should restrict writes to base directory when provided', function () {
|
|
62
|
+
var baseDir = tempDir;
|
|
63
|
+
var validPath = path_1.default.join(baseDir, 'test.png');
|
|
64
|
+
expect(function () { return (0, path_validation_1.validateWritePath)(validPath, ['.png'], baseDir); }).not.toThrow();
|
|
65
|
+
expect(function () { return (0, path_validation_1.validateWritePath)('/tmp/test.png', ['.png'], baseDir); }).toThrow('Path is outside the allowed directory');
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
//# sourceMappingURL=path-validation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-validation.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/path-validation.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
var validation_1 = require("../validation");
|
|
4
|
+
var element_1 = require("../../core/element");
|
|
5
|
+
describe('Validation', function () {
|
|
6
|
+
describe('isValidSvgString', function () {
|
|
7
|
+
it('should return true for valid SVG string', function () {
|
|
8
|
+
var svgString = '<svg><circle cx="50" cy="50" r="40" /></svg>';
|
|
9
|
+
expect((0, validation_1.isValidSvgString)(svgString)).toBe(true);
|
|
10
|
+
});
|
|
11
|
+
it('should return false for non-string input', function () {
|
|
12
|
+
expect((0, validation_1.isValidSvgString)(null)).toBe(false);
|
|
13
|
+
expect((0, validation_1.isValidSvgString)(123)).toBe(false);
|
|
14
|
+
expect((0, validation_1.isValidSvgString)({})).toBe(false);
|
|
15
|
+
});
|
|
16
|
+
it('should return false for invalid SVG string', function () {
|
|
17
|
+
expect((0, validation_1.isValidSvgString)('<div></div>')).toBe(false);
|
|
18
|
+
expect((0, validation_1.isValidSvgString)('not svg')).toBe(false);
|
|
19
|
+
expect((0, validation_1.isValidSvgString)('')).toBe(false);
|
|
20
|
+
});
|
|
21
|
+
it('should handle malformed XML', function () {
|
|
22
|
+
expect((0, validation_1.isValidSvgString)('<svg><unclosed></svg>')).toBe(false);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe('isValidSvgElement', function () {
|
|
26
|
+
it('should return true for valid SVG element', function () {
|
|
27
|
+
var svgString = '<svg><circle /></svg>';
|
|
28
|
+
var element = (0, element_1.createSVGElement)(svgString);
|
|
29
|
+
expect((0, validation_1.isValidSvgElement)(element)).toBe(true);
|
|
30
|
+
});
|
|
31
|
+
it('should return false for non-element input', function () {
|
|
32
|
+
expect((0, validation_1.isValidSvgElement)(null)).toBe(false);
|
|
33
|
+
expect((0, validation_1.isValidSvgElement)('string')).toBe(false);
|
|
34
|
+
expect((0, validation_1.isValidSvgElement)({})).toBe(false);
|
|
35
|
+
});
|
|
36
|
+
it('should return false for non-SVG element', function () {
|
|
37
|
+
var JSDOM = require('jsdom').JSDOM;
|
|
38
|
+
var dom = new JSDOM("<!DOCTYPE html><html><body><div></div></body></html>");
|
|
39
|
+
var div = dom.window.document.querySelector('div');
|
|
40
|
+
expect((0, validation_1.isValidSvgElement)(div)).toBe(false);
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=validation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/validation.test.ts"],"names":[],"mappings":";;AAAA,4CAAoE;AACpE,8CAAsD;AAEtD,QAAQ,CAAC,YAAY,EAAE;IACrB,QAAQ,CAAC,kBAAkB,EAAE;QAC3B,EAAE,CAAC,yCAAyC,EAAE;YAC5C,IAAM,SAAS,GAAG,8CAA8C,CAAC;YACjE,MAAM,CAAC,IAAA,6BAAgB,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,0CAA0C,EAAE;YAC7C,MAAM,CAAC,IAAA,6BAAgB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC3C,MAAM,CAAC,IAAA,6BAAgB,EAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1C,MAAM,CAAC,IAAA,6BAAgB,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4CAA4C,EAAE;YAC/C,MAAM,CAAC,IAAA,6BAAgB,EAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACpD,MAAM,CAAC,IAAA,6BAAgB,EAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,CAAC,IAAA,6BAAgB,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6BAA6B,EAAE;YAChC,MAAM,CAAC,IAAA,6BAAgB,EAAC,uBAAuB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChE,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,mBAAmB,EAAE;QAC5B,EAAE,CAAC,0CAA0C,EAAE;YAC7C,IAAM,SAAS,GAAG,uBAAuB,CAAC;YAC1C,IAAM,OAAO,GAAG,IAAA,0BAAgB,EAAC,SAAS,CAAC,CAAC;YAC5C,MAAM,CAAC,IAAA,8BAAiB,EAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,2CAA2C,EAAE;YAC9C,MAAM,CAAC,IAAA,8BAAiB,EAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5C,MAAM,CAAC,IAAA,8BAAiB,EAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAChD,MAAM,CAAC,IAAA,8BAAiB,EAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC5C,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,yCAAyC,EAAE;YACpC,IAAA,KAAK,GAAK,OAAO,CAAC,OAAO,CAAC,MAArB,CAAsB;YACnC,IAAM,GAAG,GAAG,IAAI,KAAK,CAAC,sDAAsD,CAAC,CAAC;YAC9E,IAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;YAErD,MAAM,CAAC,IAAA,8BAAiB,EAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7C,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DOM utility functions for SVG manipulation
|
|
3
|
+
*/
|
|
4
|
+
export declare const document: Document;
|
|
5
|
+
export declare const DOMParser: {
|
|
6
|
+
new (): DOMParser;
|
|
7
|
+
prototype: DOMParser;
|
|
8
|
+
}, XMLSerializer: {
|
|
9
|
+
new (): XMLSerializer;
|
|
10
|
+
prototype: XMLSerializer;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Creates a new DOM parser instance
|
|
14
|
+
*/
|
|
15
|
+
export declare function createDOMParser(): DOMParser;
|
|
16
|
+
/**
|
|
17
|
+
* Creates a new XML serializer instance
|
|
18
|
+
*/
|
|
19
|
+
export declare function createXMLSerializer(): XMLSerializer;
|
|
20
|
+
/**
|
|
21
|
+
* Gets the SVG namespace URI
|
|
22
|
+
*/
|
|
23
|
+
export declare const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
package/lib/utils/dom.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* DOM utility functions for SVG manipulation
|
|
4
|
+
*/
|
|
5
|
+
var _a;
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SVG_NAMESPACE = exports.XMLSerializer = exports.DOMParser = exports.document = void 0;
|
|
8
|
+
exports.createDOMParser = createDOMParser;
|
|
9
|
+
exports.createXMLSerializer = createXMLSerializer;
|
|
10
|
+
var jsdom_1 = require("jsdom");
|
|
11
|
+
// Create a singleton virtual DOM environment
|
|
12
|
+
var dom = new jsdom_1.JSDOM("<!DOCTYPE html><html><body></body></html>");
|
|
13
|
+
exports.document = dom.window.document;
|
|
14
|
+
exports.DOMParser = (_a = dom.window, _a.DOMParser), exports.XMLSerializer = _a.XMLSerializer;
|
|
15
|
+
/**
|
|
16
|
+
* Creates a new DOM parser instance
|
|
17
|
+
*/
|
|
18
|
+
function createDOMParser() {
|
|
19
|
+
return new dom.window.DOMParser();
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Creates a new XML serializer instance
|
|
23
|
+
*/
|
|
24
|
+
function createXMLSerializer() {
|
|
25
|
+
return new dom.window.XMLSerializer();
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Gets the SVG namespace URI
|
|
29
|
+
*/
|
|
30
|
+
exports.SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
|
|
31
|
+
//# sourceMappingURL=dom.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dom.js","sourceRoot":"","sources":["../../src/utils/dom.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAYH,0CAEC;AAKD,kDAEC;AAnBD,+BAA8B;AAE9B,6CAA6C;AAC7C,IAAM,GAAG,GAAG,IAAI,aAAK,CAAC,2CAA2C,CAAC,CAAC;AACpD,QAAA,QAAQ,GAAK,GAAG,CAAC,MAAM,UAAC;AACxB,QAAA,SAAS,IAAX,KAA+B,GAAG,CAAC,MAAM,iBAA5B,QAAA,aAAa,oBAAgB;AAEvD;;GAEG;AACH,SAAgB,eAAe;IAC7B,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,SAAgB,mBAAmB;IACjC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;AACxC,CAAC;AAED;;GAEG;AACU,QAAA,aAAa,GAAG,4BAA4B,CAAC"}
|