fabric 6.4.1 → 6.4.2

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 (85) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/index.js +123 -95
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.min.js +1 -1
  5. package/dist/index.min.js.map +1 -1
  6. package/dist/index.min.mjs +1 -1
  7. package/dist/index.min.mjs.map +1 -1
  8. package/dist/index.mjs +123 -95
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/index.node.cjs +123 -95
  11. package/dist/index.node.cjs.map +1 -1
  12. package/dist/index.node.mjs +123 -95
  13. package/dist/index.node.mjs.map +1 -1
  14. package/dist/package.json.min.mjs +1 -1
  15. package/dist/package.json.mjs +1 -1
  16. package/dist/src/canvas/DOMManagers/CanvasDOMManager.min.mjs +1 -1
  17. package/dist/src/canvas/DOMManagers/CanvasDOMManager.min.mjs.map +1 -1
  18. package/dist/src/canvas/DOMManagers/CanvasDOMManager.mjs +0 -1
  19. package/dist/src/canvas/DOMManagers/CanvasDOMManager.mjs.map +1 -1
  20. package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
  21. package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
  22. package/dist/src/canvas/SelectableCanvas.mjs +0 -1
  23. package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
  24. package/dist/src/config.d.ts +5 -1
  25. package/dist/src/config.d.ts.map +1 -1
  26. package/dist/src/config.min.mjs +1 -1
  27. package/dist/src/config.min.mjs.map +1 -1
  28. package/dist/src/config.mjs +6 -2
  29. package/dist/src/config.mjs.map +1 -1
  30. package/dist/src/parser/constants.d.ts +0 -1
  31. package/dist/src/parser/constants.d.ts.map +1 -1
  32. package/dist/src/parser/constants.min.mjs +1 -1
  33. package/dist/src/parser/constants.min.mjs.map +1 -1
  34. package/dist/src/parser/constants.mjs +1 -2
  35. package/dist/src/parser/constants.mjs.map +1 -1
  36. package/dist/src/shapes/Line.min.mjs +1 -1
  37. package/dist/src/shapes/Line.min.mjs.map +1 -1
  38. package/dist/src/shapes/Line.mjs +0 -1
  39. package/dist/src/shapes/Line.mjs.map +1 -1
  40. package/dist/src/shapes/Path.min.mjs +1 -1
  41. package/dist/src/shapes/Path.min.mjs.map +1 -1
  42. package/dist/src/shapes/Path.mjs +7 -1
  43. package/dist/src/shapes/Path.mjs.map +1 -1
  44. package/dist/src/shapes/Text/StyledText.min.mjs +1 -1
  45. package/dist/src/shapes/Text/StyledText.min.mjs.map +1 -1
  46. package/dist/src/shapes/Text/StyledText.mjs +0 -1
  47. package/dist/src/shapes/Text/StyledText.mjs.map +1 -1
  48. package/dist/src/util/misc/boundingBoxFromPoints.d.ts.map +1 -1
  49. package/dist/src/util/misc/boundingBoxFromPoints.min.mjs +1 -1
  50. package/dist/src/util/misc/boundingBoxFromPoints.min.mjs.map +1 -1
  51. package/dist/src/util/misc/boundingBoxFromPoints.mjs +17 -30
  52. package/dist/src/util/misc/boundingBoxFromPoints.mjs.map +1 -1
  53. package/dist/src/util/path/index.d.ts.map +1 -1
  54. package/dist/src/util/path/index.min.mjs +1 -1
  55. package/dist/src/util/path/index.min.mjs.map +1 -1
  56. package/dist/src/util/path/index.mjs +51 -47
  57. package/dist/src/util/path/index.mjs.map +1 -1
  58. package/dist/src/util/path/regex.d.ts +2 -1
  59. package/dist/src/util/path/regex.d.ts.map +1 -1
  60. package/dist/src/util/path/regex.min.mjs +1 -1
  61. package/dist/src/util/path/regex.min.mjs.map +1 -1
  62. package/dist/src/util/path/regex.mjs +41 -16
  63. package/dist/src/util/path/regex.mjs.map +1 -1
  64. package/dist/src/util/path/typedefs.d.ts +1 -0
  65. package/dist/src/util/path/typedefs.d.ts.map +1 -1
  66. package/dist-extensions/src/config.d.ts +5 -1
  67. package/dist-extensions/src/config.d.ts.map +1 -1
  68. package/dist-extensions/src/parser/constants.d.ts +0 -1
  69. package/dist-extensions/src/parser/constants.d.ts.map +1 -1
  70. package/dist-extensions/src/util/misc/boundingBoxFromPoints.d.ts.map +1 -1
  71. package/dist-extensions/src/util/path/index.d.ts.map +1 -1
  72. package/dist-extensions/src/util/path/regex.d.ts +2 -1
  73. package/dist-extensions/src/util/path/regex.d.ts.map +1 -1
  74. package/dist-extensions/src/util/path/typedefs.d.ts +1 -0
  75. package/dist-extensions/src/util/path/typedefs.d.ts.map +1 -1
  76. package/package.json +1 -1
  77. package/src/config.ts +6 -2
  78. package/src/parser/constants.ts +0 -2
  79. package/src/shapes/Path.ts +1 -1
  80. package/src/util/misc/boundingBoxFromPoints.ts +15 -24
  81. package/src/util/path/__snapshots__/index.spec.ts.snap +462 -0
  82. package/src/util/path/index.spec.ts +107 -1
  83. package/src/util/path/index.ts +56 -51
  84. package/src/util/path/regex.ts +29 -22
  85. package/src/util/path/typedefs.ts +22 -0
package/dist/index.mjs CHANGED
@@ -156,9 +156,13 @@ class BaseConfiguration {
156
156
  _defineProperty(this, "forceGLPutImageData", false);
157
157
  /**
158
158
  * If disabled boundsOfCurveCache is not used. For apps that make heavy usage of pencil drawing probably disabling it is better
159
- * @default true
159
+ * With the standard behaviour of fabric to translate all curves in absolute commands and by not subtracting the starting point from
160
+ * the curve is very hard to hit any cache.
161
+ * Enable only if you know why it could be useful.
162
+ * Candidate for removal/simplification
163
+ * @default false
160
164
  */
161
- _defineProperty(this, "cachesBoundsOfCurve", true);
165
+ _defineProperty(this, "cachesBoundsOfCurve", false);
162
166
  /**
163
167
  * Map of font files
164
168
  * Map<fontFamily, pathToFile> of font files
@@ -401,7 +405,7 @@ class Cache {
401
405
  }
402
406
  const cache = new Cache();
403
407
 
404
- var version = "6.4.1";
408
+ var version = "6.4.2";
405
409
 
406
410
  // use this syntax so babel plugin see this import here
407
411
  const VERSION = version;
@@ -4285,36 +4289,25 @@ const stopEvent = e => {
4285
4289
  * @return {Object} Object with left, top, width, height properties
4286
4290
  */
4287
4291
  const makeBoundingBoxFromPoints = points => {
4288
- if (points.length === 0) {
4289
- return {
4290
- left: 0,
4291
- top: 0,
4292
- width: 0,
4293
- height: 0
4294
- };
4292
+ let left = 0,
4293
+ top = 0,
4294
+ width = 0,
4295
+ height = 0;
4296
+ for (let i = 0, len = points.length; i < len; i++) {
4297
+ const {
4298
+ x,
4299
+ y
4300
+ } = points[i];
4301
+ if (x > width || !i) width = x;
4302
+ if (x < left || !i) left = x;
4303
+ if (y > height || !i) height = y;
4304
+ if (y < top || !i) top = y;
4295
4305
  }
4296
- const {
4297
- min,
4298
- max
4299
- } = points.reduce((_ref, curr) => {
4300
- let {
4301
- min,
4302
- max
4303
- } = _ref;
4304
- return {
4305
- min: min.min(curr),
4306
- max: max.max(curr)
4307
- };
4308
- }, {
4309
- min: new Point(points[0]),
4310
- max: new Point(points[0])
4311
- });
4312
- const size = max.subtract(min);
4313
4306
  return {
4314
- left: min.x,
4315
- top: min.y,
4316
- width: size.x,
4317
- height: size.y
4307
+ left,
4308
+ top,
4309
+ width: width - left,
4310
+ height: height - top
4318
4311
  };
4319
4312
  };
4320
4313
 
@@ -4813,10 +4806,9 @@ function getSvgRegex(arr) {
4813
4806
  return new RegExp('^(' + arr.join('|') + ')\\b', 'i');
4814
4807
  }
4815
4808
 
4816
- var _templateObject$2, _templateObject2$1;
4817
- const reNum = String.raw(_templateObject$2 || (_templateObject$2 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"])));
4809
+ var _templateObject$1;
4810
+ const reNum = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(?:[-+]?(?:d*.d+|d+.?)(?:[eE][-+]?d+)?)"], ["(?:[-+]?(?:\\d*\\.\\d+|\\d+\\.?)(?:[eE][-+]?\\d+)?)"])));
4818
4811
  const svgNS = 'http://www.w3.org/2000/svg';
4819
- String.raw(_templateObject2$1 || (_templateObject2$1 = _taggedTemplateLiteral(["(?:s+,?s*|,s*|$)"], ["(?:\\s+,?\\s*|,\\s*|$)"])));
4820
4812
  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+(.*)');
4821
4813
  const svgValidTagNames = ['path', 'circle', 'polygon', 'polyline', 'ellipse', 'rect', 'line', 'image', 'text'],
4822
4814
  svgViewBoxElements = ['symbol', 'image', 'marker', 'pattern', 'view', 'svg'],
@@ -10482,11 +10474,11 @@ const cleanupSvgAttribute = attributeValue => attributeValue.replace(regex$1, '
10482
10474
  // replace annoying commas and arbitrary whitespace with single spaces
10483
10475
  .replace(/,/gi, ' ').replace(/\s+/gi, ' ');
10484
10476
 
10485
- var _templateObject$1, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10477
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7;
10486
10478
 
10487
10479
  // == begin transform regexp
10488
10480
  const p$1 = "(".concat(reNum, ")");
10489
- const skewX = String.raw(_templateObject$1 || (_templateObject$1 = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1);
10481
+ const skewX = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(skewX)(", ")"], ["(skewX)\\(", "\\)"])), p$1);
10490
10482
  const skewY = String.raw(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["(skewY)(", ")"], ["(skewY)\\(", "\\)"])), p$1);
10491
10483
  const rotate = String.raw(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["(rotate)(", "(?: ", " ", ")?)"], ["(rotate)\\(", "(?: ", " ", ")?\\)"])), p$1, p$1, p$1);
10492
10484
  const scale = String.raw(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["(scale)(", "(?: ", ")?)"], ["(scale)\\(", "(?: ", ")?\\)"])), p$1, p$1);
@@ -11939,24 +11931,50 @@ const findScaleToFit = (source, destination) => Math.min(destination.width / sou
11939
11931
  */
11940
11932
  const findScaleToCover = (source, destination) => Math.max(destination.width / source.width, destination.height / source.height);
11941
11933
 
11942
- var _templateObject;
11934
+ const commaWsp = "\\s*,?\\s*";
11943
11935
 
11944
11936
  /**
11945
11937
  * p for param
11946
11938
  * using "bad naming" here because it makes the regex much easier to read
11939
+ * p is a number that is preceded by an arbitary number of spaces, maybe 0,
11940
+ * a comma or not, and then possibly more spaces or not.
11947
11941
  */
11948
- const p = "(".concat(reNum, ")");
11949
- const reMoveToCommand = "(M) (?:".concat(p, " ").concat(p, " ?)+");
11950
- const reLineCommand = "(L) (?:".concat(p, " ").concat(p, " ?)+");
11951
- const reHorizontalLineCommand = "(H) (?:".concat(p, " ?)+");
11952
- const reVerticalLineCommand = "(V) (?:".concat(p, " ?)+");
11953
- const reClosePathCommand = String.raw(_templateObject || (_templateObject = _taggedTemplateLiteral(["(Z)s*"], ["(Z)\\s*"])));
11954
- const reCubicCurveCommand = "(C) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
11955
- const reCubicCurveShortcutCommand = "(S) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
11956
- const reQuadraticCurveCommand = "(Q) (?:".concat(p, " ").concat(p, " ").concat(p, " ").concat(p, " ?)+");
11957
- const reQuadraticCurveShortcutCommand = "(T) (?:".concat(p, " ").concat(p, " ?)+");
11958
- const reArcCommand = "(A) (?:".concat(p, " ").concat(p, " ").concat(p, " ([01]) ?([01]) ").concat(p, " ").concat(p, " ?)+");
11959
- const rePathCommand = "(?:(?:".concat(reMoveToCommand, ")") + "|(?:".concat(reLineCommand, ")") + "|(?:".concat(reHorizontalLineCommand, ")") + "|(?:".concat(reVerticalLineCommand, ")") + "|(?:".concat(reClosePathCommand, ")") + "|(?:".concat(reCubicCurveCommand, ")") + "|(?:".concat(reCubicCurveShortcutCommand, ")") + "|(?:".concat(reQuadraticCurveCommand, ")") + "|(?:".concat(reQuadraticCurveShortcutCommand, ")") + "|(?:".concat(reArcCommand, "))");
11942
+ const p = "".concat(commaWsp, "(").concat(reNum, ")");
11943
+
11944
+ // const reMoveToCommand = `(M) ?(?:${p}${p} ?)+`;
11945
+
11946
+ // const reLineCommand = `(L) ?(?:${p}${p} ?)+`;
11947
+
11948
+ // const reHorizontalLineCommand = `(H) ?(?:${p} ?)+`;
11949
+
11950
+ // const reVerticalLineCommand = `(V) ?(?:${p} ?)+`;
11951
+
11952
+ // const reClosePathCommand = String.raw`(Z)\s*`;
11953
+
11954
+ // const reCubicCurveCommand = `(C) ?(?:${p}${p}${p}${p}${p}${p} ?)+`;
11955
+
11956
+ // const reCubicCurveShortcutCommand = `(S) ?(?:${p}${p}${p}${p} ?)+`;
11957
+
11958
+ // const reQuadraticCurveCommand = `(Q) ?(?:${p}${p}${p}${p} ?)+`;
11959
+
11960
+ // const reQuadraticCurveShortcutCommand = `(T) ?(?:${p}${p} ?)+`;
11961
+
11962
+ const reArcCommandPoints = "".concat(p).concat(p).concat(p).concat(commaWsp, "([01])").concat(commaWsp, "([01])").concat(p).concat(p);
11963
+ // const reArcCommand = `(A) ?(?:${reArcCommandPoints} ?)+`;
11964
+
11965
+ // export const rePathCommandGroups =
11966
+ // `(?:(?:${reMoveToCommand})` +
11967
+ // `|(?:${reLineCommand})` +
11968
+ // `|(?:${reHorizontalLineCommand})` +
11969
+ // `|(?:${reVerticalLineCommand})` +
11970
+ // `|(?:${reClosePathCommand})` +
11971
+ // `|(?:${reCubicCurveCommand})` +
11972
+ // `|(?:${reCubicCurveShortcutCommand})` +
11973
+ // `|(?:${reQuadraticCurveCommand})` +
11974
+ // `|(?:${reQuadraticCurveShortcutCommand})` +
11975
+ // `|(?:${reArcCommand}))`;
11976
+
11977
+ const rePathCommand = '[mzlhvcsqta][^mzlhvcsqta]*';
11960
11978
 
11961
11979
  /**
11962
11980
  * Commands that may be repeated
@@ -12586,8 +12604,19 @@ const getPointOnPath = function (path, distance) {
12586
12604
  }
12587
12605
  };
12588
12606
  const rePathCmdAll = new RegExp(rePathCommand, 'gi');
12589
- const rePathCmd = new RegExp(rePathCommand, 'i');
12590
-
12607
+ const regExpArcCommandPoints = new RegExp(reArcCommandPoints, 'g');
12608
+ const reMyNum = new RegExp(reNum, 'gi');
12609
+ const commandLengths = {
12610
+ m: 2,
12611
+ l: 2,
12612
+ h: 1,
12613
+ v: 1,
12614
+ c: 6,
12615
+ s: 4,
12616
+ q: 4,
12617
+ t: 2,
12618
+ a: 7
12619
+ };
12591
12620
  /**
12592
12621
  *
12593
12622
  * @param {string} pathString
@@ -12600,52 +12629,45 @@ const rePathCmd = new RegExp(rePathCommand, 'i');
12600
12629
  * ];
12601
12630
  */
12602
12631
  const parsePath = pathString => {
12603
- // clean the string
12604
- // add spaces around the numbers
12605
- pathString = cleanupSvgAttribute(pathString);
12606
- const res = [];
12607
- for (let [matchStr] of pathString.matchAll(rePathCmdAll)) {
12608
- const chain = [];
12609
- let paramArr;
12610
- do {
12611
- paramArr = rePathCmd.exec(matchStr);
12612
- if (!paramArr) {
12613
- break;
12614
- }
12615
- // ignore undefined match groups
12616
- const filteredGroups = paramArr.filter(g => g);
12617
- // remove the first element from the match array since it's just the whole command
12618
- filteredGroups.shift();
12619
- // if we can't parse the number, just interpret it as a string
12620
- // (since it's probably the path command)
12621
- const command = filteredGroups.map(g => {
12622
- const numParse = Number.parseFloat(g);
12623
- if (Number.isNaN(numParse)) {
12624
- return g;
12625
- } else {
12626
- return numParse;
12627
- }
12628
- });
12629
- chain.push(command);
12630
- // stop now if it's a z command
12631
- if (filteredGroups.length <= 1) {
12632
- break;
12632
+ var _pathString$match;
12633
+ const chain = [];
12634
+ const all = (_pathString$match = pathString.match(rePathCmdAll)) !== null && _pathString$match !== void 0 ? _pathString$match : [];
12635
+ for (const matchStr of all) {
12636
+ // take match string and save the first letter as the command
12637
+ const commandLetter = matchStr[0];
12638
+ // in case of Z we have very little to do
12639
+ if (commandLetter === 'z' || commandLetter === 'Z') {
12640
+ chain.push([commandLetter]);
12641
+ continue;
12642
+ }
12643
+ const commandLength = commandLengths[commandLetter.toLowerCase()];
12644
+ let paramArr = [];
12645
+ if (commandLetter === 'a' || commandLetter === 'A') {
12646
+ // the arc command ha some peculariaties that requires a special regex other than numbers
12647
+ // it is possible to avoid using a space between the sweep and large arc flags, making them either
12648
+ // 00, 01, 10 or 11, making them identical to a plain number for the regex reMyNum
12649
+ // reset the regexp
12650
+ regExpArcCommandPoints.lastIndex = 0;
12651
+ for (let out = null; out = regExpArcCommandPoints.exec(matchStr);) {
12652
+ paramArr.push(...out.slice(1));
12633
12653
  }
12634
- // remove the last part of the chained command
12635
- filteredGroups.shift();
12636
- // ` ?` is to support commands with optional spaces between flags
12637
- matchStr = matchStr.replace(new RegExp("".concat(filteredGroups.join(' ?'), " ?$")), '');
12638
- } while (paramArr);
12639
- // add the chain, convert multiple m's to l's in the process
12640
- chain.reverse().forEach((c, idx) => {
12641
- const transformed = repeatedCommands[c[0]];
12642
- if (idx > 0 && (transformed == 'l' || transformed == 'L')) {
12643
- c[0] = transformed;
12654
+ } else {
12655
+ paramArr = matchStr.match(reMyNum) || [];
12656
+ }
12657
+
12658
+ // inspect the length of paramArr, if is longer than commandLength
12659
+ // we are dealing with repeated commands
12660
+ for (let i = 0; i < paramArr.length; i += commandLength) {
12661
+ const newCommand = new Array(commandLength);
12662
+ const transformedCommand = repeatedCommands[commandLetter];
12663
+ newCommand[0] = i > 0 && transformedCommand ? transformedCommand : commandLetter;
12664
+ for (let j = 0; j < commandLength; j++) {
12665
+ newCommand[j + 1] = parseFloat(paramArr[i + j]);
12644
12666
  }
12645
- res.push(c);
12646
- });
12667
+ chain.push(newCommand);
12668
+ }
12647
12669
  }
12648
- return res;
12670
+ return chain;
12649
12671
  };
12650
12672
 
12651
12673
  /**
@@ -16569,7 +16591,13 @@ class Path extends FabricObject {
16569
16591
  // lineto, absolute
16570
16592
  x = command[1];
16571
16593
  y = command[2];
16572
- bounds.push(new Point(subpathStartX, subpathStartY), new Point(x, y));
16594
+ bounds.push({
16595
+ x: subpathStartX,
16596
+ y: subpathStartY
16597
+ }, {
16598
+ x,
16599
+ y
16600
+ });
16573
16601
  break;
16574
16602
  case 'M':
16575
16603
  // moveTo, absolute