fabric 6.0.0-beta3 → 6.0.0-beta4

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.
Files changed (51) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/index.js +309 -207
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.min.js +1 -1
  5. package/dist/index.mjs +309 -207
  6. package/dist/index.mjs.map +1 -1
  7. package/dist/index.node.cjs +309 -207
  8. package/dist/index.node.cjs.map +1 -1
  9. package/dist/index.node.mjs +309 -207
  10. package/dist/index.node.mjs.map +1 -1
  11. package/dist/src/env/index.d.ts +1 -1
  12. package/dist/src/env/types.d.ts +1 -1
  13. package/dist/src/parser/constants.d.ts +1 -1
  14. package/dist/src/parser/loadSVGFromString.d.ts +11 -5
  15. package/dist/src/parser/loadSVGFromURL.d.ts +11 -5
  16. package/dist/src/parser/parseSVGDocument.d.ts +13 -8
  17. package/dist/src/parser/parseTransformAttribute.d.ts +3 -2
  18. package/dist/src/parser/rotateMatrix.d.ts +16 -1
  19. package/dist/src/parser/scaleMatrix.d.ts +17 -1
  20. package/dist/src/parser/skewMatrix.d.ts +13 -1
  21. package/dist/src/parser/translateMatrix.d.ts +15 -1
  22. package/dist/src/parser/typedefs.d.ts +4 -0
  23. package/dist/src/shapes/Path.d.ts +30 -19
  24. package/dist/src/shapes/Polyline.d.ts +7 -0
  25. package/dist/src/typedefs.d.ts +16 -1
  26. package/dist/src/util/dom_request.d.ts +1 -1
  27. package/dist/src/util/internals/cleanupSvAttribute.d.ts +2 -0
  28. package/dist/src/util/path/regex.d.ts +0 -1
  29. package/package.json +1 -1
  30. package/src/env/index.ts +2 -1
  31. package/src/env/types.ts +1 -1
  32. package/src/gradient/Gradient.ts +3 -2
  33. package/src/parser/constants.ts +1 -1
  34. package/src/parser/loadSVGFromString.ts +18 -14
  35. package/src/parser/loadSVGFromURL.ts +26 -24
  36. package/src/parser/parseSVGDocument.ts +33 -31
  37. package/src/parser/parseTransformAttribute.ts +50 -111
  38. package/src/parser/rotateMatrix.ts +28 -16
  39. package/src/parser/scaleMatrix.ts +24 -7
  40. package/src/parser/skewMatrix.ts +45 -4
  41. package/src/parser/translateMatrix.ts +16 -7
  42. package/src/parser/typedefs.ts +13 -0
  43. package/src/shapes/Object/Object.ts +4 -2
  44. package/src/shapes/Object/ObjectGeometry.ts +4 -3
  45. package/src/shapes/Path.ts +98 -75
  46. package/src/shapes/Polyline.ts +11 -0
  47. package/src/typedefs.ts +16 -1
  48. package/src/util/internals/cleanupSvAttribute.ts +8 -0
  49. package/src/util/misc/matrix.ts +9 -22
  50. package/src/util/path/index.ts +6 -6
  51. package/src/util/path/regex.ts +2 -4
package/dist/index.js CHANGED
@@ -403,7 +403,7 @@
403
403
  }
404
404
  const cache = new Cache();
405
405
 
406
- var version = "6.0.0-beta3";
406
+ var version = "6.0.0-beta4";
407
407
 
408
408
  // use this syntax so babel plugin see this import here
409
409
  const VERSION = version;
@@ -1492,6 +1492,15 @@
1492
1492
  SVGElementName["stop"] = "stop";
1493
1493
  })(SVGElementName || (SVGElementName = {}));
1494
1494
  let SupportedSVGUnit;
1495
+
1496
+ /**
1497
+ * A transform matrix.
1498
+ * Basically a matrix in the form
1499
+ * [ a c e ]
1500
+ * [ b d f ]
1501
+ * [ 0 0 1 ]
1502
+ * For more details, see @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#matrix
1503
+ */
1495
1504
  (function (SupportedSVGUnit) {
1496
1505
  SupportedSVGUnit["mm"] = "mm";
1497
1506
  SupportedSVGUnit["cm"] = "cm";
@@ -1671,6 +1680,27 @@
1671
1680
  return !!canvas && canvas.getContext !== undefined;
1672
1681
  };
1673
1682
 
1683
+ /**
1684
+ * A scale matrix
1685
+ * Takes form
1686
+ * [x 0 0]
1687
+ * [0 y 0]
1688
+ * [0 0 1]
1689
+ * For more info, see
1690
+ * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#scale
1691
+ */
1692
+
1693
+ /**
1694
+ * Generate a scale matrix around the point 0,0
1695
+ * @param {number} x scale on X axis
1696
+ * @param {number} [y] scale on Y axis
1697
+ * @returns {TMat2D} matrix
1698
+ */
1699
+ const scaleMatrix = function (x) {
1700
+ let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : x;
1701
+ return [x, 0, 0, y, 0, 0];
1702
+ };
1703
+
1674
1704
  /**
1675
1705
  * Transforms degrees to radians.
1676
1706
  * @param {TDegree} degrees value in degrees
@@ -1685,6 +1715,37 @@
1685
1715
  */
1686
1716
  const radiansToDegrees = radians => radians / PiBy180;
1687
1717
 
1718
+ /**
1719
+ * A matrix in the form
1720
+ * [1 x 0]
1721
+ * [0 1 0]
1722
+ * [0 0 1]
1723
+ *
1724
+ * or
1725
+ *
1726
+ * [1 0 0]
1727
+ * [y 1 0]
1728
+ * [0 0 1]
1729
+ *
1730
+ * For more info, see
1731
+ * @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#skewx
1732
+ */
1733
+ const fromAngleToSkew = angle => Math.tan(degreesToRadians(angle));
1734
+
1735
+ /**
1736
+ * Generate a skew matrix for the X axis
1737
+ * @param {TDegree} skewValue translation on X axis
1738
+ * @returns {TMat2D} matrix
1739
+ */
1740
+ const skewXMatrix = skewValue => [1, 0, fromAngleToSkew(skewValue), 1, 0, 0];
1741
+
1742
+ /**
1743
+ * Generate a skew matrix for the Y axis
1744
+ * @param {TDegree} skewValue translation on Y axis
1745
+ * @returns {TMat2D} matrix
1746
+ */
1747
+ const skewYMatrix = skewValue => [1, fromAngleToSkew(skewValue), 0, 1, 0, 0];
1748
+
1688
1749
  const _excluded$k = ["translateX", "translateY", "angle"];
1689
1750
  const isIdentityMatrix = mat => mat.every((value, index) => value === iMatrix[index]);
1690
1751
 
@@ -1790,17 +1851,14 @@
1790
1851
  skewX = 0,
1791
1852
  skewY = 0
1792
1853
  } = _ref2;
1793
- let scaleMatrix = iMatrix;
1794
- if (scaleX !== 1 || scaleY !== 1 || flipX || flipY) {
1795
- scaleMatrix = [flipX ? -scaleX : scaleX, 0, 0, flipY ? -scaleY : scaleY, 0, 0];
1796
- }
1854
+ let scaleMat = scaleMatrix(flipX ? -scaleX : scaleX, flipY ? -scaleY : scaleY);
1797
1855
  if (skewX) {
1798
- scaleMatrix = multiplyTransformMatrices(scaleMatrix, [1, 0, Math.tan(degreesToRadians(skewX)), 1], true);
1856
+ scaleMat = multiplyTransformMatrices(scaleMat, skewXMatrix(skewX), true);
1799
1857
  }
1800
1858
  if (skewY) {
1801
- scaleMatrix = multiplyTransformMatrices(scaleMatrix, [1, Math.tan(degreesToRadians(skewY)), 0, 1], true);
1859
+ scaleMat = multiplyTransformMatrices(scaleMat, skewYMatrix(skewY), true);
1802
1860
  }
1803
- return scaleMatrix;
1861
+ return scaleMat;
1804
1862
  };
1805
1863
 
1806
1864
  /**
@@ -5883,6 +5941,25 @@
5883
5941
  }
5884
5942
  }
5885
5943
 
5944
+ /**
5945
+ * A translation matrix in the form of
5946
+ * [ 1 0 x ]
5947
+ * [ 0 1 y ]
5948
+ * [ 0 0 1 ]
5949
+ * See @link https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/transform#translate for more details
5950
+ */
5951
+
5952
+ /**
5953
+ * Generate a translation matrix
5954
+ * @param {number} x translation on X axis
5955
+ * @param {number} [y] translation on Y axis
5956
+ * @returns {TMat2D} matrix
5957
+ */
5958
+ const translateMatrix = function (x) {
5959
+ let y = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
5960
+ return [1, 0, 0, 1, x, y];
5961
+ };
5962
+
5886
5963
  class ObjectGeometry extends ObjectOrigin {
5887
5964
  /**
5888
5965
  * Describe object's corner position in canvas object absolute coordinates
@@ -6444,9 +6521,12 @@
6444
6521
  const rotateMatrix = calcRotateMatrix({
6445
6522
  angle: this.angle
6446
6523
  }),
6447
- center = this.getRelativeCenterPoint(),
6448
- translateMatrix = [1, 0, 0, 1, center.x, center.y],
6449
- finalMatrix = multiplyTransformMatrices(translateMatrix, rotateMatrix),
6524
+ {
6525
+ x,
6526
+ y
6527
+ } = this.getRelativeCenterPoint(),
6528
+ tMatrix = translateMatrix(x, y),
6529
+ finalMatrix = multiplyTransformMatrices(tMatrix, rotateMatrix),
6450
6530
  dim = this._getTransformedDimensions(),
6451
6531
  w = dim.x / 2,
6452
6532
  h = dim.y / 2;
@@ -7941,8 +8021,10 @@
7941
8021
  retinaScaling = this.getCanvasRetinaScaling(),
7942
8022
  width = dims.x / this.scaleX / retinaScaling,
7943
8023
  height = dims.y / this.scaleY / retinaScaling;
7944
- pCanvas.width = width;
7945
- pCanvas.height = height;
8024
+ // in case width and height are less than 1px, we have to round up.
8025
+ // since the pattern is no-repeat, this is fine
8026
+ pCanvas.width = Math.ceil(width);
8027
+ pCanvas.height = Math.ceil(height);
7946
8028
  const pCtx = pCanvas.getContext('2d');
7947
8029
  if (!pCtx) {
7948
8030
  return;
@@ -9825,7 +9907,7 @@
9825
9907
  return new RegExp('^(' + arr.join('|') + ')\\b', 'i');
9826
9908
  }
9827
9909
 
9828
- var _templateObject$1;
9910
+ var _templateObject$2, _templateObject2$1;
9829
9911
  const cssRules = {};
9830
9912
  const gradientDefs = {};
9831
9913
  const clipPaths = {};
@@ -9834,9 +9916,9 @@
9834
9916
  gradientDefs,
9835
9917
  clipPaths
9836
9918
  };
9837
- const reNum = '(?:[-+]?(?:\\d+|\\d*\\.\\d+)(?:[eE][-+]?\\d+)?)';
9919
+ const reNum = String.raw(_templateObject$2 || (_templateObject$2 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"])));
9838
9920
  const svgNS = 'http://www.w3.org/2000/svg';
9839
- const commaWsp = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(?:s+,?s*|,s*|$)"], ["(?:\\s+,?\\s*|,\\s*|$)"])));
9921
+ String.raw(_templateObject2$1 || (_templateObject2$1 = _taggedTemplateLiteral(["(?:s+,?s*|,s*|$)"], ["(?:\\s+,?\\s*|,\\s*|$)"])));
9840
9922
  const reFontDeclaration = new RegExp('(normal|italic)?\\s*(normal|small-caps)?\\s*' + '(normal|bold|bolder|lighter|100|200|300|400|500|600|700|800|900)?\\s*(' + reNum + '(?:px|cm|mm|em|pt|pc|in)*)(?:\\/(normal|' + reNum + '))?\\s+(.*)');
9841
9923
  const svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'],
9842
9924
  svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],
@@ -9967,64 +10049,51 @@
9967
10049
  return attr;
9968
10050
  }
9969
10051
 
9970
- //@ts-nocheck
9971
- function rotateMatrix(matrix, args) {
9972
- const cosValue = cos(args[0]),
9973
- sinValue = sin(args[0]);
9974
- let x = 0,
9975
- y = 0;
9976
- if (args.length === 3) {
9977
- x = args[1];
9978
- y = args[2];
9979
- }
9980
- matrix[0] = cosValue;
9981
- matrix[1] = sinValue;
9982
- matrix[2] = -sinValue;
9983
- matrix[3] = cosValue;
9984
- matrix[4] = x - (cosValue * x - sinValue * y);
9985
- matrix[5] = y - (sinValue * x + cosValue * y);
9986
- }
9987
-
9988
- //@ts-nocheck
10052
+ /**
10053
+ * A rotation matrix
10054
+ * In the form of
10055
+ * [cos(a) -sin(a) -xcos(a)+ysin(a)+x]
10056
+ * [sin(a) cos(a) -xsin(a)-ycos(a)+y]
10057
+ * [0 0 1 ]
10058
+ */
9989
10059
 
9990
- function scaleMatrix(matrix, args) {
9991
- const multiplierX = args[0],
9992
- multiplierY = args.length === 2 ? args[1] : args[0];
9993
- matrix[0] = multiplierX;
9994
- matrix[3] = multiplierY;
10060
+ /**
10061
+ * Generate a rotation matrix around the center or around a point x,y
10062
+ * @param {TDegree} angle rotation in degrees
10063
+ * @param {number} [x] translation on X axis for the pivot point
10064
+ * @param {number} [y] translation on Y axis for the pivot point
10065
+ * @returns {TMat2D} matrix
10066
+ */
10067
+ function rotateMatrix(angle) {
10068
+ let x = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
10069
+ let y = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 0;
10070
+ const angleRadiant = degreesToRadians(angle),
10071
+ cosValue = cos(angleRadiant),
10072
+ sinValue = sin(angleRadiant);
10073
+ return [cosValue, sinValue, -sinValue, cosValue, x - (cosValue * x - sinValue * y), y - (sinValue * x + cosValue * y)];
9995
10074
  }
9996
10075
 
9997
- //@ts-nocheck
9998
- function skewMatrix(matrix, args, pos) {
9999
- matrix[pos] = Math.tan(degreesToRadians(args[0]));
10000
- }
10076
+ const cleanupSvgAttribute = attributeValue => attributeValue.replace(new RegExp("(".concat(reNum, ")"), 'gi'), ' $1 ')
10077
+ // replace annoying commas and arbitrary whitespace with single spaces
10078
+ .replace(/,/gi, ' ').replace(/\s+/gi, ' ');
10001
10079
 
10002
- //@ts-nocheck
10003
-
10004
- function translateMatrix(matrix, args) {
10005
- matrix[4] = args[0];
10006
- if (args.length === 2) {
10007
- matrix[5] = args[1];
10008
- }
10009
- }
10010
-
10011
- //@ts-nocheck
10080
+ var _templateObject$1, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10012
10081
 
10013
10082
  // == begin transform regexp
10014
- const number = reNum,
10015
- skewX = '(?:(skewX)\\s*\\(\\s*(' + number + ')\\s*\\))',
10016
- skewY = '(?:(skewY)\\s*\\(\\s*(' + number + ')\\s*\\))',
10017
- rotate = '(?:(rotate)\\s*\\(\\s*(' + number + ')(?:' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + '))?\\s*\\))',
10018
- scale = '(?:(scale)\\s*\\(\\s*(' + number + ')(?:' + commaWsp + '(' + number + '))?\\s*\\))',
10019
- translate = '(?:(translate)\\s*\\(\\s*(' + number + ')(?:' + commaWsp + '(' + number + '))?\\s*\\))',
10020
- matrix = '(?:(matrix)\\s*\\(\\s*' + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + commaWsp + '(' + number + ')' + '\\s*\\))',
10021
- transform = '(?:' + matrix + '|' + translate + '|' + scale + '|' + rotate + '|' + skewX + '|' + skewY + ')',
10022
- transforms = '(?:' + transform + '(?:' + commaWsp + '*' + transform + ')*' + ')',
10023
- transformList = '^\\s*(?:' + transforms + '?)\\s*$',
10024
- // http://www.w3.org/TR/SVG/coords.html#TransformAttribute
10025
- reTransformList = new RegExp(transformList),
10026
- // == end transform regexp
10027
- reTransform = new RegExp(transform, 'g');
10083
+ const p$1 = "(".concat(reNum, ")");
10084
+ const skewX = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1);
10085
+ const skewY = String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["(skewY)(", ")"], ["(skewY)\\(", "\\)"])), p$1);
10086
+ const rotate = String.raw(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["(rotate)(", "(?: ", " ", ")?)"], ["(rotate)\\(", "(?: ", " ", ")?\\)"])), p$1, p$1, p$1);
10087
+ const scale = String.raw(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["(scale)(", "(?: ", ")?)"], ["(scale)\\(", "(?: ", ")?\\)"])), p$1, p$1);
10088
+ const translate = String.raw(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["(translate)(", "(?: ", ")?)"], ["(translate)\\(", "(?: ", ")?\\)"])), p$1, p$1);
10089
+ const matrix = String.raw(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["(matrix)(", " ", " ", " ", " ", " ", ")"], ["(matrix)\\(", " ", " ", " ", " ", " ", "\\)"])), p$1, p$1, p$1, p$1, p$1, p$1);
10090
+ const transform = "(?:".concat(matrix, "|").concat(translate, "|").concat(rotate, "|").concat(scale, "|").concat(skewX, "|").concat(skewY, ")");
10091
+ const transforms = "(?:".concat(transform, "*)");
10092
+ const transformList = String.raw(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["^s*(?:", "?)s*$"], ["^\\s*(?:", "?)\\s*$"])), transforms);
10093
+ // http://www.w3.org/TR/SVG/coords.html#TransformAttribute
10094
+ const reTransformList = new RegExp(transformList);
10095
+ // == end transform regexp
10096
+ const reTransform = new RegExp(transform, 'g');
10028
10097
 
10029
10098
  /**
10030
10099
  * Parses "transform" attribute, returning an array of values
@@ -10032,58 +10101,56 @@
10032
10101
  * @function
10033
10102
  * @memberOf fabric
10034
10103
  * @param {String} attributeValue String containing attribute value
10035
- * @return {Array} Array of 6 elements representing transformation matrix
10104
+ * @return {TTransformMatrix} Array of 6 elements representing transformation matrix
10036
10105
  */
10037
10106
  function parseTransformAttribute(attributeValue) {
10107
+ // first we clean the string
10108
+ attributeValue = cleanupSvgAttribute(attributeValue)
10109
+ // remove spaces around front parentheses
10110
+ .replace(/\s*([()])\s*/gi, '$1');
10111
+
10038
10112
  // start with identity matrix
10039
- let matrix = iMatrix.concat();
10040
10113
  const matrices = [];
10041
10114
 
10042
10115
  // return if no argument was given or
10043
10116
  // an argument does not match transform attribute regexp
10044
10117
  if (!attributeValue || attributeValue && !reTransformList.test(attributeValue)) {
10045
- return matrix;
10118
+ return [...iMatrix];
10046
10119
  }
10047
- attributeValue.replace(reTransform, function (match) {
10048
- const m = new RegExp(transform).exec(match).filter(function (match) {
10049
- // match !== '' && match != null
10050
- return !!match;
10051
- }),
10052
- operation = m[1],
10053
- args = m.slice(2).map(parseFloat);
10120
+ for (const match of attributeValue.matchAll(reTransform)) {
10121
+ const transformMatch = new RegExp(transform).exec(match[0]);
10122
+ if (!transformMatch) {
10123
+ continue;
10124
+ }
10125
+ let matrix = iMatrix;
10126
+ const matchedParams = transformMatch.filter(m => !!m);
10127
+ const [, operation, ...rawArgs] = matchedParams;
10128
+ const [arg0, arg1, arg2, arg3, arg4, arg5] = rawArgs.map(arg => parseFloat(arg));
10054
10129
  switch (operation) {
10055
10130
  case 'translate':
10056
- translateMatrix(matrix, args);
10131
+ matrix = translateMatrix(arg0, arg1);
10057
10132
  break;
10058
10133
  case 'rotate':
10059
- args[0] = degreesToRadians(args[0]);
10060
- rotateMatrix(matrix, args);
10134
+ matrix = rotateMatrix(arg0, arg1, arg2);
10061
10135
  break;
10062
10136
  case 'scale':
10063
- scaleMatrix(matrix, args);
10137
+ matrix = scaleMatrix(arg0, arg1);
10064
10138
  break;
10065
10139
  case 'skewX':
10066
- skewMatrix(matrix, args, 2);
10140
+ matrix = skewXMatrix(arg0);
10067
10141
  break;
10068
10142
  case 'skewY':
10069
- skewMatrix(matrix, args, 1);
10143
+ matrix = skewYMatrix(arg0);
10070
10144
  break;
10071
10145
  case 'matrix':
10072
- matrix = args;
10146
+ matrix = [arg0, arg1, arg2, arg3, arg4, arg5];
10073
10147
  break;
10074
10148
  }
10075
10149
 
10076
10150
  // snapshot current matrix into matrices array
10077
- matrices.push(matrix.concat());
10078
- // reset
10079
- matrix = iMatrix.concat();
10080
- });
10081
- let combinedMatrix = matrices[0];
10082
- while (matrices.length > 1) {
10083
- matrices.shift();
10084
- combinedMatrix = multiplyTransformMatrices(combinedMatrix, matrices[0]);
10151
+ matrices.push(matrix);
10085
10152
  }
10086
- return combinedMatrix;
10153
+ return matrices.reduce((acc, matrix) => multiplyTransformMatrices(acc, matrix), iMatrix);
10087
10154
  }
10088
10155
 
10089
10156
  //@ts-nocheck
@@ -14496,6 +14563,7 @@
14496
14563
  */
14497
14564
  static fromElement(el, instance, svgOptions) {
14498
14565
  const gradientUnits = parseGradientUnits(el);
14566
+ const center = instance._findCenterFromElement();
14499
14567
  return new this(_objectSpread2({
14500
14568
  id: el.getAttribute('id') || undefined,
14501
14569
  type: parseType(el),
@@ -14507,8 +14575,8 @@
14507
14575
  gradientUnits,
14508
14576
  gradientTransform: parseTransformAttribute(el.getAttribute('gradientTransform') || '')
14509
14577
  }, gradientUnits === 'pixels' ? {
14510
- offsetX: -instance.left,
14511
- offsetY: -instance.top
14578
+ offsetX: instance.width / 2 - center.x,
14579
+ offsetY: instance.height / 2 - center.y
14512
14580
  } : {
14513
14581
  offsetX: 0,
14514
14582
  offsetY: 0
@@ -14807,21 +14875,18 @@
14807
14875
  }
14808
14876
  }
14809
14877
 
14810
- var _templateObject, _templateObject2;
14811
- // absolute value number
14812
- const absNumberRegExStr = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(?:d*.d+|d+.?)(?:[eE][-+]?d+)?"], ["(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?"])));
14813
- const numberRegExStr = "[-+]?".concat(absNumberRegExStr);
14878
+ var _templateObject;
14814
14879
 
14815
14880
  /**
14816
14881
  * p for param
14817
14882
  * using "bad naming" here because it makes the regex much easier to read
14818
14883
  */
14819
- const p = "(".concat(numberRegExStr, ")");
14884
+ const p = "(".concat(reNum, ")");
14820
14885
  const reMoveToCommand = "(M) (?:".concat(p, " ").concat(p, " ?)+");
14821
14886
  const reLineCommand = "(L) (?:".concat(p, " ").concat(p, " ?)+");
14822
14887
  const reHorizontalLineCommand = "(H) (?:".concat(p, " ?)+");
14823
14888
  const reVerticalLineCommand = "(V) (?:".concat(p, " ?)+");
14824
- const reClosePathCommand = String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["(Z)s*"], ["(Z)\\s*"])));
14889
+ const reClosePathCommand = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(Z)s*"], ["(Z)\\s*"])));
14825
14890
  const reCubicCurveCommand = "(C) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
14826
14891
  const reCubicCurveShortcutCommand = "(S) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
14827
14892
  const reQuadraticCurveCommand = "(Q) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
@@ -14878,6 +14943,9 @@
14878
14943
  * @param rotateX
14879
14944
  */
14880
14945
  const arcToSegments = (toX, toY, rx, ry, large, sweep, rotateX) => {
14946
+ if (rx === 0 || ry === 0) {
14947
+ return [];
14948
+ }
14881
14949
  let fromX = 0,
14882
14950
  fromY = 0,
14883
14951
  root = 0;
@@ -15469,9 +15537,7 @@
15469
15537
  const parsePath = pathString => {
15470
15538
  // clean the string
15471
15539
  // add spaces around the numbers
15472
- pathString = pathString.replace(new RegExp("(".concat(numberRegExStr, ")"), 'gi'), ' $1 ')
15473
- // replace annoying commas and arbitrary whitespace with single spaces
15474
- .replace(/,/gi, ' ').replace(/\s+/gi, ' ');
15540
+ pathString = cleanupSvgAttribute(pathString);
15475
15541
  const res = [];
15476
15542
  for (const match of pathString.matchAll(new RegExp(rePathCommand, 'gi'))) {
15477
15543
  let matchStr = match[0];
@@ -15642,8 +15708,8 @@
15642
15708
 
15643
15709
  /**
15644
15710
  * Constructor
15645
- * @param {TSimplePathData} path Path data (sequence of coordinates and corresponding "command" tokens)
15646
- * @param {Object} [options] Options object
15711
+ * @param {TComplexPathData} path Path data (sequence of coordinates and corresponding "command" tokens)
15712
+ * @param {Partial<PathProps>} [options] Options object
15647
15713
  * @return {Path} thisArg
15648
15714
  */
15649
15715
  constructor(path) {
@@ -15655,20 +15721,31 @@
15655
15721
  } = _ref,
15656
15722
  options = _objectWithoutProperties(_ref, _excluded$9);
15657
15723
  super(options);
15658
- const pathTL = this._setPath(path || []);
15659
- const origin = this.translateToGivenOrigin(new Point(left !== null && left !== void 0 ? left : pathTL.x, top !== null && top !== void 0 ? top : pathTL.y), typeof left === 'number' ? this.originX : 'left', typeof top === 'number' ? this.originY : 'top', this.originX, this.originY);
15660
- this.setPositionByOrigin(origin, this.originX, this.originY);
15724
+ this._setPath(path || [], true);
15725
+ typeof left === 'number' && this.set('left', left);
15726
+ typeof top === 'number' && this.set('top', top);
15661
15727
  }
15662
15728
 
15663
15729
  /**
15664
15730
  * @private
15665
- * @param {TSimplePathData | string} path Path data (sequence of coordinates and corresponding "command" tokens)
15731
+ * @param {TComplexPathData | string} path Path data (sequence of coordinates and corresponding "command" tokens)
15666
15732
  * @param {boolean} [adjustPosition] pass true to reposition the object according to the bounding box
15667
15733
  * @returns {Point} top left position of the bounding box, useful for complementary positioning
15668
15734
  */
15669
15735
  _setPath(path, adjustPosition) {
15670
15736
  this.path = makePathSimpler(Array.isArray(path) ? path : parsePath(path));
15671
- return this.setDimensions();
15737
+ this.setBoundingBox(adjustPosition);
15738
+ }
15739
+
15740
+ /**
15741
+ * This function is an helper for svg import. it returns the center of the object in the svg
15742
+ * untransformed coordinates, by look at the polyline/polygon points.
15743
+ * @private
15744
+ * @return {Point} center point from element coordinates
15745
+ */
15746
+ _findCenterFromElement() {
15747
+ const bbox = this._calcBoundsFromPath();
15748
+ return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);
15672
15749
  }
15673
15750
 
15674
15751
  /**
@@ -15676,9 +15753,7 @@
15676
15753
  * @param {CanvasRenderingContext2D} ctx context to render path on
15677
15754
  */
15678
15755
  _renderPathCommands(ctx) {
15679
- let current,
15680
- // current instruction
15681
- subpathStartX = 0,
15756
+ let subpathStartX = 0,
15682
15757
  subpathStartY = 0,
15683
15758
  x = 0,
15684
15759
  // current x
@@ -15690,39 +15765,38 @@
15690
15765
  const l = -this.pathOffset.x,
15691
15766
  t = -this.pathOffset.y;
15692
15767
  ctx.beginPath();
15693
- for (let i = 0, len = this.path.length; i < len; ++i) {
15694
- current = this.path[i];
15695
- switch (current[0] // first letter
15768
+ for (const command of this.path) {
15769
+ switch (command[0] // first letter
15696
15770
  ) {
15697
15771
  case 'L':
15698
15772
  // lineto, absolute
15699
- x = current[1];
15700
- y = current[2];
15773
+ x = command[1];
15774
+ y = command[2];
15701
15775
  ctx.lineTo(x + l, y + t);
15702
15776
  break;
15703
15777
  case 'M':
15704
15778
  // moveTo, absolute
15705
- x = current[1];
15706
- y = current[2];
15779
+ x = command[1];
15780
+ y = command[2];
15707
15781
  subpathStartX = x;
15708
15782
  subpathStartY = y;
15709
15783
  ctx.moveTo(x + l, y + t);
15710
15784
  break;
15711
15785
  case 'C':
15712
15786
  // bezierCurveTo, absolute
15713
- x = current[5];
15714
- y = current[6];
15715
- controlX = current[3];
15716
- controlY = current[4];
15717
- ctx.bezierCurveTo(current[1] + l, current[2] + t, controlX + l, controlY + t, x + l, y + t);
15787
+ x = command[5];
15788
+ y = command[6];
15789
+ controlX = command[3];
15790
+ controlY = command[4];
15791
+ ctx.bezierCurveTo(command[1] + l, command[2] + t, controlX + l, controlY + t, x + l, y + t);
15718
15792
  break;
15719
15793
  case 'Q':
15720
15794
  // quadraticCurveTo, absolute
15721
- ctx.quadraticCurveTo(current[1] + l, current[2] + t, current[3] + l, current[4] + t);
15722
- x = current[3];
15723
- y = current[4];
15724
- controlX = current[1];
15725
- controlY = current[2];
15795
+ ctx.quadraticCurveTo(command[1] + l, command[2] + t, command[3] + l, command[4] + t);
15796
+ x = command[3];
15797
+ y = command[4];
15798
+ controlX = command[1];
15799
+ controlY = command[2];
15726
15800
  break;
15727
15801
  case 'Z':
15728
15802
  x = subpathStartX;
@@ -15786,6 +15860,11 @@
15786
15860
  const path = joinPath(this.path, config.NUM_FRACTION_DIGITS);
15787
15861
  return ['<path ', 'COMMON_PARTS', "d=\"".concat(path, "\" stroke-linecap=\"round\" />\n")];
15788
15862
  }
15863
+
15864
+ /**
15865
+ * @private
15866
+ * @return the path command's translate transform attribute
15867
+ */
15789
15868
  _getOffsetTransform() {
15790
15869
  const digits = config.NUM_FRACTION_DIGITS;
15791
15870
  return " translate(".concat(toFixed(-this.pathOffset.x, digits), ", ").concat(toFixed(-this.pathOffset.y, digits), ")");
@@ -15825,6 +15904,9 @@
15825
15904
  return this.path.length;
15826
15905
  }
15827
15906
  setDimensions() {
15907
+ this.setBoundingBox();
15908
+ }
15909
+ setBoundingBox(adjustPosition) {
15828
15910
  const {
15829
15911
  left,
15830
15912
  top,
@@ -15837,13 +15919,9 @@
15837
15919
  height,
15838
15920
  pathOffset
15839
15921
  });
15840
- return new Point(left, top);
15922
+ adjustPosition && this.setPositionByOrigin(new Point(left, top), 'left', 'top');
15841
15923
  }
15842
-
15843
- /**
15844
- * @private
15845
- */
15846
- _calcDimensions() {
15924
+ _calcBoundsFromPath() {
15847
15925
  const bounds = [];
15848
15926
  let subpathStartX = 0,
15849
15927
  subpathStartY = 0,
@@ -15851,34 +15929,34 @@
15851
15929
  // current x
15852
15930
  y = 0; // current y
15853
15931
 
15854
- for (let i = 0; i < this.path.length; ++i) {
15855
- const current = this.path[i]; // current instruction
15856
- switch (current[0] // first letter
15932
+ for (const command of this.path) {
15933
+ // current instruction
15934
+ switch (command[0] // first letter
15857
15935
  ) {
15858
15936
  case 'L':
15859
15937
  // lineto, absolute
15860
- x = current[1];
15861
- y = current[2];
15938
+ x = command[1];
15939
+ y = command[2];
15862
15940
  bounds.push(new Point(subpathStartX, subpathStartY), new Point(x, y));
15863
15941
  break;
15864
15942
  case 'M':
15865
15943
  // moveTo, absolute
15866
- x = current[1];
15867
- y = current[2];
15944
+ x = command[1];
15945
+ y = command[2];
15868
15946
  subpathStartX = x;
15869
15947
  subpathStartY = y;
15870
15948
  break;
15871
15949
  case 'C':
15872
15950
  // bezierCurveTo, absolute
15873
- bounds.push(...getBoundsOfCurve(x, y, current[1], current[2], current[3], current[4], current[5], current[6]));
15874
- x = current[5];
15875
- y = current[6];
15951
+ bounds.push(...getBoundsOfCurve(x, y, command[1], command[2], command[3], command[4], command[5], command[6]));
15952
+ x = command[5];
15953
+ y = command[6];
15876
15954
  break;
15877
15955
  case 'Q':
15878
15956
  // quadraticCurveTo, absolute
15879
- bounds.push(...getBoundsOfCurve(x, y, current[1], current[2], current[1], current[2], current[3], current[4]));
15880
- x = current[3];
15881
- y = current[4];
15957
+ bounds.push(...getBoundsOfCurve(x, y, command[1], command[2], command[1], command[2], command[3], command[4]));
15958
+ x = command[3];
15959
+ y = command[4];
15882
15960
  break;
15883
15961
  case 'Z':
15884
15962
  x = subpathStartX;
@@ -15886,7 +15964,14 @@
15886
15964
  break;
15887
15965
  }
15888
15966
  }
15889
- const bbox = makeBoundingBoxFromPoints(bounds);
15967
+ return makeBoundingBoxFromPoints(bounds);
15968
+ }
15969
+
15970
+ /**
15971
+ * @private
15972
+ */
15973
+ _calcDimensions() {
15974
+ const bbox = this._calcBoundsFromPath();
15890
15975
  const strokeCorrection = this.fromSVG ? 0 : this.strokeWidth / 2;
15891
15976
  return _objectSpread2(_objectSpread2({}, bbox), {}, {
15892
15977
  left: bbox.left - strokeCorrection,
@@ -15920,9 +16005,8 @@
15920
16005
  * @static
15921
16006
  * @memberOf Path
15922
16007
  * @param {SVGElement} element to parse
15923
- * @param {Function} callback Callback to invoke when an Path instance is created
15924
- * @param {Object} [options] Options object
15925
- * @param {Function} [callback] Options callback invoked after parsing is finished
16008
+ * @param {(path: Path) => void} callback Callback to invoke after the element has been parsed
16009
+ * @param {Partial<PathProps>} [options] Options object
15926
16010
  */
15927
16011
  static fromElement(element, callback, options) {
15928
16012
  const parsedAttributes = parseAttributes(element, this.ATTRIBUTE_NAMES);
@@ -17637,6 +17721,17 @@
17637
17721
  strokeOffset: new Point(bboxNoStroke.left, bboxNoStroke.top).subtract(new Point(bbox.left, bbox.top))
17638
17722
  });
17639
17723
  }
17724
+
17725
+ /**
17726
+ * This function is an helper for svg import. it returns the center of the object in the svg
17727
+ * untransformed coordinates, by look at the polyline/polygon points.
17728
+ * @private
17729
+ * @return {Point} center point from element coordinates
17730
+ */
17731
+ _findCenterFromElement() {
17732
+ const bbox = makeBoundingBoxFromPoints(this.points);
17733
+ return new Point(bbox.left + bbox.width / 2, bbox.top + bbox.height / 2);
17734
+ }
17640
17735
  setDimensions() {
17641
17736
  this.setBoundingBox();
17642
17737
  }
@@ -24681,116 +24776,123 @@
24681
24776
  }
24682
24777
  }
24683
24778
 
24684
- //@ts-nocheck
24685
-
24686
24779
  /**
24687
24780
  * Parses an SVG document, converts it to an array of corresponding fabric.* instances and passes them to a callback
24688
24781
  * @static
24689
24782
  * @function
24690
24783
  * @memberOf fabric
24691
- * @param {SVGDocument} doc SVG document to parse
24692
- * @param {Function} callback Callback to call when parsing is finished;
24693
- * It's being passed an array of elements (parsed from a document).
24694
- * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
24695
- * @param {Object} [parsingOptions] options for parsing document
24696
- * @param {String} [parsingOptions.crossOrigin] crossOrigin settings
24697
- * @param {AbortSignal} [parsingOptions.signal] see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
24784
+ * @param {HTMLElement} doc SVG document to parse
24785
+ * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
24786
+ * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
24787
+ * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
24788
+ * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
24789
+ * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
24790
+ * or extra custom manipulation
24791
+ * @param {Object} [options] Object containing options for parsing
24792
+ * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
24793
+ * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
24698
24794
  */
24699
- function parseSVGDocument(doc, callback, reviver, parsingOptions) {
24795
+ function parseSVGDocument(doc, callback, reviver) {
24796
+ let {
24797
+ crossOrigin,
24798
+ signal
24799
+ } = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
24700
24800
  if (!doc) {
24701
24801
  return;
24702
24802
  }
24703
- if (parsingOptions && parsingOptions.signal && parsingOptions.signal.aborted) {
24803
+ if (signal && signal.aborted) {
24704
24804
  throw new Error('`options.signal` is in `aborted` state');
24705
24805
  }
24706
24806
  parseUseDirectives(doc);
24707
24807
  const svgUid = uid(),
24708
- options = applyViewboxTransform(doc),
24709
- descendants = Array.from(doc.getElementsByTagName('*'));
24710
- options.crossOrigin = parsingOptions && parsingOptions.crossOrigin;
24711
- options.svgUid = svgUid;
24712
- options.signal = parsingOptions && parsingOptions.signal;
24808
+ descendants = Array.from(doc.getElementsByTagName('*')),
24809
+ options = _objectSpread2(_objectSpread2({}, applyViewboxTransform(doc)), {}, {
24810
+ crossOrigin,
24811
+ svgUid,
24812
+ signal
24813
+ });
24713
24814
  const elements = descendants.filter(function (el) {
24714
24815
  applyViewboxTransform(el);
24715
24816
  return svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')) && !hasAncestorWithNodeName(el, svgInvalidAncestorsRegEx); // http://www.w3.org/TR/SVG/struct.html#DefsElement
24716
24817
  });
24717
24818
 
24718
24819
  if (!elements || elements && !elements.length) {
24719
- callback && callback([], {});
24820
+ callback([], {}, [], descendants);
24720
24821
  return;
24721
24822
  }
24722
24823
  const localClipPaths = {};
24723
- descendants.filter(function (el) {
24724
- return el.nodeName.replace('svg:', '') === 'clipPath';
24725
- }).forEach(function (el) {
24824
+ descendants.filter(el => el.nodeName.replace('svg:', '') === 'clipPath').forEach(el => {
24726
24825
  const id = el.getAttribute('id');
24727
- localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(function (el) {
24728
- return svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', ''));
24729
- });
24826
+ localClipPaths[id] = Array.from(el.getElementsByTagName('*')).filter(el => svgValidTagNamesRegEx.test(el.nodeName.replace('svg:', '')));
24730
24827
  });
24731
24828
  gradientDefs[svgUid] = getGradientDefs(doc);
24732
24829
  cssRules[svgUid] = getCSSRules(doc);
24733
24830
  clipPaths[svgUid] = localClipPaths;
24734
24831
  // Precedence of rules: style > class > attribute
24735
- parseElements(elements, function (instances, elements) {
24832
+ parseElements(elements, (instances, elements) => {
24736
24833
  if (callback) {
24737
24834
  callback(instances, options, elements, descendants);
24738
24835
  delete gradientDefs[svgUid];
24739
24836
  delete cssRules[svgUid];
24740
24837
  delete clipPaths[svgUid];
24741
24838
  }
24742
- }, Object.assign({}, options), reviver, parsingOptions);
24839
+ }, _objectSpread2({}, options), reviver, {
24840
+ crossOrigin,
24841
+ signal
24842
+ });
24743
24843
  }
24744
24844
 
24745
- //@ts-nocheck
24746
-
24747
24845
  /**
24748
24846
  * Takes url corresponding to an SVG document, and parses it into a set of fabric objects.
24749
24847
  * Note that SVG is fetched via XMLHttpRequest, so it needs to conform to SOP (Same Origin Policy)
24750
24848
  * @memberOf fabric
24751
- * @param {String} url
24752
- * @param {Function} callback
24753
- * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
24849
+ * @param {string} url where the SVG is
24850
+ * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
24851
+ * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
24852
+ * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
24853
+ * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
24854
+ * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
24855
+ * or extra custom manipulation
24754
24856
  * @param {Object} [options] Object containing options for parsing
24755
- * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
24857
+ * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
24756
24858
  * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
24757
24859
  */
24758
- function loadSVGFromURL(url, callback, reviver, options) {
24759
- new request(url.replace(/^\n\s*/, '').trim(), {
24760
- method: 'get',
24761
- onComplete: onComplete,
24762
- signal: options && options.signal
24763
- });
24764
- function onComplete(r) {
24860
+ function loadSVGFromURL(url, callback, reviver) {
24861
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
24862
+ const onComplete = r => {
24765
24863
  const xml = r.responseXML;
24766
24864
  if (!xml || !xml.documentElement) {
24767
- callback && callback(null);
24865
+ callback(null, {}, [], []);
24768
24866
  return false;
24769
24867
  }
24770
- parseSVGDocument(xml.documentElement, function (results, _options, elements, allElements) {
24771
- callback && callback(results, _options, elements, allElements);
24772
- }, reviver, options);
24773
- }
24868
+ parseSVGDocument(xml.documentElement, callback, reviver, options);
24869
+ };
24870
+ request(url.replace(/^\n\s*/, '').trim(), {
24871
+ method: 'get',
24872
+ onComplete,
24873
+ signal: options.signal
24874
+ });
24774
24875
  }
24775
24876
 
24776
- //@ts-nocheck
24777
-
24778
24877
  /**
24779
24878
  * Takes string corresponding to an SVG document, and parses it into a set of fabric objects
24780
24879
  * @memberOf fabric
24781
- * @param {String} string
24782
- * @param {Function} callback
24783
- * @param {Function} [reviver] Method for further parsing of SVG elements, called after each fabric object created.
24880
+ * @param {String} string representing the svg
24881
+ * @param {TSvgParsedCallback} callback Invoked when the parsing is done, with null if parsing wasn't possible with the list of svg nodes.
24882
+ * {@link TSvgParsedCallback} also receives `allElements` array as the last argument. This is the full list of svg nodes available in the document.
24883
+ * You may want to use it if you are trying to regroup the objects as they were originally grouped in the SVG. ( This was the reason why it was added )
24884
+ * @param {TSvgReviverCallback} [reviver] Extra callback for further parsing of SVG elements, called after each fabric object has been created.
24885
+ * Takes as input the original svg element and the generated `FabricObject` as arguments. Used to inspect extra properties not parsed by fabric,
24886
+ * or extra custom manipulation
24784
24887
  * @param {Object} [options] Object containing options for parsing
24785
- * @param {String} [options.crossOrigin] crossOrigin crossOrigin setting to use for external resources
24888
+ * @param {String} [options.crossOrigin] crossOrigin setting to use for external resources
24786
24889
  * @param {AbortSignal} [options.signal] handle aborting, see https://developer.mozilla.org/en-US/docs/Web/API/AbortController/signal
24787
24890
  */
24788
24891
  function loadSVGFromString(string, callback, reviver, options) {
24789
24892
  const parser = new (getWindow().DOMParser)(),
24893
+ // should we use `image/svg+xml` here?
24790
24894
  doc = parser.parseFromString(string.trim(), 'text/xml');
24791
- parseSVGDocument(doc.documentElement, function (results, _options, elements, allElements) {
24792
- callback(results, _options, elements, allElements);
24793
- }, reviver, options);
24895
+ parseSVGDocument(doc.documentElement, callback, reviver, options);
24794
24896
  }
24795
24897
 
24796
24898
  const getSize = poly => {