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/CHANGELOG.md CHANGED
@@ -2,6 +2,21 @@
2
2
 
3
3
  ## [next]
4
4
 
5
+ ## [6.2.0]
6
+
7
+ - fix(): Parse use directive attribute issues [#10053](https://github.com/fabricjs/fabric.js/pull/10053)
8
+ - fix(parseUseDirectives): Fix style tag processing in use tag when reference also has a style [#10050](https://github.com/fabricjs/fabric.js/pull/10050)
9
+ - fix(): Fix path Arc parsing regression issue [#10048](https://github.com/fabricjs/fabric.js/pull/10048)
10
+ - chore(TS): Update TS to latest [#10044](https://github.com/fabricjs/fabric.js/pull/10044)
11
+ - feat(): Add has method to classRegistry to allow to check if a class exists. (fixes #10001)
12
+
13
+ ## [6.1.0]
14
+
15
+ - fix(): Avoid errors on restoring custom properties that pass the lazy detection of shadow,gradient,pattern and clipPath. [#10001](https://github.com/fabricjs/fabric.js/issues/10001)
16
+ - fix(): When deselecting an active selection remove its reference from hoveredTarget [#9961](https://github.com/fabricjs/fabric.js/pull/9961)
17
+ - feat(): Path controls utility [#9998](https://github.com/fabricjs/fabric.js/pull/9998)
18
+ - chore(): Removed website submodule
19
+
5
20
  ## [6.0.2]
6
21
 
7
22
  - fix(TS): Type fixes and improved JSDOCS. [#9978](https://github.com/fabricjs/fabric.js/pull/9978)
package/dist/index.js CHANGED
@@ -407,7 +407,7 @@
407
407
  }
408
408
  const cache = new Cache();
409
409
 
410
- var version = "6.0.2";
410
+ var version = "6.2.0";
411
411
 
412
412
  // use this syntax so babel plugin see this import here
413
413
  const VERSION = version;
@@ -436,6 +436,7 @@
436
436
  const SKEWING = 'skewing';
437
437
  const RESIZING = 'resizing';
438
438
  const MODIFY_POLY = 'modifyPoly';
439
+ const MODIFY_PATH = 'modifyPath';
439
440
  const CHANGED = 'changed';
440
441
  const SCALE = 'scale';
441
442
  const SCALE_X = 'scaleX';
@@ -465,6 +466,9 @@
465
466
  this[JSON$1] = new Map();
466
467
  this[SVG] = new Map();
467
468
  }
469
+ has(classType) {
470
+ return this[JSON$1].has(classType);
471
+ }
468
472
  getClass(classType) {
469
473
  const constructor = this[JSON$1].get(classType);
470
474
  if (!constructor) {
@@ -1959,8 +1963,13 @@
1959
1963
  if (!value) {
1960
1964
  return value;
1961
1965
  }
1962
- // clipPath or shadow or gradient
1963
- if (value.type) {
1966
+ /**
1967
+ * clipPath or shadow or gradient or text on a path or a pattern,
1968
+ * or the backgroundImage or overlayImage of canvas
1969
+ * If we have a type and there is a classe registered for it, we enlive it.
1970
+ * If there is no class registered for it we return the value as is
1971
+ * */
1972
+ if (value.type && classRegistry.has(value.type)) {
1964
1973
  return enlivenObjects([value], {
1965
1974
  signal
1966
1975
  }).then(_ref => {
@@ -1969,15 +1978,6 @@
1969
1978
  return enlived;
1970
1979
  });
1971
1980
  }
1972
- // pattern
1973
- if (value.source) {
1974
- return classRegistry.getClass('pattern').fromObject(value, {
1975
- signal
1976
- }).then(pattern => {
1977
- instances.push(pattern);
1978
- return pattern;
1979
- });
1980
- }
1981
1981
  return value;
1982
1982
  });
1983
1983
  const keys = Object.keys(serializedObject);
@@ -2851,6 +2851,7 @@
2851
2851
  top
2852
2852
  };
2853
2853
  }
2854
+ let elementLoop = element;
2854
2855
  const docElement = doc.documentElement,
2855
2856
  body = doc.body || {
2856
2857
  scrollLeft: 0,
@@ -2860,19 +2861,16 @@
2860
2861
  // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,
2861
2862
  // but the .parentNode of a root ShadowDOM node will always be null, instead
2862
2863
  // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938
2863
- // @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
2864
- while (element && (element.parentNode || element.host)) {
2865
- // @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
2866
- element = element.parentNode || element.host;
2867
- // @ts-expect-error because element is typed as HTMLElement but it can go up to document
2868
- if (element === doc) {
2864
+ while (elementLoop && (elementLoop.parentNode || elementLoop.host)) {
2865
+ elementLoop = elementLoop.parentNode || elementLoop.host;
2866
+ if (elementLoop === doc) {
2869
2867
  left = body.scrollLeft || docElement.scrollLeft || 0;
2870
2868
  top = body.scrollTop || docElement.scrollTop || 0;
2871
2869
  } else {
2872
- left += element.scrollLeft || 0;
2873
- top += element.scrollTop || 0;
2870
+ left += elementLoop.scrollLeft || 0;
2871
+ top += elementLoop.scrollTop || 0;
2874
2872
  }
2875
- if (element.nodeType === 1 && element.style.position === 'fixed') {
2873
+ if (elementLoop.nodeType === 1 && elementLoop.style.position === 'fixed') {
2876
2874
  break;
2877
2875
  }
2878
2876
  }
@@ -2945,29 +2943,23 @@
2945
2943
  */
2946
2944
  function getElementOffset(element) {
2947
2945
  var _getWindowFromElement;
2948
- let box = {
2949
- left: 0,
2950
- top: 0
2951
- };
2952
2946
  const doc = element && getDocumentFromElement(element),
2953
2947
  offset = {
2954
2948
  left: 0,
2955
2949
  top: 0
2956
- },
2957
- offsetAttributes = {
2958
- borderLeftWidth: LEFT,
2959
- borderTopWidth: TOP,
2960
- paddingLeft: LEFT,
2961
- paddingTop: TOP
2962
2950
  };
2963
2951
  if (!doc) {
2964
2952
  return offset;
2965
2953
  }
2966
2954
  const elemStyle = ((_getWindowFromElement = getWindowFromElement(element)) === null || _getWindowFromElement === void 0 ? void 0 : _getWindowFromElement.getComputedStyle(element, null)) || {};
2967
- for (const attr in offsetAttributes) {
2968
- // @ts-expect-error TS learn to iterate!
2969
- offset[offsetAttributes[attr]] += parseInt(elemStyle[attr], 10) || 0;
2970
- }
2955
+ offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0;
2956
+ offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0;
2957
+ offset.left += parseInt(elemStyle.paddingLeft, 10) || 0;
2958
+ offset.top += parseInt(elemStyle.paddingTop, 10) || 0;
2959
+ let box = {
2960
+ left: 0,
2961
+ top: 0
2962
+ };
2971
2963
  const docElem = doc.documentElement;
2972
2964
  if (typeof element.getBoundingClientRect !== 'undefined') {
2973
2965
  box = element.getBoundingClientRect();
@@ -6743,11 +6735,7 @@
6743
6735
 
6744
6736
  constructor(arg0) {
6745
6737
  const options = typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;
6746
- Object.assign(this, Shadow.ownDefaults);
6747
- for (const prop in options) {
6748
- // @ts-expect-error for loops are so messy in TS
6749
- this[prop] = options[prop];
6750
- }
6738
+ Object.assign(this, Shadow.ownDefaults, options);
6751
6739
  this.id = uid();
6752
6740
  }
6753
6741
 
@@ -8196,14 +8184,16 @@
8196
8184
 
8197
8185
  /**
8198
8186
  * Wrap an action handler with firing an event if the action is performed
8199
- * @param {Function} actionHandler the function to wrap
8200
- * @return {Function} a function with an action handler signature
8187
+ * @param {TModificationEvents} eventName the event we want to fire
8188
+ * @param {TransformActionHandler<T>} actionHandler the function to wrap
8189
+ * @param {object} extraEventInfo extra information to pas to the event handler
8190
+ * @return {TransformActionHandler<T>} a function with an action handler signature
8201
8191
  */
8202
- const wrapWithFireEvent = (eventName, actionHandler) => {
8192
+ const wrapWithFireEvent = (eventName, actionHandler, extraEventInfo) => {
8203
8193
  return (eventData, transform, x, y) => {
8204
8194
  const actionPerformed = actionHandler(eventData, transform, x, y);
8205
8195
  if (actionPerformed) {
8206
- fireEvent(eventName, commonEventInfo(eventData, transform, x, y));
8196
+ fireEvent(eventName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), extraEventInfo));
8207
8197
  }
8208
8198
  return actionPerformed;
8209
8199
  };
@@ -10675,6 +10665,7 @@
10675
10665
  */
10676
10666
  function parseStyleString(style, oStyle) {
10677
10667
  style.replace(/;\s*$/, '').split(';').forEach(chunk => {
10668
+ if (!chunk) return;
10678
10669
  const [attr, value] = chunk.split(':');
10679
10670
  oStyle[attr.trim().toLowerCase()] = value.trim();
10680
10671
  });
@@ -11104,7 +11095,7 @@
11104
11095
  const {
11105
11096
  target
11106
11097
  } = context;
11107
- return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? {
11098
+ return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY, MODIFY_PATH].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? {
11108
11099
  type: LAYOUT_TYPE_OBJECT_MODIFIED,
11109
11100
  trigger: key,
11110
11101
  e,
@@ -12041,7 +12032,7 @@
12041
12032
 
12042
12033
  // Convert into cubic bezier segments <= 90deg
12043
12034
  const segments = Math.ceil(Math.abs(dtheta / PI * 2)),
12044
- result = new Array(segments),
12035
+ result = [],
12045
12036
  mDelta = dtheta / segments,
12046
12037
  mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2);
12047
12038
  let th3 = mTheta + mDelta;
@@ -12592,7 +12583,6 @@
12592
12583
  * ['Q', 3, 5, 2, 1, 4, 0],
12593
12584
  * ['Q', 9, 12, 2, 1, 4, 0],
12594
12585
  * ];
12595
- *
12596
12586
  */
12597
12587
  const parsePath = pathString => {
12598
12588
  // clean the string
@@ -14052,6 +14042,9 @@
14052
14042
  if (this._currentTransform && this._currentTransform.target === obj) {
14053
14043
  this.endCurrentTransform(e);
14054
14044
  }
14045
+ if (isActiveSelection(obj) && obj === this._hoveredTarget) {
14046
+ this._hoveredTarget = undefined;
14047
+ }
14055
14048
  this._activeObject = undefined;
14056
14049
  return true;
14057
14050
  }
@@ -18713,8 +18706,6 @@
18713
18706
  * @return {String}
18714
18707
  */
18715
18708
  getSvgStyles(skipShadow) {
18716
- // cant use ts-expect-error because of ts 5.3 cross check
18717
- // @ts-ignore TS doesn't respect this type casting
18718
18709
  return "".concat(super.getSvgStyles(skipShadow), " white-space: pre;");
18719
18710
  }
18720
18711
 
@@ -20667,7 +20658,6 @@
20667
20658
  } : undefined);
20668
20659
  this._fireSelectionChanged();
20669
20660
  if (this.canvas) {
20670
- // @ts-expect-error in reality it is an IText instance
20671
20661
  this.canvas.fire('text:editing:entered', {
20672
20662
  target: this,
20673
20663
  e
@@ -23163,8 +23153,6 @@
23163
23153
  * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
23164
23154
  * @return {Object} object representation of an instance
23165
23155
  */
23166
- // cant use ts-expect-error because of ts 5.3 cross check
23167
- // @ts-ignore TS this typing limitations
23168
23156
  toObject() {
23169
23157
  let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
23170
23158
  return super.toObject(['minWidth', 'splitByGrapheme', ...propertiesToInclude]);
@@ -24356,8 +24344,6 @@
24356
24344
  */
24357
24345
  drawCacheOnCanvas(ctx) {
24358
24346
  ctx.imageSmoothingEnabled = this.imageSmoothing;
24359
- // cant use ts-expect-error because of ts 5.3 cross check
24360
- // @ts-ignore TS doesn't respect this type casting
24361
24347
  super.drawCacheOnCanvas(ctx);
24362
24348
  }
24363
24349
 
@@ -24747,65 +24733,82 @@
24747
24733
 
24748
24734
  function parseUseDirectives(doc) {
24749
24735
  const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);
24750
- let i = 0;
24751
- while (nodelist.length && i < nodelist.length) {
24752
- const el = nodelist[i],
24753
- xlinkAttribute = el.getAttribute('xlink:href') || el.getAttribute('href');
24754
- if (xlinkAttribute === null) {
24736
+ const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];
24737
+ for (const useElement of nodelist) {
24738
+ const useAttributes = useElement.attributes;
24739
+ const useAttrMap = {};
24740
+ for (const attr of useAttributes) {
24741
+ attr.value && (useAttrMap[attr.name] = attr.value);
24742
+ }
24743
+ const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);
24744
+ if (xlink === '') {
24755
24745
  return;
24756
24746
  }
24757
- const xlink = xlinkAttribute.slice(1);
24758
- const x = el.getAttribute('x') || 0;
24759
- const y = el.getAttribute('y') || 0;
24760
- const el2Orig = doc.getElementById(xlink);
24761
- if (el2Orig === null) {
24747
+ const referencedElement = doc.getElementById(xlink);
24748
+ if (referencedElement === null) {
24762
24749
  // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink
24763
24750
  return;
24764
24751
  }
24765
- let el2 = el2Orig.cloneNode(true);
24766
- let currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')';
24767
- const oldLength = nodelist.length;
24768
- const namespace = svgNS;
24769
- applyViewboxTransform(el2);
24770
- if (/^svg$/i.test(el2.nodeName)) {
24771
- const el3 = el2.ownerDocument.createElementNS(namespace, 'g');
24772
- for (let j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {
24773
- const attr = attrs.item(j);
24774
- attr && el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);
24775
- }
24776
- // el2.firstChild != null
24777
- while (el2.firstChild) {
24778
- el3.appendChild(el2.firstChild);
24779
- }
24780
- el2 = el3;
24752
+ let clonedOriginal = referencedElement.cloneNode(true);
24753
+ const originalAttributes = clonedOriginal.attributes;
24754
+ const originalAttrMap = {};
24755
+ for (const attr of originalAttributes) {
24756
+ attr.value && (originalAttrMap[attr.name] = attr.value);
24781
24757
  }
24782
- for (let j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {
24783
- const attr = attrs.item(j);
24758
+
24759
+ // Transform attribute needs to be merged in a particular way
24760
+ const {
24761
+ x = 0,
24762
+ y = 0,
24763
+ transform = ''
24764
+ } = useAttrMap;
24765
+ const currentTrans = "".concat(transform, " ").concat(originalAttrMap.transform || '', " translate(").concat(x, ", ").concat(y, ")");
24766
+ applyViewboxTransform(clonedOriginal);
24767
+ if (/^svg$/i.test(clonedOriginal.nodeName)) {
24768
+ // if is an SVG, create a group and apply all the attributes on top of it
24769
+ const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');
24770
+ Object.entries(originalAttrMap).forEach(_ref => {
24771
+ let [name, value] = _ref;
24772
+ return el3.setAttributeNS(svgNS, name, value);
24773
+ });
24774
+ el3.append(...clonedOriginal.childNodes);
24775
+ clonedOriginal = el3;
24776
+ }
24777
+ for (const attr of useAttributes) {
24784
24778
  if (!attr) {
24785
24779
  continue;
24786
24780
  }
24787
24781
  const {
24788
- nodeName,
24789
- nodeValue
24782
+ name,
24783
+ value
24790
24784
  } = attr;
24791
- if (nodeName === 'x' || nodeName === 'y' || nodeName === 'xlink:href' || nodeName === 'href') {
24785
+ if (skipAttributes.includes(name)) {
24792
24786
  continue;
24793
24787
  }
24794
- if (nodeName === 'transform') {
24795
- currentTrans = nodeValue + ' ' + currentTrans;
24788
+ if (name === 'style') {
24789
+ // when use has a style, merge the two styles, with the ref being priority (not use)
24790
+ // priority is by feature. an attribute for fill on the original element
24791
+ // will overwrite the fill in style or attribute for tha use
24792
+ const styleRecord = {};
24793
+ parseStyleString(value, styleRecord);
24794
+ // cleanup styleRecord from attributes of original
24795
+ Object.entries(originalAttrMap).forEach(_ref2 => {
24796
+ let [name, value] = _ref2;
24797
+ styleRecord[name] = value;
24798
+ });
24799
+ // now we can put in the style of the original that will overwrite the original attributes
24800
+ parseStyleString(originalAttrMap.style || '', styleRecord);
24801
+ const mergedStyles = Object.entries(styleRecord).map(entry => entry.join(':')).join(';');
24802
+ clonedOriginal.setAttribute(name, mergedStyles);
24796
24803
  } else {
24797
- el2.setAttribute(nodeName, nodeValue);
24804
+ // set the attribute from use element only if the original does not have it already
24805
+ !originalAttrMap[name] && clonedOriginal.setAttribute(name, value);
24798
24806
  }
24799
24807
  }
24800
- el2.setAttribute('transform', currentTrans);
24801
- el2.setAttribute('instantiated_by_use', '1');
24802
- el2.removeAttribute('id');
24803
- const parentNode = el.parentNode;
24804
- parentNode.replaceChild(el2, el);
24805
- // some browsers do not shorten nodelist after replaceChild (IE8)
24806
- if (nodelist.length === oldLength) {
24807
- i++;
24808
- }
24808
+ clonedOriginal.setAttribute('transform', currentTrans);
24809
+ clonedOriginal.setAttribute('instantiated_by_use', '1');
24810
+ clonedOriginal.removeAttribute('id');
24811
+ useElement.parentNode.replaceChild(clonedOriginal, useElement);
24809
24812
  }
24810
24813
  }
24811
24814
 
@@ -25162,7 +25165,7 @@
25162
25165
  });
25163
25166
  }
25164
25167
 
25165
- const ACTION_NAME = MODIFY_POLY;
25168
+ const ACTION_NAME$1 = MODIFY_POLY;
25166
25169
  /**
25167
25170
  * This function locates the controls.
25168
25171
  * It'll be used both for drawing and for interaction.
@@ -25214,13 +25217,13 @@
25214
25217
  return actionPerformed;
25215
25218
  };
25216
25219
  };
25217
- const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME, factoryPolyActionHandler(pointIndex, polyActionHandler));
25220
+ const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME$1, factoryPolyActionHandler(pointIndex, polyActionHandler));
25218
25221
  function createPolyControls(arg0) {
25219
25222
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25220
25223
  const controls = {};
25221
25224
  for (let idx = 0; idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length); idx++) {
25222
25225
  controls["p".concat(idx)] = new Control(_objectSpread2({
25223
- actionName: ACTION_NAME,
25226
+ actionName: ACTION_NAME$1,
25224
25227
  positionHandler: createPolyPositionHandler(idx),
25225
25228
  actionHandler: createPolyActionHandler(idx)
25226
25229
  }, options));
@@ -25228,10 +25231,157 @@
25228
25231
  return controls;
25229
25232
  }
25230
25233
 
25234
+ const ACTION_NAME = 'modifyPath';
25235
+ const calcPathPointPosition = (pathObject, commandIndex, pointIndex) => {
25236
+ const {
25237
+ path,
25238
+ pathOffset
25239
+ } = pathObject;
25240
+ const command = path[commandIndex];
25241
+ return new Point(command[pointIndex] - pathOffset.x, command[pointIndex + 1] - pathOffset.y).transform(multiplyTransformMatrices(pathObject.getViewportTransform(), pathObject.calcTransformMatrix()));
25242
+ };
25243
+ const movePathPoint = (pathObject, x, y, commandIndex, pointIndex) => {
25244
+ const {
25245
+ path,
25246
+ pathOffset
25247
+ } = pathObject;
25248
+ const anchorCommand = path[(commandIndex > 0 ? commandIndex : path.length) - 1];
25249
+ const anchorPoint = new Point(anchorCommand[pointIndex], anchorCommand[pointIndex + 1]);
25250
+ const anchorPointInParentPlane = anchorPoint.subtract(pathOffset).transform(pathObject.calcOwnMatrix());
25251
+ const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, pathObject.calcOwnMatrix());
25252
+ path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;
25253
+ path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;
25254
+ pathObject.setDimensions();
25255
+ const newAnchorPointInParentPlane = anchorPoint.subtract(pathObject.pathOffset).transform(pathObject.calcOwnMatrix());
25256
+ const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);
25257
+ pathObject.left -= diff.x;
25258
+ pathObject.top -= diff.y;
25259
+ pathObject.set('dirty', true);
25260
+ return true;
25261
+ };
25262
+
25263
+ /**
25264
+ * This function locates the controls.
25265
+ * It'll be used both for drawing and for interaction.
25266
+ */
25267
+ function pathPositionHandler(dim, finalMatrix, pathObject) {
25268
+ const {
25269
+ commandIndex,
25270
+ pointIndex
25271
+ } = this;
25272
+ return calcPathPointPosition(pathObject, commandIndex, pointIndex);
25273
+ }
25274
+
25275
+ /**
25276
+ * This function defines what the control does.
25277
+ * It'll be called on every mouse move after a control has been clicked and is being dragged.
25278
+ * The function receives as argument the mouse event, the current transform object
25279
+ * and the current position in canvas coordinate `transform.target` is a reference to the
25280
+ * current object being transformed.
25281
+ */
25282
+ function pathActionHandler(eventData, transform, x, y) {
25283
+ const {
25284
+ target
25285
+ } = transform;
25286
+ const {
25287
+ commandIndex,
25288
+ pointIndex
25289
+ } = this;
25290
+ const actionPerformed = movePathPoint(target, x, y, commandIndex, pointIndex);
25291
+ {
25292
+ fireEvent(this.actionName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), {}, {
25293
+ commandIndex,
25294
+ pointIndex
25295
+ }));
25296
+ }
25297
+ return actionPerformed;
25298
+ }
25299
+ const indexFromPrevCommand = previousCommandType => previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;
25300
+ class PathPointControl extends Control {
25301
+ constructor(options) {
25302
+ super(options);
25303
+ }
25304
+ render(ctx, left, top, styleOverride, fabricObject) {
25305
+ const overrides = _objectSpread2(_objectSpread2({}, styleOverride), {}, {
25306
+ cornerColor: this.controlFill,
25307
+ cornerStrokeColor: this.controlStroke,
25308
+ transparentCorners: !this.controlFill
25309
+ });
25310
+ super.render(ctx, left, top, overrides, fabricObject);
25311
+ }
25312
+ }
25313
+ class PathControlPointControl extends PathPointControl {
25314
+ constructor(options) {
25315
+ super(options);
25316
+ }
25317
+ render(ctx, left, top, styleOverride, fabricObject) {
25318
+ const {
25319
+ path
25320
+ } = fabricObject;
25321
+ const {
25322
+ commandIndex,
25323
+ pointIndex,
25324
+ connectToCommandIndex,
25325
+ connectToPointIndex
25326
+ } = this;
25327
+ ctx.save();
25328
+ ctx.strokeStyle = this.controlStroke;
25329
+ if (this.connectionDashArray) {
25330
+ ctx.setLineDash(this.connectionDashArray);
25331
+ }
25332
+ const [commandType] = path[commandIndex];
25333
+ const point = calcPathPointPosition(fabricObject, connectToCommandIndex, connectToPointIndex);
25334
+ if (commandType === 'Q') {
25335
+ // one control point connects to 2 points
25336
+ const point2 = calcPathPointPosition(fabricObject, commandIndex, pointIndex + 2);
25337
+ ctx.moveTo(point2.x, point2.y);
25338
+ ctx.lineTo(left, top);
25339
+ } else {
25340
+ ctx.moveTo(left, top);
25341
+ }
25342
+ ctx.lineTo(point.x, point.y);
25343
+ ctx.stroke();
25344
+ ctx.restore();
25345
+ super.render(ctx, left, top, styleOverride, fabricObject);
25346
+ }
25347
+ }
25348
+ const createControl = (commandIndexPos, pointIndexPos, isControlPoint, options, connectToCommandIndex, connectToPointIndex) => new (isControlPoint ? PathControlPointControl : PathPointControl)(_objectSpread2(_objectSpread2({
25349
+ commandIndex: commandIndexPos,
25350
+ pointIndex: pointIndexPos,
25351
+ actionName: ACTION_NAME,
25352
+ positionHandler: pathPositionHandler,
25353
+ actionHandler: pathActionHandler,
25354
+ connectToCommandIndex,
25355
+ connectToPointIndex
25356
+ }, options), isControlPoint ? options.controlPointStyle : options.pointStyle));
25357
+ function createPathControls(path) {
25358
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25359
+ const controls = {};
25360
+ let previousCommandType = 'M';
25361
+ path.path.forEach((command, commandIndex) => {
25362
+ const commandType = command[0];
25363
+ if (commandType !== 'Z') {
25364
+ controls["c_".concat(commandIndex, "_").concat(commandType)] = createControl(commandIndex, command.length - 2, false, options);
25365
+ }
25366
+ switch (commandType) {
25367
+ case 'C':
25368
+ controls["c_".concat(commandIndex, "_C_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex - 1, indexFromPrevCommand(previousCommandType));
25369
+ controls["c_".concat(commandIndex, "_C_CP_2")] = createControl(commandIndex, 3, true, options, commandIndex, 5);
25370
+ break;
25371
+ case 'Q':
25372
+ controls["c_".concat(commandIndex, "_Q_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex, 3);
25373
+ break;
25374
+ }
25375
+ previousCommandType = commandType;
25376
+ });
25377
+ return controls;
25378
+ }
25379
+
25231
25380
  var index = /*#__PURE__*/Object.freeze({
25232
25381
  __proto__: null,
25233
25382
  changeWidth: changeWidth,
25234
25383
  createObjectDefaultControls: createObjectDefaultControls,
25384
+ createPathControls: createPathControls,
25235
25385
  createPolyActionHandler: createPolyActionHandler,
25236
25386
  createPolyControls: createPolyControls,
25237
25387
  createPolyPositionHandler: createPolyPositionHandler,
@@ -25590,7 +25740,6 @@
25590
25740
  return _objectSpread2({
25591
25741
  type: this.type
25592
25742
  }, defaultKeys.reduce((acc, key) => {
25593
- //@ts-expect-error TS doesn't get i want an object that looks like this
25594
25743
  acc[key] = this[key];
25595
25744
  return acc;
25596
25745
  }, {}));