fabric 6.0.2 → 6.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.
Files changed (207) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/index.js +250 -101
  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 +250 -101
  9. package/dist/index.mjs.map +1 -1
  10. package/dist/index.node.cjs +250 -101
  11. package/dist/index.node.cjs.map +1 -1
  12. package/dist/index.node.mjs +250 -101
  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/ClassRegistry.d.ts +1 -0
  17. package/dist/src/ClassRegistry.d.ts.map +1 -1
  18. package/dist/src/ClassRegistry.min.mjs +1 -1
  19. package/dist/src/ClassRegistry.min.mjs.map +1 -1
  20. package/dist/src/ClassRegistry.mjs +3 -0
  21. package/dist/src/ClassRegistry.mjs.map +1 -1
  22. package/dist/src/Collection.d.ts +3 -3
  23. package/dist/src/Collection.d.ts.map +1 -1
  24. package/dist/src/EventTypeDefs.d.ts +19 -11
  25. package/dist/src/EventTypeDefs.d.ts.map +1 -1
  26. package/dist/src/LayoutManager/LayoutManager.d.ts.map +1 -1
  27. package/dist/src/LayoutManager/LayoutManager.min.mjs +1 -1
  28. package/dist/src/LayoutManager/LayoutManager.min.mjs.map +1 -1
  29. package/dist/src/LayoutManager/LayoutManager.mjs +2 -2
  30. package/dist/src/LayoutManager/LayoutManager.mjs.map +1 -1
  31. package/dist/src/Shadow.d.ts.map +1 -1
  32. package/dist/src/Shadow.min.mjs +1 -1
  33. package/dist/src/Shadow.min.mjs.map +1 -1
  34. package/dist/src/Shadow.mjs +1 -5
  35. package/dist/src/Shadow.mjs.map +1 -1
  36. package/dist/src/canvas/DOMManagers/util.d.ts.map +1 -1
  37. package/dist/src/canvas/DOMManagers/util.min.mjs +1 -1
  38. package/dist/src/canvas/DOMManagers/util.min.mjs.map +1 -1
  39. package/dist/src/canvas/DOMManagers/util.mjs +9 -15
  40. package/dist/src/canvas/DOMManagers/util.mjs.map +1 -1
  41. package/dist/src/canvas/SelectableCanvas.d.ts.map +1 -1
  42. package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
  43. package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
  44. package/dist/src/canvas/SelectableCanvas.mjs +3 -0
  45. package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
  46. package/dist/src/canvas/StaticCanvas.d.ts +20 -24
  47. package/dist/src/canvas/StaticCanvas.d.ts.map +1 -1
  48. package/dist/src/color/util.d.ts.map +1 -1
  49. package/dist/src/constants.d.ts +1 -0
  50. package/dist/src/constants.d.ts.map +1 -1
  51. package/dist/src/constants.min.mjs +1 -1
  52. package/dist/src/constants.min.mjs.map +1 -1
  53. package/dist/src/constants.mjs +2 -1
  54. package/dist/src/constants.mjs.map +1 -1
  55. package/dist/src/controls/controlRendering.d.ts +1 -1
  56. package/dist/src/controls/controlRendering.d.ts.map +1 -1
  57. package/dist/src/controls/controlRendering.min.mjs.map +1 -1
  58. package/dist/src/controls/controlRendering.mjs.map +1 -1
  59. package/dist/src/controls/fireEvent.d.ts +2 -2
  60. package/dist/src/controls/fireEvent.d.ts.map +1 -1
  61. package/dist/src/controls/fireEvent.min.mjs.map +1 -1
  62. package/dist/src/controls/fireEvent.mjs.map +1 -1
  63. package/dist/src/controls/index.d.ts +1 -0
  64. package/dist/src/controls/index.d.ts.map +1 -1
  65. package/dist/src/controls/index.min.mjs +1 -1
  66. package/dist/src/controls/index.mjs +1 -0
  67. package/dist/src/controls/index.mjs.map +1 -1
  68. package/dist/src/controls/pathControl.d.ts +12 -0
  69. package/dist/src/controls/pathControl.d.ts.map +1 -0
  70. package/dist/src/controls/pathControl.min.mjs +2 -0
  71. package/dist/src/controls/pathControl.min.mjs.map +1 -0
  72. package/dist/src/controls/pathControl.mjs +156 -0
  73. package/dist/src/controls/pathControl.mjs.map +1 -0
  74. package/dist/src/controls/polyControl.d.ts.map +1 -1
  75. package/dist/src/controls/polyControl.min.mjs +1 -1
  76. package/dist/src/controls/polyControl.min.mjs.map +1 -1
  77. package/dist/src/controls/polyControl.mjs +1 -9
  78. package/dist/src/controls/polyControl.mjs.map +1 -1
  79. package/dist/src/controls/util.d.ts +1 -1
  80. package/dist/src/controls/wrapWithFireEvent.d.ts +5 -3
  81. package/dist/src/controls/wrapWithFireEvent.d.ts.map +1 -1
  82. package/dist/src/controls/wrapWithFireEvent.min.mjs +1 -1
  83. package/dist/src/controls/wrapWithFireEvent.min.mjs.map +1 -1
  84. package/dist/src/controls/wrapWithFireEvent.mjs +7 -4
  85. package/dist/src/controls/wrapWithFireEvent.mjs.map +1 -1
  86. package/dist/src/controls/wrapWithFixedAnchor.d.ts.map +1 -1
  87. package/dist/src/env/index.d.ts.map +1 -1
  88. package/dist/src/env/node.d.ts.map +1 -1
  89. package/dist/src/filters/BaseFilter.d.ts.map +1 -1
  90. package/dist/src/filters/BaseFilter.min.mjs.map +1 -1
  91. package/dist/src/filters/BaseFilter.mjs +0 -1
  92. package/dist/src/filters/BaseFilter.mjs.map +1 -1
  93. package/dist/src/filters/ColorMatrix.d.ts.map +1 -1
  94. package/dist/src/filters/ColorMatrixFilters.d.ts +8 -96
  95. package/dist/src/filters/ColorMatrixFilters.d.ts.map +1 -1
  96. package/dist/src/filters/Convolute.d.ts +2 -1
  97. package/dist/src/filters/Convolute.d.ts.map +1 -1
  98. package/dist/src/filters/shaders/baseFilter.d.ts +1 -1
  99. package/dist/src/filters/shaders/baseFilter.d.ts.map +1 -1
  100. package/dist/src/filters/utils.d.ts.map +1 -1
  101. package/dist/src/parser/normalizeAttr.d.ts.map +1 -1
  102. package/dist/src/parser/parseStyleString.d.ts.map +1 -1
  103. package/dist/src/parser/parseStyleString.min.mjs +1 -1
  104. package/dist/src/parser/parseStyleString.min.mjs.map +1 -1
  105. package/dist/src/parser/parseStyleString.mjs +1 -0
  106. package/dist/src/parser/parseStyleString.mjs.map +1 -1
  107. package/dist/src/parser/parseUseDirectives.d.ts.map +1 -1
  108. package/dist/src/parser/parseUseDirectives.min.mjs +1 -1
  109. package/dist/src/parser/parseUseDirectives.min.mjs.map +1 -1
  110. package/dist/src/parser/parseUseDirectives.mjs +61 -43
  111. package/dist/src/parser/parseUseDirectives.mjs.map +1 -1
  112. package/dist/src/shapes/Group.d.ts +20 -20
  113. package/dist/src/shapes/Group.d.ts.map +1 -1
  114. package/dist/src/shapes/IText/DraggableTextDelegate.d.ts.map +1 -1
  115. package/dist/src/shapes/IText/ITextBehavior.d.ts.map +1 -1
  116. package/dist/src/shapes/IText/ITextBehavior.min.mjs.map +1 -1
  117. package/dist/src/shapes/IText/ITextBehavior.mjs +0 -1
  118. package/dist/src/shapes/IText/ITextBehavior.mjs.map +1 -1
  119. package/dist/src/shapes/Image.d.ts.map +1 -1
  120. package/dist/src/shapes/Image.min.mjs.map +1 -1
  121. package/dist/src/shapes/Image.mjs +0 -2
  122. package/dist/src/shapes/Image.mjs.map +1 -1
  123. package/dist/src/shapes/Path.d.ts +9 -9
  124. package/dist/src/shapes/Path.d.ts.map +1 -1
  125. package/dist/src/shapes/Polyline.d.ts +1 -1
  126. package/dist/src/shapes/Rect.d.ts +1 -1
  127. package/dist/src/shapes/Text/Text.d.ts +1 -1
  128. package/dist/src/shapes/Text/Text.d.ts.map +1 -1
  129. package/dist/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
  130. package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs.map +1 -1
  131. package/dist/src/shapes/Text/TextSVGExportMixin.mjs +0 -2
  132. package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
  133. package/dist/src/shapes/Textbox.d.ts.map +1 -1
  134. package/dist/src/shapes/Textbox.min.mjs.map +1 -1
  135. package/dist/src/shapes/Textbox.mjs +0 -2
  136. package/dist/src/shapes/Textbox.mjs.map +1 -1
  137. package/dist/src/util/applyMixins.d.ts.map +1 -1
  138. package/dist/src/util/dom_misc.d.ts.map +1 -1
  139. package/dist/src/util/dom_misc.min.mjs +1 -1
  140. package/dist/src/util/dom_misc.min.mjs.map +1 -1
  141. package/dist/src/util/dom_misc.mjs +7 -9
  142. package/dist/src/util/dom_misc.mjs.map +1 -1
  143. package/dist/src/util/internals/cloneDeep.d.ts.map +1 -1
  144. package/dist/src/util/internals/console.d.ts +1 -1
  145. package/dist/src/util/internals/findRight.d.ts.map +1 -1
  146. package/dist/src/util/internals/removeFromArray.d.ts.map +1 -1
  147. package/dist/src/util/misc/dom.d.ts.map +1 -1
  148. package/dist/src/util/misc/groupSVGElements.d.ts.map +1 -1
  149. package/dist/src/util/misc/matrix.d.ts.map +1 -1
  150. package/dist/src/util/misc/objectEnlive.d.ts +1 -1
  151. package/dist/src/util/misc/objectEnlive.d.ts.map +1 -1
  152. package/dist/src/util/misc/objectEnlive.min.mjs +1 -1
  153. package/dist/src/util/misc/objectEnlive.min.mjs.map +1 -1
  154. package/dist/src/util/misc/objectEnlive.mjs +7 -11
  155. package/dist/src/util/misc/objectEnlive.mjs.map +1 -1
  156. package/dist/src/util/misc/objectTransforms.d.ts.map +1 -1
  157. package/dist/src/util/misc/pick.d.ts.map +1 -1
  158. package/dist/src/util/misc/planeChange.d.ts.map +1 -1
  159. package/dist/src/util/misc/svgParsing.d.ts.map +1 -1
  160. package/dist/src/util/misc/textStyles.d.ts.map +1 -1
  161. package/dist/src/util/path/index.d.ts +0 -1
  162. package/dist/src/util/path/index.d.ts.map +1 -1
  163. package/dist/src/util/path/index.min.mjs +1 -1
  164. package/dist/src/util/path/index.min.mjs.map +1 -1
  165. package/dist/src/util/path/index.mjs +1 -2
  166. package/dist/src/util/path/index.mjs.map +1 -1
  167. package/dist/src/util/path/typedefs.d.ts +1 -0
  168. package/dist/src/util/path/typedefs.d.ts.map +1 -1
  169. package/dist/src/util/typeAssertions.d.ts +2 -2
  170. package/dist/src/util/typeAssertions.d.ts.map +1 -1
  171. package/lib/aligning_guidelines.js +76 -1
  172. package/lib/centering_guidelines.js +3 -1
  173. package/package.json +3 -3
  174. package/src/ClassRegistry.spec.ts +39 -0
  175. package/src/ClassRegistry.ts +4 -0
  176. package/src/EventTypeDefs.ts +22 -10
  177. package/src/LayoutManager/ActiveSelectionLayoutManager.spec.ts +1 -0
  178. package/src/LayoutManager/LayoutManager.spec.ts +1 -0
  179. package/src/LayoutManager/LayoutManager.ts +2 -0
  180. package/src/Shadow.ts +1 -6
  181. package/src/canvas/DOMManagers/util.ts +11 -15
  182. package/src/canvas/SelectableCanvas.spec.ts +18 -0
  183. package/src/canvas/SelectableCanvas.ts +3 -0
  184. package/src/constants.ts +1 -0
  185. package/src/controls/controlRendering.ts +4 -2
  186. package/src/controls/fireEvent.ts +2 -2
  187. package/src/controls/index.ts +1 -0
  188. package/src/controls/pathControl.spec.ts +75 -0
  189. package/src/controls/pathControl.ts +293 -0
  190. package/src/controls/polyControl.ts +1 -1
  191. package/src/controls/wrapWithFireEvent.ts +14 -5
  192. package/src/filters/BaseFilter.ts +1 -2
  193. package/src/parser/parseStyleString.ts +1 -0
  194. package/src/parser/parseUseDirectives.test.ts +113 -0
  195. package/src/parser/parseUseDirectives.ts +64 -58
  196. package/src/shapes/IText/ITextBehavior.ts +4 -2
  197. package/src/shapes/Image.ts +0 -2
  198. package/src/shapes/Text/TextSVGExportMixin.ts +0 -2
  199. package/src/shapes/Textbox.ts +0 -2
  200. package/src/util/dom_misc.ts +17 -10
  201. package/src/util/misc/objectEnlive.spec.ts +68 -0
  202. package/src/util/misc/objectEnlive.ts +7 -13
  203. package/src/util/path/__snapshots__/index.spec.ts.snap +327 -0
  204. package/src/util/path/index.spec.ts +13 -2
  205. package/src/util/path/index.ts +2 -4
  206. package/src/util/path/typedefs.ts +2 -0
  207. package/.gitmodules +0 -3
package/dist/index.mjs CHANGED
@@ -401,7 +401,7 @@ class Cache {
401
401
  }
402
402
  const cache = new Cache();
403
403
 
404
- var version = "6.0.2";
404
+ var version = "6.2.0";
405
405
 
406
406
  // use this syntax so babel plugin see this import here
407
407
  const VERSION = version;
@@ -430,6 +430,7 @@ const ROTATE = 'rotate';
430
430
  const SKEWING = 'skewing';
431
431
  const RESIZING = 'resizing';
432
432
  const MODIFY_POLY = 'modifyPoly';
433
+ const MODIFY_PATH = 'modifyPath';
433
434
  const CHANGED = 'changed';
434
435
  const SCALE = 'scale';
435
436
  const SCALE_X = 'scaleX';
@@ -459,6 +460,9 @@ class ClassRegistry {
459
460
  this[JSON$1] = new Map();
460
461
  this[SVG] = new Map();
461
462
  }
463
+ has(classType) {
464
+ return this[JSON$1].has(classType);
465
+ }
462
466
  getClass(classType) {
463
467
  const constructor = this[JSON$1].get(classType);
464
468
  if (!constructor) {
@@ -1953,8 +1957,13 @@ const enlivenObjectEnlivables = function (serializedObject) {
1953
1957
  if (!value) {
1954
1958
  return value;
1955
1959
  }
1956
- // clipPath or shadow or gradient
1957
- if (value.type) {
1960
+ /**
1961
+ * clipPath or shadow or gradient or text on a path or a pattern,
1962
+ * or the backgroundImage or overlayImage of canvas
1963
+ * If we have a type and there is a classe registered for it, we enlive it.
1964
+ * If there is no class registered for it we return the value as is
1965
+ * */
1966
+ if (value.type && classRegistry.has(value.type)) {
1958
1967
  return enlivenObjects([value], {
1959
1968
  signal
1960
1969
  }).then(_ref => {
@@ -1963,15 +1972,6 @@ const enlivenObjectEnlivables = function (serializedObject) {
1963
1972
  return enlived;
1964
1973
  });
1965
1974
  }
1966
- // pattern
1967
- if (value.source) {
1968
- return classRegistry.getClass('pattern').fromObject(value, {
1969
- signal
1970
- }).then(pattern => {
1971
- instances.push(pattern);
1972
- return pattern;
1973
- });
1974
- }
1975
1975
  return value;
1976
1976
  });
1977
1977
  const keys = Object.keys(serializedObject);
@@ -2845,6 +2845,7 @@ function getScrollLeftTop(element) {
2845
2845
  top
2846
2846
  };
2847
2847
  }
2848
+ let elementLoop = element;
2848
2849
  const docElement = doc.documentElement,
2849
2850
  body = doc.body || {
2850
2851
  scrollLeft: 0,
@@ -2854,19 +2855,16 @@ function getScrollLeftTop(element) {
2854
2855
  // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,
2855
2856
  // but the .parentNode of a root ShadowDOM node will always be null, instead
2856
2857
  // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938
2857
- // @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
2858
- while (element && (element.parentNode || element.host)) {
2859
- // @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
2860
- element = element.parentNode || element.host;
2861
- // @ts-expect-error because element is typed as HTMLElement but it can go up to document
2862
- if (element === doc) {
2858
+ while (elementLoop && (elementLoop.parentNode || elementLoop.host)) {
2859
+ elementLoop = elementLoop.parentNode || elementLoop.host;
2860
+ if (elementLoop === doc) {
2863
2861
  left = body.scrollLeft || docElement.scrollLeft || 0;
2864
2862
  top = body.scrollTop || docElement.scrollTop || 0;
2865
2863
  } else {
2866
- left += element.scrollLeft || 0;
2867
- top += element.scrollTop || 0;
2864
+ left += elementLoop.scrollLeft || 0;
2865
+ top += elementLoop.scrollTop || 0;
2868
2866
  }
2869
- if (element.nodeType === 1 && element.style.position === 'fixed') {
2867
+ if (elementLoop.nodeType === 1 && elementLoop.style.position === 'fixed') {
2870
2868
  break;
2871
2869
  }
2872
2870
  }
@@ -2939,29 +2937,23 @@ const setCSSDimensions = (el, _ref2) => {
2939
2937
  */
2940
2938
  function getElementOffset(element) {
2941
2939
  var _getWindowFromElement;
2942
- let box = {
2943
- left: 0,
2944
- top: 0
2945
- };
2946
2940
  const doc = element && getDocumentFromElement(element),
2947
2941
  offset = {
2948
2942
  left: 0,
2949
2943
  top: 0
2950
- },
2951
- offsetAttributes = {
2952
- borderLeftWidth: LEFT,
2953
- borderTopWidth: TOP,
2954
- paddingLeft: LEFT,
2955
- paddingTop: TOP
2956
2944
  };
2957
2945
  if (!doc) {
2958
2946
  return offset;
2959
2947
  }
2960
2948
  const elemStyle = ((_getWindowFromElement = getWindowFromElement(element)) === null || _getWindowFromElement === void 0 ? void 0 : _getWindowFromElement.getComputedStyle(element, null)) || {};
2961
- for (const attr in offsetAttributes) {
2962
- // @ts-expect-error TS learn to iterate!
2963
- offset[offsetAttributes[attr]] += parseInt(elemStyle[attr], 10) || 0;
2964
- }
2949
+ offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0;
2950
+ offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0;
2951
+ offset.left += parseInt(elemStyle.paddingLeft, 10) || 0;
2952
+ offset.top += parseInt(elemStyle.paddingTop, 10) || 0;
2953
+ let box = {
2954
+ left: 0,
2955
+ top: 0
2956
+ };
2965
2957
  const docElem = doc.documentElement;
2966
2958
  if (typeof element.getBoundingClientRect !== 'undefined') {
2967
2959
  box = element.getBoundingClientRect();
@@ -6737,11 +6729,7 @@ class Shadow {
6737
6729
 
6738
6730
  constructor(arg0) {
6739
6731
  const options = typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;
6740
- Object.assign(this, Shadow.ownDefaults);
6741
- for (const prop in options) {
6742
- // @ts-expect-error for loops are so messy in TS
6743
- this[prop] = options[prop];
6744
- }
6732
+ Object.assign(this, Shadow.ownDefaults, options);
6745
6733
  this.id = uid();
6746
6734
  }
6747
6735
 
@@ -8190,14 +8178,16 @@ classRegistry.setClass(FabricObject$1, 'object');
8190
8178
 
8191
8179
  /**
8192
8180
  * Wrap an action handler with firing an event if the action is performed
8193
- * @param {Function} actionHandler the function to wrap
8194
- * @return {Function} a function with an action handler signature
8181
+ * @param {TModificationEvents} eventName the event we want to fire
8182
+ * @param {TransformActionHandler<T>} actionHandler the function to wrap
8183
+ * @param {object} extraEventInfo extra information to pas to the event handler
8184
+ * @return {TransformActionHandler<T>} a function with an action handler signature
8195
8185
  */
8196
- const wrapWithFireEvent = (eventName, actionHandler) => {
8186
+ const wrapWithFireEvent = (eventName, actionHandler, extraEventInfo) => {
8197
8187
  return (eventData, transform, x, y) => {
8198
8188
  const actionPerformed = actionHandler(eventData, transform, x, y);
8199
8189
  if (actionPerformed) {
8200
- fireEvent(eventName, commonEventInfo(eventData, transform, x, y));
8190
+ fireEvent(eventName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), extraEventInfo));
8201
8191
  }
8202
8192
  return actionPerformed;
8203
8193
  };
@@ -10669,6 +10659,7 @@ function parseStyleObject(style, oStyle) {
10669
10659
  */
10670
10660
  function parseStyleString(style, oStyle) {
10671
10661
  style.replace(/;\s*$/, '').split(';').forEach(chunk => {
10662
+ if (!chunk) return;
10672
10663
  const [attr, value] = chunk.split(':');
10673
10664
  oStyle[attr.trim().toLowerCase()] = value.trim();
10674
10665
  });
@@ -11098,7 +11089,7 @@ class LayoutManager {
11098
11089
  const {
11099
11090
  target
11100
11091
  } = context;
11101
- return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? {
11092
+ return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY, MODIFY_PATH].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? {
11102
11093
  type: LAYOUT_TYPE_OBJECT_MODIFIED,
11103
11094
  trigger: key,
11104
11095
  e,
@@ -12035,7 +12026,7 @@ const arcToSegments = (toX, toY, rx, ry, large, sweep, rotateX) => {
12035
12026
 
12036
12027
  // Convert into cubic bezier segments <= 90deg
12037
12028
  const segments = Math.ceil(Math.abs(dtheta / PI * 2)),
12038
- result = new Array(segments),
12029
+ result = [],
12039
12030
  mDelta = dtheta / segments,
12040
12031
  mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2);
12041
12032
  let th3 = mTheta + mDelta;
@@ -12586,7 +12577,6 @@ const rePathCmd = new RegExp(rePathCommand, 'i');
12586
12577
  * ['Q', 3, 5, 2, 1, 4, 0],
12587
12578
  * ['Q', 9, 12, 2, 1, 4, 0],
12588
12579
  * ];
12589
- *
12590
12580
  */
12591
12581
  const parsePath = pathString => {
12592
12582
  // clean the string
@@ -14046,6 +14036,9 @@ class SelectableCanvas extends StaticCanvas {
14046
14036
  if (this._currentTransform && this._currentTransform.target === obj) {
14047
14037
  this.endCurrentTransform(e);
14048
14038
  }
14039
+ if (isActiveSelection(obj) && obj === this._hoveredTarget) {
14040
+ this._hoveredTarget = undefined;
14041
+ }
14049
14042
  this._activeObject = undefined;
14050
14043
  return true;
14051
14044
  }
@@ -18707,8 +18700,6 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
18707
18700
  * @return {String}
18708
18701
  */
18709
18702
  getSvgStyles(skipShadow) {
18710
- // cant use ts-expect-error because of ts 5.3 cross check
18711
- // @ts-ignore TS doesn't respect this type casting
18712
18703
  return "".concat(super.getSvgStyles(skipShadow), " white-space: pre;");
18713
18704
  }
18714
18705
 
@@ -20661,7 +20652,6 @@ class ITextBehavior extends FabricText {
20661
20652
  } : undefined);
20662
20653
  this._fireSelectionChanged();
20663
20654
  if (this.canvas) {
20664
- // @ts-expect-error in reality it is an IText instance
20665
20655
  this.canvas.fire('text:editing:entered', {
20666
20656
  target: this,
20667
20657
  e
@@ -23157,8 +23147,6 @@ class Textbox extends IText {
23157
23147
  * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
23158
23148
  * @return {Object} object representation of an instance
23159
23149
  */
23160
- // cant use ts-expect-error because of ts 5.3 cross check
23161
- // @ts-ignore TS this typing limitations
23162
23150
  toObject() {
23163
23151
  let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
23164
23152
  return super.toObject(['minWidth', 'splitByGrapheme', ...propertiesToInclude]);
@@ -24350,8 +24338,6 @@ class FabricImage extends FabricObject {
24350
24338
  */
24351
24339
  drawCacheOnCanvas(ctx) {
24352
24340
  ctx.imageSmoothingEnabled = this.imageSmoothing;
24353
- // cant use ts-expect-error because of ts 5.3 cross check
24354
- // @ts-ignore TS doesn't respect this type casting
24355
24341
  super.drawCacheOnCanvas(ctx);
24356
24342
  }
24357
24343
 
@@ -24741,65 +24727,82 @@ function getMultipleNodes(doc, nodeNames) {
24741
24727
 
24742
24728
  function parseUseDirectives(doc) {
24743
24729
  const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);
24744
- let i = 0;
24745
- while (nodelist.length && i < nodelist.length) {
24746
- const el = nodelist[i],
24747
- xlinkAttribute = el.getAttribute('xlink:href') || el.getAttribute('href');
24748
- if (xlinkAttribute === null) {
24730
+ const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];
24731
+ for (const useElement of nodelist) {
24732
+ const useAttributes = useElement.attributes;
24733
+ const useAttrMap = {};
24734
+ for (const attr of useAttributes) {
24735
+ attr.value && (useAttrMap[attr.name] = attr.value);
24736
+ }
24737
+ const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);
24738
+ if (xlink === '') {
24749
24739
  return;
24750
24740
  }
24751
- const xlink = xlinkAttribute.slice(1);
24752
- const x = el.getAttribute('x') || 0;
24753
- const y = el.getAttribute('y') || 0;
24754
- const el2Orig = doc.getElementById(xlink);
24755
- if (el2Orig === null) {
24741
+ const referencedElement = doc.getElementById(xlink);
24742
+ if (referencedElement === null) {
24756
24743
  // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink
24757
24744
  return;
24758
24745
  }
24759
- let el2 = el2Orig.cloneNode(true);
24760
- let currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')';
24761
- const oldLength = nodelist.length;
24762
- const namespace = svgNS;
24763
- applyViewboxTransform(el2);
24764
- if (/^svg$/i.test(el2.nodeName)) {
24765
- const el3 = el2.ownerDocument.createElementNS(namespace, 'g');
24766
- for (let j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {
24767
- const attr = attrs.item(j);
24768
- attr && el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);
24769
- }
24770
- // el2.firstChild != null
24771
- while (el2.firstChild) {
24772
- el3.appendChild(el2.firstChild);
24773
- }
24774
- el2 = el3;
24746
+ let clonedOriginal = referencedElement.cloneNode(true);
24747
+ const originalAttributes = clonedOriginal.attributes;
24748
+ const originalAttrMap = {};
24749
+ for (const attr of originalAttributes) {
24750
+ attr.value && (originalAttrMap[attr.name] = attr.value);
24775
24751
  }
24776
- for (let j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {
24777
- const attr = attrs.item(j);
24752
+
24753
+ // Transform attribute needs to be merged in a particular way
24754
+ const {
24755
+ x = 0,
24756
+ y = 0,
24757
+ transform = ''
24758
+ } = useAttrMap;
24759
+ const currentTrans = "".concat(transform, " ").concat(originalAttrMap.transform || '', " translate(").concat(x, ", ").concat(y, ")");
24760
+ applyViewboxTransform(clonedOriginal);
24761
+ if (/^svg$/i.test(clonedOriginal.nodeName)) {
24762
+ // if is an SVG, create a group and apply all the attributes on top of it
24763
+ const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');
24764
+ Object.entries(originalAttrMap).forEach(_ref => {
24765
+ let [name, value] = _ref;
24766
+ return el3.setAttributeNS(svgNS, name, value);
24767
+ });
24768
+ el3.append(...clonedOriginal.childNodes);
24769
+ clonedOriginal = el3;
24770
+ }
24771
+ for (const attr of useAttributes) {
24778
24772
  if (!attr) {
24779
24773
  continue;
24780
24774
  }
24781
24775
  const {
24782
- nodeName,
24783
- nodeValue
24776
+ name,
24777
+ value
24784
24778
  } = attr;
24785
- if (nodeName === 'x' || nodeName === 'y' || nodeName === 'xlink:href' || nodeName === 'href') {
24779
+ if (skipAttributes.includes(name)) {
24786
24780
  continue;
24787
24781
  }
24788
- if (nodeName === 'transform') {
24789
- currentTrans = nodeValue + ' ' + currentTrans;
24782
+ if (name === 'style') {
24783
+ // when use has a style, merge the two styles, with the ref being priority (not use)
24784
+ // priority is by feature. an attribute for fill on the original element
24785
+ // will overwrite the fill in style or attribute for tha use
24786
+ const styleRecord = {};
24787
+ parseStyleString(value, styleRecord);
24788
+ // cleanup styleRecord from attributes of original
24789
+ Object.entries(originalAttrMap).forEach(_ref2 => {
24790
+ let [name, value] = _ref2;
24791
+ styleRecord[name] = value;
24792
+ });
24793
+ // now we can put in the style of the original that will overwrite the original attributes
24794
+ parseStyleString(originalAttrMap.style || '', styleRecord);
24795
+ const mergedStyles = Object.entries(styleRecord).map(entry => entry.join(':')).join(';');
24796
+ clonedOriginal.setAttribute(name, mergedStyles);
24790
24797
  } else {
24791
- el2.setAttribute(nodeName, nodeValue);
24798
+ // set the attribute from use element only if the original does not have it already
24799
+ !originalAttrMap[name] && clonedOriginal.setAttribute(name, value);
24792
24800
  }
24793
24801
  }
24794
- el2.setAttribute('transform', currentTrans);
24795
- el2.setAttribute('instantiated_by_use', '1');
24796
- el2.removeAttribute('id');
24797
- const parentNode = el.parentNode;
24798
- parentNode.replaceChild(el2, el);
24799
- // some browsers do not shorten nodelist after replaceChild (IE8)
24800
- if (nodelist.length === oldLength) {
24801
- i++;
24802
- }
24802
+ clonedOriginal.setAttribute('transform', currentTrans);
24803
+ clonedOriginal.setAttribute('instantiated_by_use', '1');
24804
+ clonedOriginal.removeAttribute('id');
24805
+ useElement.parentNode.replaceChild(clonedOriginal, useElement);
24803
24806
  }
24804
24807
  }
24805
24808
 
@@ -25156,7 +25159,7 @@ function loadSVGFromURL(url, reviver) {
25156
25159
  });
25157
25160
  }
25158
25161
 
25159
- const ACTION_NAME = MODIFY_POLY;
25162
+ const ACTION_NAME$1 = MODIFY_POLY;
25160
25163
  /**
25161
25164
  * This function locates the controls.
25162
25165
  * It'll be used both for drawing and for interaction.
@@ -25208,13 +25211,13 @@ const factoryPolyActionHandler = (pointIndex, fn) => {
25208
25211
  return actionPerformed;
25209
25212
  };
25210
25213
  };
25211
- const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME, factoryPolyActionHandler(pointIndex, polyActionHandler));
25214
+ const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME$1, factoryPolyActionHandler(pointIndex, polyActionHandler));
25212
25215
  function createPolyControls(arg0) {
25213
25216
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25214
25217
  const controls = {};
25215
25218
  for (let idx = 0; idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length); idx++) {
25216
25219
  controls["p".concat(idx)] = new Control(_objectSpread2({
25217
- actionName: ACTION_NAME,
25220
+ actionName: ACTION_NAME$1,
25218
25221
  positionHandler: createPolyPositionHandler(idx),
25219
25222
  actionHandler: createPolyActionHandler(idx)
25220
25223
  }, options));
@@ -25222,10 +25225,157 @@ function createPolyControls(arg0) {
25222
25225
  return controls;
25223
25226
  }
25224
25227
 
25228
+ const ACTION_NAME = 'modifyPath';
25229
+ const calcPathPointPosition = (pathObject, commandIndex, pointIndex) => {
25230
+ const {
25231
+ path,
25232
+ pathOffset
25233
+ } = pathObject;
25234
+ const command = path[commandIndex];
25235
+ return new Point(command[pointIndex] - pathOffset.x, command[pointIndex + 1] - pathOffset.y).transform(multiplyTransformMatrices(pathObject.getViewportTransform(), pathObject.calcTransformMatrix()));
25236
+ };
25237
+ const movePathPoint = (pathObject, x, y, commandIndex, pointIndex) => {
25238
+ const {
25239
+ path,
25240
+ pathOffset
25241
+ } = pathObject;
25242
+ const anchorCommand = path[(commandIndex > 0 ? commandIndex : path.length) - 1];
25243
+ const anchorPoint = new Point(anchorCommand[pointIndex], anchorCommand[pointIndex + 1]);
25244
+ const anchorPointInParentPlane = anchorPoint.subtract(pathOffset).transform(pathObject.calcOwnMatrix());
25245
+ const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, pathObject.calcOwnMatrix());
25246
+ path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;
25247
+ path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;
25248
+ pathObject.setDimensions();
25249
+ const newAnchorPointInParentPlane = anchorPoint.subtract(pathObject.pathOffset).transform(pathObject.calcOwnMatrix());
25250
+ const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);
25251
+ pathObject.left -= diff.x;
25252
+ pathObject.top -= diff.y;
25253
+ pathObject.set('dirty', true);
25254
+ return true;
25255
+ };
25256
+
25257
+ /**
25258
+ * This function locates the controls.
25259
+ * It'll be used both for drawing and for interaction.
25260
+ */
25261
+ function pathPositionHandler(dim, finalMatrix, pathObject) {
25262
+ const {
25263
+ commandIndex,
25264
+ pointIndex
25265
+ } = this;
25266
+ return calcPathPointPosition(pathObject, commandIndex, pointIndex);
25267
+ }
25268
+
25269
+ /**
25270
+ * This function defines what the control does.
25271
+ * It'll be called on every mouse move after a control has been clicked and is being dragged.
25272
+ * The function receives as argument the mouse event, the current transform object
25273
+ * and the current position in canvas coordinate `transform.target` is a reference to the
25274
+ * current object being transformed.
25275
+ */
25276
+ function pathActionHandler(eventData, transform, x, y) {
25277
+ const {
25278
+ target
25279
+ } = transform;
25280
+ const {
25281
+ commandIndex,
25282
+ pointIndex
25283
+ } = this;
25284
+ const actionPerformed = movePathPoint(target, x, y, commandIndex, pointIndex);
25285
+ {
25286
+ fireEvent(this.actionName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), {}, {
25287
+ commandIndex,
25288
+ pointIndex
25289
+ }));
25290
+ }
25291
+ return actionPerformed;
25292
+ }
25293
+ const indexFromPrevCommand = previousCommandType => previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;
25294
+ class PathPointControl extends Control {
25295
+ constructor(options) {
25296
+ super(options);
25297
+ }
25298
+ render(ctx, left, top, styleOverride, fabricObject) {
25299
+ const overrides = _objectSpread2(_objectSpread2({}, styleOverride), {}, {
25300
+ cornerColor: this.controlFill,
25301
+ cornerStrokeColor: this.controlStroke,
25302
+ transparentCorners: !this.controlFill
25303
+ });
25304
+ super.render(ctx, left, top, overrides, fabricObject);
25305
+ }
25306
+ }
25307
+ class PathControlPointControl extends PathPointControl {
25308
+ constructor(options) {
25309
+ super(options);
25310
+ }
25311
+ render(ctx, left, top, styleOverride, fabricObject) {
25312
+ const {
25313
+ path
25314
+ } = fabricObject;
25315
+ const {
25316
+ commandIndex,
25317
+ pointIndex,
25318
+ connectToCommandIndex,
25319
+ connectToPointIndex
25320
+ } = this;
25321
+ ctx.save();
25322
+ ctx.strokeStyle = this.controlStroke;
25323
+ if (this.connectionDashArray) {
25324
+ ctx.setLineDash(this.connectionDashArray);
25325
+ }
25326
+ const [commandType] = path[commandIndex];
25327
+ const point = calcPathPointPosition(fabricObject, connectToCommandIndex, connectToPointIndex);
25328
+ if (commandType === 'Q') {
25329
+ // one control point connects to 2 points
25330
+ const point2 = calcPathPointPosition(fabricObject, commandIndex, pointIndex + 2);
25331
+ ctx.moveTo(point2.x, point2.y);
25332
+ ctx.lineTo(left, top);
25333
+ } else {
25334
+ ctx.moveTo(left, top);
25335
+ }
25336
+ ctx.lineTo(point.x, point.y);
25337
+ ctx.stroke();
25338
+ ctx.restore();
25339
+ super.render(ctx, left, top, styleOverride, fabricObject);
25340
+ }
25341
+ }
25342
+ const createControl = (commandIndexPos, pointIndexPos, isControlPoint, options, connectToCommandIndex, connectToPointIndex) => new (isControlPoint ? PathControlPointControl : PathPointControl)(_objectSpread2(_objectSpread2({
25343
+ commandIndex: commandIndexPos,
25344
+ pointIndex: pointIndexPos,
25345
+ actionName: ACTION_NAME,
25346
+ positionHandler: pathPositionHandler,
25347
+ actionHandler: pathActionHandler,
25348
+ connectToCommandIndex,
25349
+ connectToPointIndex
25350
+ }, options), isControlPoint ? options.controlPointStyle : options.pointStyle));
25351
+ function createPathControls(path) {
25352
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25353
+ const controls = {};
25354
+ let previousCommandType = 'M';
25355
+ path.path.forEach((command, commandIndex) => {
25356
+ const commandType = command[0];
25357
+ if (commandType !== 'Z') {
25358
+ controls["c_".concat(commandIndex, "_").concat(commandType)] = createControl(commandIndex, command.length - 2, false, options);
25359
+ }
25360
+ switch (commandType) {
25361
+ case 'C':
25362
+ controls["c_".concat(commandIndex, "_C_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex - 1, indexFromPrevCommand(previousCommandType));
25363
+ controls["c_".concat(commandIndex, "_C_CP_2")] = createControl(commandIndex, 3, true, options, commandIndex, 5);
25364
+ break;
25365
+ case 'Q':
25366
+ controls["c_".concat(commandIndex, "_Q_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex, 3);
25367
+ break;
25368
+ }
25369
+ previousCommandType = commandType;
25370
+ });
25371
+ return controls;
25372
+ }
25373
+
25225
25374
  var index = /*#__PURE__*/Object.freeze({
25226
25375
  __proto__: null,
25227
25376
  changeWidth: changeWidth,
25228
25377
  createObjectDefaultControls: createObjectDefaultControls,
25378
+ createPathControls: createPathControls,
25229
25379
  createPolyActionHandler: createPolyActionHandler,
25230
25380
  createPolyControls: createPolyControls,
25231
25381
  createPolyPositionHandler: createPolyPositionHandler,
@@ -25584,7 +25734,6 @@ class BaseFilter {
25584
25734
  return _objectSpread2({
25585
25735
  type: this.type
25586
25736
  }, defaultKeys.reduce((acc, key) => {
25587
- //@ts-expect-error TS doesn't get i want an object that looks like this
25588
25737
  acc[key] = this[key];
25589
25738
  return acc;
25590
25739
  }, {}));