@emasoft/svg-matrix 1.1.0 → 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/bin/svg-matrix.js +7 -6
- package/bin/svgm.js +109 -40
- package/dist/svg-matrix.min.js +7 -7
- package/dist/svg-toolbox.min.js +148 -228
- package/dist/svgm.min.js +152 -232
- package/dist/version.json +5 -5
- package/package.json +1 -1
- package/scripts/postinstall.js +72 -41
- package/scripts/test-postinstall.js +18 -16
- package/scripts/version-sync.js +78 -60
- package/src/animation-optimization.js +190 -98
- package/src/animation-references.js +11 -3
- package/src/arc-length.js +23 -20
- package/src/bezier-analysis.js +9 -13
- package/src/bezier-intersections.js +18 -4
- package/src/browser-verify.js +35 -8
- package/src/clip-path-resolver.js +285 -114
- package/src/convert-path-data.js +20 -8
- package/src/css-specificity.js +33 -9
- package/src/douglas-peucker.js +272 -141
- package/src/geometry-to-path.js +79 -22
- package/src/gjk-collision.js +287 -126
- package/src/index.js +56 -21
- package/src/inkscape-support.js +122 -101
- package/src/logger.js +43 -27
- package/src/marker-resolver.js +201 -121
- package/src/mask-resolver.js +231 -98
- package/src/matrix.js +9 -5
- package/src/mesh-gradient.js +22 -14
- package/src/off-canvas-detection.js +53 -17
- package/src/path-optimization.js +356 -171
- package/src/path-simplification.js +671 -256
- package/src/pattern-resolver.js +1 -3
- package/src/polygon-clip.js +396 -78
- package/src/svg-boolean-ops.js +90 -23
- package/src/svg-collections.js +1546 -667
- package/src/svg-flatten.js +152 -38
- package/src/svg-matrix-lib.js +2 -2
- package/src/svg-parser.js +5 -1
- package/src/svg-rendering-context.js +3 -1
- package/src/svg-toolbox-lib.js +2 -2
- package/src/svg-toolbox.js +99 -457
- package/src/svg-validation-data.js +513 -345
- package/src/svg2-polyfills.js +156 -93
- package/src/svgm-lib.js +8 -4
- package/src/transform-optimization.js +168 -51
- package/src/transforms2d.js +73 -40
- package/src/transforms3d.js +34 -27
- package/src/use-symbol-resolver.js +175 -76
- package/src/vector.js +80 -44
- package/src/vendor/inkscape-hatch-polyfill.js +143 -108
- package/src/vendor/inkscape-hatch-polyfill.min.js +291 -1
- package/src/vendor/inkscape-mesh-polyfill.js +953 -766
- package/src/vendor/inkscape-mesh-polyfill.min.js +896 -1
- package/src/verification.js +3 -4
package/src/convert-path-data.js
CHANGED
|
@@ -177,9 +177,7 @@ export function parsePath(d) {
|
|
|
177
177
|
|
|
178
178
|
// BUG FIX #6: Validate command exists in COMMAND_PARAMS
|
|
179
179
|
if (paramCount === undefined) {
|
|
180
|
-
console.warn(
|
|
181
|
-
`Unknown SVG path command '${cmd}' - skipping`,
|
|
182
|
-
);
|
|
180
|
+
console.warn(`Unknown SVG path command '${cmd}' - skipping`);
|
|
183
181
|
continue;
|
|
184
182
|
}
|
|
185
183
|
|
|
@@ -218,7 +216,9 @@ export function parsePath(d) {
|
|
|
218
216
|
export function formatNumber(num, precision = 3) {
|
|
219
217
|
// Parameter validation: num must be a number
|
|
220
218
|
if (typeof num !== "number") {
|
|
221
|
-
throw new TypeError(
|
|
219
|
+
throw new TypeError(
|
|
220
|
+
`formatNumber: num must be a number, got ${typeof num}`,
|
|
221
|
+
);
|
|
222
222
|
}
|
|
223
223
|
// Parameter validation: precision must be a non-negative integer
|
|
224
224
|
if (
|
|
@@ -568,10 +568,14 @@ export function lineToZ(cmd, cx, cy, startX, startY, tolerance = 1e-6) {
|
|
|
568
568
|
throw new TypeError(`lineToZ: cy must be a finite number, got ${cy}`);
|
|
569
569
|
}
|
|
570
570
|
if (typeof startX !== "number" || !isFinite(startX)) {
|
|
571
|
-
throw new TypeError(
|
|
571
|
+
throw new TypeError(
|
|
572
|
+
`lineToZ: startX must be a finite number, got ${startX}`,
|
|
573
|
+
);
|
|
572
574
|
}
|
|
573
575
|
if (typeof startY !== "number" || !isFinite(startY)) {
|
|
574
|
-
throw new TypeError(
|
|
576
|
+
throw new TypeError(
|
|
577
|
+
`lineToZ: startY must be a finite number, got ${startY}`,
|
|
578
|
+
);
|
|
575
579
|
}
|
|
576
580
|
if (typeof tolerance !== "number" || !isFinite(tolerance) || tolerance < 0) {
|
|
577
581
|
throw new TypeError(
|
|
@@ -919,7 +923,11 @@ export function convertPathData(d, options = {}) {
|
|
|
919
923
|
throw new TypeError(`convertPathData: d must be a string, got ${typeof d}`);
|
|
920
924
|
}
|
|
921
925
|
// Parameter validation: options must be an object
|
|
922
|
-
if (
|
|
926
|
+
if (
|
|
927
|
+
typeof options !== "object" ||
|
|
928
|
+
options === null ||
|
|
929
|
+
Array.isArray(options)
|
|
930
|
+
) {
|
|
923
931
|
throw new TypeError(
|
|
924
932
|
`convertPathData: options must be an object, got ${typeof options}`,
|
|
925
933
|
);
|
|
@@ -1119,7 +1127,11 @@ export function optimizeDocumentPaths(root, options = {}) {
|
|
|
1119
1127
|
);
|
|
1120
1128
|
}
|
|
1121
1129
|
// Parameter validation: options must be an object
|
|
1122
|
-
if (
|
|
1130
|
+
if (
|
|
1131
|
+
typeof options !== "object" ||
|
|
1132
|
+
options === null ||
|
|
1133
|
+
Array.isArray(options)
|
|
1134
|
+
) {
|
|
1123
1135
|
throw new TypeError(
|
|
1124
1136
|
`optimizeDocumentPaths: options must be an object, got ${typeof options}`,
|
|
1125
1137
|
);
|
package/src/css-specificity.js
CHANGED
|
@@ -229,11 +229,18 @@ function parseSimpleSelector(selector) {
|
|
|
229
229
|
|
|
230
230
|
// Handle legacy pseudo-elements (CSS2 syntax with single colon)
|
|
231
231
|
// These should be treated as pseudo-elements, not pseudo-classes
|
|
232
|
-
const legacyPseudoElements = [
|
|
232
|
+
const legacyPseudoElements = [
|
|
233
|
+
"before",
|
|
234
|
+
"after",
|
|
235
|
+
"first-line",
|
|
236
|
+
"first-letter",
|
|
237
|
+
];
|
|
233
238
|
const isPseudoElement = legacyPseudoElements.includes(pseudoValue);
|
|
234
239
|
|
|
235
240
|
components.push({
|
|
236
|
-
type: isPseudoElement
|
|
241
|
+
type: isPseudoElement
|
|
242
|
+
? SELECTOR_TYPES.PSEUDO_ELEMENT
|
|
243
|
+
: SELECTOR_TYPES.PSEUDO_CLASS,
|
|
237
244
|
value: pseudoValue,
|
|
238
245
|
});
|
|
239
246
|
}
|
|
@@ -268,7 +275,9 @@ function parseSimpleSelector(selector) {
|
|
|
268
275
|
// This is a namespace prefix, skip it for specificity purposes
|
|
269
276
|
// The actual element name follows the |
|
|
270
277
|
nextIdx++; // Skip the |
|
|
271
|
-
const elementMatch = selector
|
|
278
|
+
const elementMatch = selector
|
|
279
|
+
.slice(nextIdx)
|
|
280
|
+
.match(/^([a-zA-Z*][\w-]*)/);
|
|
272
281
|
if (elementMatch) {
|
|
273
282
|
value = elementMatch[1]; // Use the element name after namespace
|
|
274
283
|
nextIdx += elementMatch[0].length;
|
|
@@ -443,7 +452,9 @@ export function calculateSpecificity(selector) {
|
|
|
443
452
|
|
|
444
453
|
// :not(), :is(), :has() don't count themselves, but their arguments do
|
|
445
454
|
if (
|
|
446
|
-
(value.startsWith("not(") ||
|
|
455
|
+
(value.startsWith("not(") ||
|
|
456
|
+
value.startsWith("is(") ||
|
|
457
|
+
value.startsWith("has(")) &&
|
|
447
458
|
value.endsWith(")")
|
|
448
459
|
) {
|
|
449
460
|
const funcName = value.match(/^(\w+)\(/)[1];
|
|
@@ -473,7 +484,8 @@ export function calculateSpecificity(selector) {
|
|
|
473
484
|
|
|
474
485
|
// :nth-child() and :nth-last-child() with "of S" clause
|
|
475
486
|
if (
|
|
476
|
-
(value.startsWith("nth-child(") ||
|
|
487
|
+
(value.startsWith("nth-child(") ||
|
|
488
|
+
value.startsWith("nth-last-child(")) &&
|
|
477
489
|
value.endsWith(")")
|
|
478
490
|
) {
|
|
479
491
|
const funcName = value.match(/^([\w-]+)\(/)[1];
|
|
@@ -596,10 +608,18 @@ export function compareSpecificity(spec1, spec2) {
|
|
|
596
608
|
|
|
597
609
|
// Validate all elements are valid numbers
|
|
598
610
|
for (let i = 0; i < 3; i++) {
|
|
599
|
-
if (
|
|
611
|
+
if (
|
|
612
|
+
typeof spec1[i] !== "number" ||
|
|
613
|
+
!Number.isFinite(spec1[i]) ||
|
|
614
|
+
spec1[i] < 0
|
|
615
|
+
) {
|
|
600
616
|
throw new Error(`spec1[${i}] must be a non-negative finite number`);
|
|
601
617
|
}
|
|
602
|
-
if (
|
|
618
|
+
if (
|
|
619
|
+
typeof spec2[i] !== "number" ||
|
|
620
|
+
!Number.isFinite(spec2[i]) ||
|
|
621
|
+
spec2[i] < 0
|
|
622
|
+
) {
|
|
603
623
|
throw new Error(`spec2[${i}] must be a non-negative finite number`);
|
|
604
624
|
}
|
|
605
625
|
}
|
|
@@ -669,10 +689,14 @@ export function stringifySelector(components) {
|
|
|
669
689
|
return components
|
|
670
690
|
.map((component, index) => {
|
|
671
691
|
if (!component || typeof component.type !== "string") {
|
|
672
|
-
throw new Error(
|
|
692
|
+
throw new Error(
|
|
693
|
+
`Component at index ${index} must have a 'type' property`,
|
|
694
|
+
);
|
|
673
695
|
}
|
|
674
696
|
if (component.value === undefined) {
|
|
675
|
-
throw new Error(
|
|
697
|
+
throw new Error(
|
|
698
|
+
`Component at index ${index} must have a 'value' property`,
|
|
699
|
+
);
|
|
676
700
|
}
|
|
677
701
|
switch (component.type) {
|
|
678
702
|
case SELECTOR_TYPES.ID:
|