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
@@ -459,7 +459,7 @@ class Cache {
459
459
  }
460
460
  const cache = new Cache();
461
461
 
462
- var version = "6.0.2";
462
+ var version = "6.2.0";
463
463
 
464
464
  // use this syntax so babel plugin see this import here
465
465
  const VERSION = version;
@@ -488,6 +488,7 @@ const ROTATE = 'rotate';
488
488
  const SKEWING = 'skewing';
489
489
  const RESIZING = 'resizing';
490
490
  const MODIFY_POLY = 'modifyPoly';
491
+ const MODIFY_PATH = 'modifyPath';
491
492
  const CHANGED = 'changed';
492
493
  const SCALE = 'scale';
493
494
  const SCALE_X = 'scaleX';
@@ -517,6 +518,9 @@ class ClassRegistry {
517
518
  this[JSON$1] = new Map();
518
519
  this[SVG] = new Map();
519
520
  }
521
+ has(classType) {
522
+ return this[JSON$1].has(classType);
523
+ }
520
524
  getClass(classType) {
521
525
  const constructor = this[JSON$1].get(classType);
522
526
  if (!constructor) {
@@ -2011,8 +2015,13 @@ const enlivenObjectEnlivables = function (serializedObject) {
2011
2015
  if (!value) {
2012
2016
  return value;
2013
2017
  }
2014
- // clipPath or shadow or gradient
2015
- if (value.type) {
2018
+ /**
2019
+ * clipPath or shadow or gradient or text on a path or a pattern,
2020
+ * or the backgroundImage or overlayImage of canvas
2021
+ * If we have a type and there is a classe registered for it, we enlive it.
2022
+ * If there is no class registered for it we return the value as is
2023
+ * */
2024
+ if (value.type && classRegistry.has(value.type)) {
2016
2025
  return enlivenObjects([value], {
2017
2026
  signal
2018
2027
  }).then(_ref => {
@@ -2021,15 +2030,6 @@ const enlivenObjectEnlivables = function (serializedObject) {
2021
2030
  return enlived;
2022
2031
  });
2023
2032
  }
2024
- // pattern
2025
- if (value.source) {
2026
- return classRegistry.getClass('pattern').fromObject(value, {
2027
- signal
2028
- }).then(pattern => {
2029
- instances.push(pattern);
2030
- return pattern;
2031
- });
2032
- }
2033
2033
  return value;
2034
2034
  });
2035
2035
  const keys = Object.keys(serializedObject);
@@ -2903,6 +2903,7 @@ function getScrollLeftTop(element) {
2903
2903
  top
2904
2904
  };
2905
2905
  }
2906
+ let elementLoop = element;
2906
2907
  const docElement = doc.documentElement,
2907
2908
  body = doc.body || {
2908
2909
  scrollLeft: 0,
@@ -2912,19 +2913,16 @@ function getScrollLeftTop(element) {
2912
2913
  // to account for ShadowDOM. We still want to traverse up out of ShadowDOM,
2913
2914
  // but the .parentNode of a root ShadowDOM node will always be null, instead
2914
2915
  // it should be accessed through .host. See http://stackoverflow.com/a/24765528/4383938
2915
- // @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
2916
- while (element && (element.parentNode || element.host)) {
2917
- // @ts-expect-error Set element to element parent, or 'host' in case of ShadowDOM
2918
- element = element.parentNode || element.host;
2919
- // @ts-expect-error because element is typed as HTMLElement but it can go up to document
2920
- if (element === doc) {
2916
+ while (elementLoop && (elementLoop.parentNode || elementLoop.host)) {
2917
+ elementLoop = elementLoop.parentNode || elementLoop.host;
2918
+ if (elementLoop === doc) {
2921
2919
  left = body.scrollLeft || docElement.scrollLeft || 0;
2922
2920
  top = body.scrollTop || docElement.scrollTop || 0;
2923
2921
  } else {
2924
- left += element.scrollLeft || 0;
2925
- top += element.scrollTop || 0;
2922
+ left += elementLoop.scrollLeft || 0;
2923
+ top += elementLoop.scrollTop || 0;
2926
2924
  }
2927
- if (element.nodeType === 1 && element.style.position === 'fixed') {
2925
+ if (elementLoop.nodeType === 1 && elementLoop.style.position === 'fixed') {
2928
2926
  break;
2929
2927
  }
2930
2928
  }
@@ -2997,29 +2995,23 @@ const setCSSDimensions = (el, _ref2) => {
2997
2995
  */
2998
2996
  function getElementOffset(element) {
2999
2997
  var _getWindowFromElement;
3000
- let box = {
3001
- left: 0,
3002
- top: 0
3003
- };
3004
2998
  const doc = element && getDocumentFromElement(element),
3005
2999
  offset = {
3006
3000
  left: 0,
3007
3001
  top: 0
3008
- },
3009
- offsetAttributes = {
3010
- borderLeftWidth: LEFT,
3011
- borderTopWidth: TOP,
3012
- paddingLeft: LEFT,
3013
- paddingTop: TOP
3014
3002
  };
3015
3003
  if (!doc) {
3016
3004
  return offset;
3017
3005
  }
3018
3006
  const elemStyle = ((_getWindowFromElement = getWindowFromElement(element)) === null || _getWindowFromElement === void 0 ? void 0 : _getWindowFromElement.getComputedStyle(element, null)) || {};
3019
- for (const attr in offsetAttributes) {
3020
- // @ts-expect-error TS learn to iterate!
3021
- offset[offsetAttributes[attr]] += parseInt(elemStyle[attr], 10) || 0;
3022
- }
3007
+ offset.left += parseInt(elemStyle.borderLeftWidth, 10) || 0;
3008
+ offset.top += parseInt(elemStyle.borderTopWidth, 10) || 0;
3009
+ offset.left += parseInt(elemStyle.paddingLeft, 10) || 0;
3010
+ offset.top += parseInt(elemStyle.paddingTop, 10) || 0;
3011
+ let box = {
3012
+ left: 0,
3013
+ top: 0
3014
+ };
3023
3015
  const docElem = doc.documentElement;
3024
3016
  if (typeof element.getBoundingClientRect !== 'undefined') {
3025
3017
  box = element.getBoundingClientRect();
@@ -6795,11 +6787,7 @@ class Shadow {
6795
6787
 
6796
6788
  constructor(arg0) {
6797
6789
  const options = typeof arg0 === 'string' ? Shadow.parseShadow(arg0) : arg0;
6798
- Object.assign(this, Shadow.ownDefaults);
6799
- for (const prop in options) {
6800
- // @ts-expect-error for loops are so messy in TS
6801
- this[prop] = options[prop];
6802
- }
6790
+ Object.assign(this, Shadow.ownDefaults, options);
6803
6791
  this.id = uid();
6804
6792
  }
6805
6793
 
@@ -8248,14 +8236,16 @@ classRegistry.setClass(FabricObject$1, 'object');
8248
8236
 
8249
8237
  /**
8250
8238
  * Wrap an action handler with firing an event if the action is performed
8251
- * @param {Function} actionHandler the function to wrap
8252
- * @return {Function} a function with an action handler signature
8239
+ * @param {TModificationEvents} eventName the event we want to fire
8240
+ * @param {TransformActionHandler<T>} actionHandler the function to wrap
8241
+ * @param {object} extraEventInfo extra information to pas to the event handler
8242
+ * @return {TransformActionHandler<T>} a function with an action handler signature
8253
8243
  */
8254
- const wrapWithFireEvent = (eventName, actionHandler) => {
8244
+ const wrapWithFireEvent = (eventName, actionHandler, extraEventInfo) => {
8255
8245
  return (eventData, transform, x, y) => {
8256
8246
  const actionPerformed = actionHandler(eventData, transform, x, y);
8257
8247
  if (actionPerformed) {
8258
- fireEvent(eventName, commonEventInfo(eventData, transform, x, y));
8248
+ fireEvent(eventName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), extraEventInfo));
8259
8249
  }
8260
8250
  return actionPerformed;
8261
8251
  };
@@ -10727,6 +10717,7 @@ function parseStyleObject(style, oStyle) {
10727
10717
  */
10728
10718
  function parseStyleString(style, oStyle) {
10729
10719
  style.replace(/;\s*$/, '').split(';').forEach(chunk => {
10720
+ if (!chunk) return;
10730
10721
  const [attr, value] = chunk.split(':');
10731
10722
  oStyle[attr.trim().toLowerCase()] = value.trim();
10732
10723
  });
@@ -11156,7 +11147,7 @@ class LayoutManager {
11156
11147
  const {
11157
11148
  target
11158
11149
  } = context;
11159
- return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? {
11150
+ return [MODIFIED, MOVING, RESIZING, ROTATING, SCALING, SKEWING, CHANGED, MODIFY_POLY, MODIFY_PATH].map(key => object.on(key, e => this.performLayout(key === MODIFIED ? {
11160
11151
  type: LAYOUT_TYPE_OBJECT_MODIFIED,
11161
11152
  trigger: key,
11162
11153
  e,
@@ -12093,7 +12084,7 @@ const arcToSegments = (toX, toY, rx, ry, large, sweep, rotateX) => {
12093
12084
 
12094
12085
  // Convert into cubic bezier segments <= 90deg
12095
12086
  const segments = Math.ceil(Math.abs(dtheta / PI * 2)),
12096
- result = new Array(segments),
12087
+ result = [],
12097
12088
  mDelta = dtheta / segments,
12098
12089
  mT = 8 / 3 * Math.sin(mDelta / 4) * Math.sin(mDelta / 4) / Math.sin(mDelta / 2);
12099
12090
  let th3 = mTheta + mDelta;
@@ -12644,7 +12635,6 @@ const rePathCmd = new RegExp(rePathCommand, 'i');
12644
12635
  * ['Q', 3, 5, 2, 1, 4, 0],
12645
12636
  * ['Q', 9, 12, 2, 1, 4, 0],
12646
12637
  * ];
12647
- *
12648
12638
  */
12649
12639
  const parsePath = pathString => {
12650
12640
  // clean the string
@@ -14104,6 +14094,9 @@ class SelectableCanvas extends StaticCanvas$1 {
14104
14094
  if (this._currentTransform && this._currentTransform.target === obj) {
14105
14095
  this.endCurrentTransform(e);
14106
14096
  }
14097
+ if (isActiveSelection(obj) && obj === this._hoveredTarget) {
14098
+ this._hoveredTarget = undefined;
14099
+ }
14107
14100
  this._activeObject = undefined;
14108
14101
  return true;
14109
14102
  }
@@ -18765,8 +18758,6 @@ class TextSVGExportMixin extends FabricObjectSVGExportMixin {
18765
18758
  * @return {String}
18766
18759
  */
18767
18760
  getSvgStyles(skipShadow) {
18768
- // cant use ts-expect-error because of ts 5.3 cross check
18769
- // @ts-ignore TS doesn't respect this type casting
18770
18761
  return "".concat(super.getSvgStyles(skipShadow), " white-space: pre;");
18771
18762
  }
18772
18763
 
@@ -20719,7 +20710,6 @@ class ITextBehavior extends FabricText {
20719
20710
  } : undefined);
20720
20711
  this._fireSelectionChanged();
20721
20712
  if (this.canvas) {
20722
- // @ts-expect-error in reality it is an IText instance
20723
20713
  this.canvas.fire('text:editing:entered', {
20724
20714
  target: this,
20725
20715
  e
@@ -23215,8 +23205,6 @@ class Textbox extends IText {
23215
23205
  * @param {Array} [propertiesToInclude] Any properties that you might want to additionally include in the output
23216
23206
  * @return {Object} object representation of an instance
23217
23207
  */
23218
- // cant use ts-expect-error because of ts 5.3 cross check
23219
- // @ts-ignore TS this typing limitations
23220
23208
  toObject() {
23221
23209
  let propertiesToInclude = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
23222
23210
  return super.toObject(['minWidth', 'splitByGrapheme', ...propertiesToInclude]);
@@ -24408,8 +24396,6 @@ class FabricImage extends FabricObject {
24408
24396
  */
24409
24397
  drawCacheOnCanvas(ctx) {
24410
24398
  ctx.imageSmoothingEnabled = this.imageSmoothing;
24411
- // cant use ts-expect-error because of ts 5.3 cross check
24412
- // @ts-ignore TS doesn't respect this type casting
24413
24399
  super.drawCacheOnCanvas(ctx);
24414
24400
  }
24415
24401
 
@@ -24799,65 +24785,82 @@ function getMultipleNodes(doc, nodeNames) {
24799
24785
 
24800
24786
  function parseUseDirectives(doc) {
24801
24787
  const nodelist = getMultipleNodes(doc, ['use', 'svg:use']);
24802
- let i = 0;
24803
- while (nodelist.length && i < nodelist.length) {
24804
- const el = nodelist[i],
24805
- xlinkAttribute = el.getAttribute('xlink:href') || el.getAttribute('href');
24806
- if (xlinkAttribute === null) {
24788
+ const skipAttributes = ['x', 'y', 'xlink:href', 'href', 'transform'];
24789
+ for (const useElement of nodelist) {
24790
+ const useAttributes = useElement.attributes;
24791
+ const useAttrMap = {};
24792
+ for (const attr of useAttributes) {
24793
+ attr.value && (useAttrMap[attr.name] = attr.value);
24794
+ }
24795
+ const xlink = (useAttrMap['xlink:href'] || useAttrMap.href || '').slice(1);
24796
+ if (xlink === '') {
24807
24797
  return;
24808
24798
  }
24809
- const xlink = xlinkAttribute.slice(1);
24810
- const x = el.getAttribute('x') || 0;
24811
- const y = el.getAttribute('y') || 0;
24812
- const el2Orig = doc.getElementById(xlink);
24813
- if (el2Orig === null) {
24799
+ const referencedElement = doc.getElementById(xlink);
24800
+ if (referencedElement === null) {
24814
24801
  // if we can't find the target of the xlink, consider this use tag bad, similar to no xlink
24815
24802
  return;
24816
24803
  }
24817
- let el2 = el2Orig.cloneNode(true);
24818
- let currentTrans = (el2.getAttribute('transform') || '') + ' translate(' + x + ', ' + y + ')';
24819
- const oldLength = nodelist.length;
24820
- const namespace = svgNS;
24821
- applyViewboxTransform(el2);
24822
- if (/^svg$/i.test(el2.nodeName)) {
24823
- const el3 = el2.ownerDocument.createElementNS(namespace, 'g');
24824
- for (let j = 0, attrs = el2.attributes, len = attrs.length; j < len; j++) {
24825
- const attr = attrs.item(j);
24826
- attr && el3.setAttributeNS(namespace, attr.nodeName, attr.nodeValue);
24827
- }
24828
- // el2.firstChild != null
24829
- while (el2.firstChild) {
24830
- el3.appendChild(el2.firstChild);
24831
- }
24832
- el2 = el3;
24804
+ let clonedOriginal = referencedElement.cloneNode(true);
24805
+ const originalAttributes = clonedOriginal.attributes;
24806
+ const originalAttrMap = {};
24807
+ for (const attr of originalAttributes) {
24808
+ attr.value && (originalAttrMap[attr.name] = attr.value);
24833
24809
  }
24834
- for (let j = 0, attrs = el.attributes, len = attrs.length; j < len; j++) {
24835
- const attr = attrs.item(j);
24810
+
24811
+ // Transform attribute needs to be merged in a particular way
24812
+ const {
24813
+ x = 0,
24814
+ y = 0,
24815
+ transform = ''
24816
+ } = useAttrMap;
24817
+ const currentTrans = "".concat(transform, " ").concat(originalAttrMap.transform || '', " translate(").concat(x, ", ").concat(y, ")");
24818
+ applyViewboxTransform(clonedOriginal);
24819
+ if (/^svg$/i.test(clonedOriginal.nodeName)) {
24820
+ // if is an SVG, create a group and apply all the attributes on top of it
24821
+ const el3 = clonedOriginal.ownerDocument.createElementNS(svgNS, 'g');
24822
+ Object.entries(originalAttrMap).forEach(_ref => {
24823
+ let [name, value] = _ref;
24824
+ return el3.setAttributeNS(svgNS, name, value);
24825
+ });
24826
+ el3.append(...clonedOriginal.childNodes);
24827
+ clonedOriginal = el3;
24828
+ }
24829
+ for (const attr of useAttributes) {
24836
24830
  if (!attr) {
24837
24831
  continue;
24838
24832
  }
24839
24833
  const {
24840
- nodeName,
24841
- nodeValue
24834
+ name,
24835
+ value
24842
24836
  } = attr;
24843
- if (nodeName === 'x' || nodeName === 'y' || nodeName === 'xlink:href' || nodeName === 'href') {
24837
+ if (skipAttributes.includes(name)) {
24844
24838
  continue;
24845
24839
  }
24846
- if (nodeName === 'transform') {
24847
- currentTrans = nodeValue + ' ' + currentTrans;
24840
+ if (name === 'style') {
24841
+ // when use has a style, merge the two styles, with the ref being priority (not use)
24842
+ // priority is by feature. an attribute for fill on the original element
24843
+ // will overwrite the fill in style or attribute for tha use
24844
+ const styleRecord = {};
24845
+ parseStyleString(value, styleRecord);
24846
+ // cleanup styleRecord from attributes of original
24847
+ Object.entries(originalAttrMap).forEach(_ref2 => {
24848
+ let [name, value] = _ref2;
24849
+ styleRecord[name] = value;
24850
+ });
24851
+ // now we can put in the style of the original that will overwrite the original attributes
24852
+ parseStyleString(originalAttrMap.style || '', styleRecord);
24853
+ const mergedStyles = Object.entries(styleRecord).map(entry => entry.join(':')).join(';');
24854
+ clonedOriginal.setAttribute(name, mergedStyles);
24848
24855
  } else {
24849
- el2.setAttribute(nodeName, nodeValue);
24856
+ // set the attribute from use element only if the original does not have it already
24857
+ !originalAttrMap[name] && clonedOriginal.setAttribute(name, value);
24850
24858
  }
24851
24859
  }
24852
- el2.setAttribute('transform', currentTrans);
24853
- el2.setAttribute('instantiated_by_use', '1');
24854
- el2.removeAttribute('id');
24855
- const parentNode = el.parentNode;
24856
- parentNode.replaceChild(el2, el);
24857
- // some browsers do not shorten nodelist after replaceChild (IE8)
24858
- if (nodelist.length === oldLength) {
24859
- i++;
24860
- }
24860
+ clonedOriginal.setAttribute('transform', currentTrans);
24861
+ clonedOriginal.setAttribute('instantiated_by_use', '1');
24862
+ clonedOriginal.removeAttribute('id');
24863
+ useElement.parentNode.replaceChild(clonedOriginal, useElement);
24861
24864
  }
24862
24865
  }
24863
24866
 
@@ -25214,7 +25217,7 @@ function loadSVGFromURL(url, reviver) {
25214
25217
  });
25215
25218
  }
25216
25219
 
25217
- const ACTION_NAME = MODIFY_POLY;
25220
+ const ACTION_NAME$1 = MODIFY_POLY;
25218
25221
  /**
25219
25222
  * This function locates the controls.
25220
25223
  * It'll be used both for drawing and for interaction.
@@ -25266,13 +25269,13 @@ const factoryPolyActionHandler = (pointIndex, fn) => {
25266
25269
  return actionPerformed;
25267
25270
  };
25268
25271
  };
25269
- const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME, factoryPolyActionHandler(pointIndex, polyActionHandler));
25272
+ const createPolyActionHandler = pointIndex => wrapWithFireEvent(ACTION_NAME$1, factoryPolyActionHandler(pointIndex, polyActionHandler));
25270
25273
  function createPolyControls(arg0) {
25271
25274
  let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25272
25275
  const controls = {};
25273
25276
  for (let idx = 0; idx < (typeof arg0 === 'number' ? arg0 : arg0.points.length); idx++) {
25274
25277
  controls["p".concat(idx)] = new Control(_objectSpread2({
25275
- actionName: ACTION_NAME,
25278
+ actionName: ACTION_NAME$1,
25276
25279
  positionHandler: createPolyPositionHandler(idx),
25277
25280
  actionHandler: createPolyActionHandler(idx)
25278
25281
  }, options));
@@ -25280,10 +25283,157 @@ function createPolyControls(arg0) {
25280
25283
  return controls;
25281
25284
  }
25282
25285
 
25286
+ const ACTION_NAME = 'modifyPath';
25287
+ const calcPathPointPosition = (pathObject, commandIndex, pointIndex) => {
25288
+ const {
25289
+ path,
25290
+ pathOffset
25291
+ } = pathObject;
25292
+ const command = path[commandIndex];
25293
+ return new Point(command[pointIndex] - pathOffset.x, command[pointIndex + 1] - pathOffset.y).transform(multiplyTransformMatrices(pathObject.getViewportTransform(), pathObject.calcTransformMatrix()));
25294
+ };
25295
+ const movePathPoint = (pathObject, x, y, commandIndex, pointIndex) => {
25296
+ const {
25297
+ path,
25298
+ pathOffset
25299
+ } = pathObject;
25300
+ const anchorCommand = path[(commandIndex > 0 ? commandIndex : path.length) - 1];
25301
+ const anchorPoint = new Point(anchorCommand[pointIndex], anchorCommand[pointIndex + 1]);
25302
+ const anchorPointInParentPlane = anchorPoint.subtract(pathOffset).transform(pathObject.calcOwnMatrix());
25303
+ const mouseLocalPosition = sendPointToPlane(new Point(x, y), undefined, pathObject.calcOwnMatrix());
25304
+ path[commandIndex][pointIndex] = mouseLocalPosition.x + pathOffset.x;
25305
+ path[commandIndex][pointIndex + 1] = mouseLocalPosition.y + pathOffset.y;
25306
+ pathObject.setDimensions();
25307
+ const newAnchorPointInParentPlane = anchorPoint.subtract(pathObject.pathOffset).transform(pathObject.calcOwnMatrix());
25308
+ const diff = newAnchorPointInParentPlane.subtract(anchorPointInParentPlane);
25309
+ pathObject.left -= diff.x;
25310
+ pathObject.top -= diff.y;
25311
+ pathObject.set('dirty', true);
25312
+ return true;
25313
+ };
25314
+
25315
+ /**
25316
+ * This function locates the controls.
25317
+ * It'll be used both for drawing and for interaction.
25318
+ */
25319
+ function pathPositionHandler(dim, finalMatrix, pathObject) {
25320
+ const {
25321
+ commandIndex,
25322
+ pointIndex
25323
+ } = this;
25324
+ return calcPathPointPosition(pathObject, commandIndex, pointIndex);
25325
+ }
25326
+
25327
+ /**
25328
+ * This function defines what the control does.
25329
+ * It'll be called on every mouse move after a control has been clicked and is being dragged.
25330
+ * The function receives as argument the mouse event, the current transform object
25331
+ * and the current position in canvas coordinate `transform.target` is a reference to the
25332
+ * current object being transformed.
25333
+ */
25334
+ function pathActionHandler(eventData, transform, x, y) {
25335
+ const {
25336
+ target
25337
+ } = transform;
25338
+ const {
25339
+ commandIndex,
25340
+ pointIndex
25341
+ } = this;
25342
+ const actionPerformed = movePathPoint(target, x, y, commandIndex, pointIndex);
25343
+ {
25344
+ fireEvent(this.actionName, _objectSpread2(_objectSpread2({}, commonEventInfo(eventData, transform, x, y)), {}, {
25345
+ commandIndex,
25346
+ pointIndex
25347
+ }));
25348
+ }
25349
+ return actionPerformed;
25350
+ }
25351
+ const indexFromPrevCommand = previousCommandType => previousCommandType === 'C' ? 5 : previousCommandType === 'Q' ? 3 : 1;
25352
+ class PathPointControl extends Control {
25353
+ constructor(options) {
25354
+ super(options);
25355
+ }
25356
+ render(ctx, left, top, styleOverride, fabricObject) {
25357
+ const overrides = _objectSpread2(_objectSpread2({}, styleOverride), {}, {
25358
+ cornerColor: this.controlFill,
25359
+ cornerStrokeColor: this.controlStroke,
25360
+ transparentCorners: !this.controlFill
25361
+ });
25362
+ super.render(ctx, left, top, overrides, fabricObject);
25363
+ }
25364
+ }
25365
+ class PathControlPointControl extends PathPointControl {
25366
+ constructor(options) {
25367
+ super(options);
25368
+ }
25369
+ render(ctx, left, top, styleOverride, fabricObject) {
25370
+ const {
25371
+ path
25372
+ } = fabricObject;
25373
+ const {
25374
+ commandIndex,
25375
+ pointIndex,
25376
+ connectToCommandIndex,
25377
+ connectToPointIndex
25378
+ } = this;
25379
+ ctx.save();
25380
+ ctx.strokeStyle = this.controlStroke;
25381
+ if (this.connectionDashArray) {
25382
+ ctx.setLineDash(this.connectionDashArray);
25383
+ }
25384
+ const [commandType] = path[commandIndex];
25385
+ const point = calcPathPointPosition(fabricObject, connectToCommandIndex, connectToPointIndex);
25386
+ if (commandType === 'Q') {
25387
+ // one control point connects to 2 points
25388
+ const point2 = calcPathPointPosition(fabricObject, commandIndex, pointIndex + 2);
25389
+ ctx.moveTo(point2.x, point2.y);
25390
+ ctx.lineTo(left, top);
25391
+ } else {
25392
+ ctx.moveTo(left, top);
25393
+ }
25394
+ ctx.lineTo(point.x, point.y);
25395
+ ctx.stroke();
25396
+ ctx.restore();
25397
+ super.render(ctx, left, top, styleOverride, fabricObject);
25398
+ }
25399
+ }
25400
+ const createControl = (commandIndexPos, pointIndexPos, isControlPoint, options, connectToCommandIndex, connectToPointIndex) => new (isControlPoint ? PathControlPointControl : PathPointControl)(_objectSpread2(_objectSpread2({
25401
+ commandIndex: commandIndexPos,
25402
+ pointIndex: pointIndexPos,
25403
+ actionName: ACTION_NAME,
25404
+ positionHandler: pathPositionHandler,
25405
+ actionHandler: pathActionHandler,
25406
+ connectToCommandIndex,
25407
+ connectToPointIndex
25408
+ }, options), isControlPoint ? options.controlPointStyle : options.pointStyle));
25409
+ function createPathControls(path) {
25410
+ let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
25411
+ const controls = {};
25412
+ let previousCommandType = 'M';
25413
+ path.path.forEach((command, commandIndex) => {
25414
+ const commandType = command[0];
25415
+ if (commandType !== 'Z') {
25416
+ controls["c_".concat(commandIndex, "_").concat(commandType)] = createControl(commandIndex, command.length - 2, false, options);
25417
+ }
25418
+ switch (commandType) {
25419
+ case 'C':
25420
+ controls["c_".concat(commandIndex, "_C_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex - 1, indexFromPrevCommand(previousCommandType));
25421
+ controls["c_".concat(commandIndex, "_C_CP_2")] = createControl(commandIndex, 3, true, options, commandIndex, 5);
25422
+ break;
25423
+ case 'Q':
25424
+ controls["c_".concat(commandIndex, "_Q_CP_1")] = createControl(commandIndex, 1, true, options, commandIndex, 3);
25425
+ break;
25426
+ }
25427
+ previousCommandType = commandType;
25428
+ });
25429
+ return controls;
25430
+ }
25431
+
25283
25432
  var index = /*#__PURE__*/Object.freeze({
25284
25433
  __proto__: null,
25285
25434
  changeWidth: changeWidth,
25286
25435
  createObjectDefaultControls: createObjectDefaultControls,
25436
+ createPathControls: createPathControls,
25287
25437
  createPolyActionHandler: createPolyActionHandler,
25288
25438
  createPolyControls: createPolyControls,
25289
25439
  createPolyPositionHandler: createPolyPositionHandler,
@@ -25642,7 +25792,6 @@ class BaseFilter {
25642
25792
  return _objectSpread2({
25643
25793
  type: this.type
25644
25794
  }, defaultKeys.reduce((acc, key) => {
25645
- //@ts-expect-error TS doesn't get i want an object that looks like this
25646
25795
  acc[key] = this[key];
25647
25796
  return acc;
25648
25797
  }, {}));