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