fabric 5.3.0 → 6.0.0-beta3

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 (604) hide show
  1. package/.babelrc +11 -0
  2. package/.babelrcAlt +19 -0
  3. package/.browserslistrc +5 -0
  4. package/.eslintignore +3 -0
  5. package/.eslintrc.js +43 -0
  6. package/.eslintrc.json +38 -46
  7. package/.eslintrc_tests +12 -0
  8. package/.gitattributes +2 -0
  9. package/.gitpod.yml +17 -1
  10. package/.prettierignore +19 -0
  11. package/.prettierrc +4 -0
  12. package/CHANGELOG.md +532 -189
  13. package/CONTRIBUTING.md +224 -59
  14. package/README.md +200 -235
  15. package/bower.json +1 -3
  16. package/dist/fabric.d.ts +42 -0
  17. package/dist/index.d.ts +2 -0
  18. package/dist/index.js +27582 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/index.min.js +1 -0
  21. package/dist/index.mjs +27519 -0
  22. package/dist/index.mjs.map +1 -0
  23. package/dist/index.node.cjs +27663 -0
  24. package/dist/index.node.cjs.map +1 -0
  25. package/dist/index.node.d.ts +14 -0
  26. package/dist/index.node.mjs +27606 -0
  27. package/dist/index.node.mjs.map +1 -0
  28. package/dist/src/ClassRegistry.d.ts +13 -0
  29. package/dist/src/Collection.d.ts +136 -0
  30. package/dist/src/CommonMethods.d.ts +32 -0
  31. package/dist/src/EventTypeDefs.d.ts +227 -0
  32. package/dist/src/Intersection.d.ts +112 -0
  33. package/dist/src/Observable.d.ts +60 -0
  34. package/dist/src/Pattern.d.ts +113 -0
  35. package/dist/src/Point.d.ts +232 -0
  36. package/dist/src/Shadow.d.ts +97 -0
  37. package/dist/src/brushes/BaseBrush.d.ts +105 -0
  38. package/dist/src/brushes/CircleBrush.d.ts +49 -0
  39. package/dist/src/brushes/PatternBrush.d.ts +23 -0
  40. package/dist/src/brushes/PencilBrush.d.ts +92 -0
  41. package/dist/src/brushes/SprayBrush.d.ts +79 -0
  42. package/dist/src/cache.d.ts +47 -0
  43. package/dist/src/canvas/Canvas.d.ts +548 -0
  44. package/dist/src/canvas/SelectableCanvas.d.ts +754 -0
  45. package/dist/src/canvas/StaticCanvas.d.ts +778 -0
  46. package/dist/src/canvas/TextEditingManager.d.ts +17 -0
  47. package/dist/src/canvas/canvas_gestures.mixin.d.ts +2 -0
  48. package/dist/src/color/Color.d.ts +174 -0
  49. package/dist/src/color/color_map.d.ts +155 -0
  50. package/dist/src/color/constants.d.ts +22 -0
  51. package/dist/src/color/util.d.ts +12 -0
  52. package/dist/src/config.d.ts +115 -0
  53. package/dist/src/constants.d.ts +14 -0
  54. package/dist/src/controls/Control.d.ts +228 -0
  55. package/dist/src/controls/changeWidth.d.ts +13 -0
  56. package/dist/src/controls/commonControls.d.ts +28 -0
  57. package/dist/src/controls/controlRendering.d.ts +29 -0
  58. package/dist/src/controls/drag.d.ts +12 -0
  59. package/dist/src/controls/index.d.ts +13 -0
  60. package/dist/src/controls/polyControl.d.ts +5 -0
  61. package/dist/src/controls/rotate.d.ts +12 -0
  62. package/dist/src/controls/scale.d.ts +47 -0
  63. package/dist/src/controls/scaleSkew.d.ts +39 -0
  64. package/dist/src/controls/skew.d.ts +33 -0
  65. package/dist/src/controls/util.d.ts +41 -0
  66. package/dist/src/controls/wrapWithFireEvent.d.ts +8 -0
  67. package/dist/src/controls/wrapWithFixedAnchor.d.ts +9 -0
  68. package/dist/src/env/browser.d.ts +3 -0
  69. package/dist/src/env/index.d.ts +15 -0
  70. package/dist/src/env/node.d.ts +5 -0
  71. package/dist/src/env/types.d.ts +15 -0
  72. package/dist/src/filters/BaseFilter.d.ts +153 -0
  73. package/dist/src/filters/BlendColor.d.ts +80 -0
  74. package/dist/src/filters/BlendImage.d.ts +92 -0
  75. package/dist/src/filters/Blur.d.ts +51 -0
  76. package/dist/src/filters/Boilerplate.d.ts +48 -0
  77. package/dist/src/filters/Brightness.d.ts +47 -0
  78. package/dist/src/filters/Canvas2dFilterBackend.d.ts +27 -0
  79. package/dist/src/filters/ColorMatrix.d.ts +63 -0
  80. package/dist/src/filters/ColorMatrixFilters.d.ts +545 -0
  81. package/dist/src/filters/Composed.d.ts +45 -0
  82. package/dist/src/filters/Contrast.d.ts +45 -0
  83. package/dist/src/filters/Convolute.d.ts +82 -0
  84. package/dist/src/filters/FilterBackend.d.ts +14 -0
  85. package/dist/src/filters/GLProbes/GLProbe.d.ts +11 -0
  86. package/dist/src/filters/GLProbes/NodeGLProbe.d.ts +11 -0
  87. package/dist/src/filters/GLProbes/WebGLProbe.d.ts +20 -0
  88. package/dist/src/filters/Gamma.d.ts +54 -0
  89. package/dist/src/filters/Grayscale.d.ts +46 -0
  90. package/dist/src/filters/HueRotation.d.ts +24 -0
  91. package/dist/src/filters/Invert.d.ts +55 -0
  92. package/dist/src/filters/Noise.d.ts +54 -0
  93. package/dist/src/filters/Pixelate.d.ts +44 -0
  94. package/dist/src/filters/RemoveColor.d.ts +63 -0
  95. package/dist/src/filters/Resize.d.ts +136 -0
  96. package/dist/src/filters/Saturation.d.ts +48 -0
  97. package/dist/src/filters/Vibrance.d.ts +48 -0
  98. package/dist/src/filters/WebGLFilterBackend.d.ts +126 -0
  99. package/dist/src/filters/filters.d.ts +21 -0
  100. package/dist/src/filters/index.d.ts +5 -0
  101. package/dist/src/filters/shaders/baseFilter.d.ts +4 -0
  102. package/dist/src/filters/shaders/blendColor.d.ts +13 -0
  103. package/dist/src/filters/shaders/blendImage.d.ts +3 -0
  104. package/dist/src/filters/shaders/blur.d.ts +2 -0
  105. package/dist/src/filters/shaders/brightness.d.ts +2 -0
  106. package/dist/src/filters/shaders/colorMatrix.d.ts +2 -0
  107. package/dist/src/filters/shaders/constrast.d.ts +2 -0
  108. package/dist/src/filters/shaders/convolute.d.ts +11 -0
  109. package/dist/src/filters/shaders/gamma.d.ts +2 -0
  110. package/dist/src/filters/shaders/grayscale.d.ts +3 -0
  111. package/dist/src/filters/shaders/invert.d.ts +2 -0
  112. package/dist/src/filters/shaders/noise.d.ts +2 -0
  113. package/dist/src/filters/shaders/pixelate.d.ts +2 -0
  114. package/dist/src/filters/shaders/removeColor.d.ts +2 -0
  115. package/dist/src/filters/shaders/saturation.d.ts +2 -0
  116. package/dist/src/filters/shaders/vibrance.d.ts +2 -0
  117. package/dist/src/filters/typedefs.d.ts +49 -0
  118. package/dist/src/gradient/Gradient.d.ts +149 -0
  119. package/dist/src/gradient/constants.d.ts +15 -0
  120. package/dist/src/gradient/parser/index.d.ts +4 -0
  121. package/dist/src/gradient/parser/misc.d.ts +4 -0
  122. package/dist/src/gradient/parser/parseColorStops.d.ts +3 -0
  123. package/dist/src/gradient/parser/parseCoords.d.ts +17 -0
  124. package/dist/src/gradient/typedefs.d.ts +93 -0
  125. package/dist/src/mixins/eraser_brush.mixin.d.ts +2 -0
  126. package/dist/src/parkinglot/canvas_animation.mixin.d.ts +2 -0
  127. package/dist/src/parkinglot/straighten.d.ts +2 -0
  128. package/dist/src/parser/applyViewboxTransform.d.ts +5 -0
  129. package/dist/src/parser/attributes.d.ts +6 -0
  130. package/dist/src/parser/constants.d.ts +53 -0
  131. package/dist/src/parser/doesSomeParentMatch.d.ts +2 -0
  132. package/dist/src/parser/elementById.d.ts +6 -0
  133. package/dist/src/parser/elementMatchesRule.d.ts +5 -0
  134. package/dist/src/parser/elements_parser.d.ts +3 -0
  135. package/dist/src/parser/getCSSRules.d.ts +7 -0
  136. package/dist/src/parser/getGlobalStylesForElement.d.ts +5 -0
  137. package/dist/src/parser/getGradientDefs.d.ts +7 -0
  138. package/dist/src/parser/getMultipleNodes.d.ts +2 -0
  139. package/dist/src/parser/getSvgRegex.d.ts +2 -0
  140. package/dist/src/parser/hasAncestorWithNodeName.d.ts +2 -0
  141. package/dist/src/parser/index.d.ts +10 -0
  142. package/dist/src/parser/loadSVGFromString.d.ts +12 -0
  143. package/dist/src/parser/loadSVGFromURL.d.ts +13 -0
  144. package/dist/src/parser/normalizeAttr.d.ts +2 -0
  145. package/dist/src/parser/normalizeValue.d.ts +2 -0
  146. package/dist/src/parser/parseAttributes.d.ts +9 -0
  147. package/dist/src/parser/parseElements.d.ts +11 -0
  148. package/dist/src/parser/parseFontDeclaration.d.ts +10 -0
  149. package/dist/src/parser/parsePointsAttribute.d.ts +12 -0
  150. package/dist/src/parser/parseSVGDocument.d.ts +15 -0
  151. package/dist/src/parser/parseStyleAttribute.d.ts +9 -0
  152. package/dist/src/parser/parseStyleObject.d.ts +2 -0
  153. package/dist/src/parser/parseStyleString.d.ts +2 -0
  154. package/dist/src/parser/parseTransformAttribute.d.ts +10 -0
  155. package/dist/src/parser/parseUseDirectives.d.ts +2 -0
  156. package/dist/src/parser/percent.d.ts +9 -0
  157. package/dist/src/parser/recursivelyParseGradientsXlink.d.ts +2 -0
  158. package/dist/src/parser/rotateMatrix.d.ts +2 -0
  159. package/dist/src/parser/scaleMatrix.d.ts +2 -0
  160. package/dist/src/parser/selectorMatches.d.ts +2 -0
  161. package/dist/src/parser/setStrokeFillOpacity.d.ts +6 -0
  162. package/dist/src/parser/skewMatrix.d.ts +2 -0
  163. package/dist/src/parser/translateMatrix.d.ts +2 -0
  164. package/dist/src/shapes/ActiveSelection.d.ts +82 -0
  165. package/dist/src/shapes/Circle.d.ts +99 -0
  166. package/dist/src/shapes/Ellipse.d.ts +84 -0
  167. package/dist/src/shapes/Group.d.ts +408 -0
  168. package/dist/src/shapes/IText/DraggableTextDelegate.d.ts +78 -0
  169. package/dist/src/shapes/IText/IText.d.ts +335 -0
  170. package/dist/src/shapes/IText/ITextBehavior.d.ts +287 -0
  171. package/dist/src/shapes/IText/ITextClickBehavior.d.ts +83 -0
  172. package/dist/src/shapes/IText/ITextKeyBehavior.d.ts +195 -0
  173. package/dist/src/shapes/IText/constants.d.ts +13 -0
  174. package/dist/src/shapes/Image.d.ts +311 -0
  175. package/dist/src/shapes/Line.d.ts +126 -0
  176. package/dist/src/shapes/Object/AnimatableObject.d.ts +33 -0
  177. package/dist/src/shapes/Object/FabricObject.d.ts +11 -0
  178. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts +74 -0
  179. package/dist/src/shapes/Object/InteractiveObject.d.ts +296 -0
  180. package/dist/src/shapes/Object/Object.d.ts +594 -0
  181. package/dist/src/shapes/Object/ObjectGeometry.d.ts +327 -0
  182. package/dist/src/shapes/Object/ObjectOrigin.d.ts +109 -0
  183. package/dist/src/shapes/Object/StackedObject.d.ts +72 -0
  184. package/dist/src/shapes/Object/defaultValues.d.ts +76 -0
  185. package/dist/src/shapes/Object/types/BaseProps.d.ts +84 -0
  186. package/dist/src/shapes/Object/types/BorderProps.d.ts +37 -0
  187. package/dist/src/shapes/Object/types/ControlProps.d.ts +62 -0
  188. package/dist/src/shapes/Object/types/FabricObjectProps.d.ts +96 -0
  189. package/dist/src/shapes/Object/types/FillStrokeProps.d.ts +80 -0
  190. package/dist/src/shapes/Object/types/LockInteractionProps.d.ts +51 -0
  191. package/dist/src/shapes/Object/types/ObjectProps.d.ts +42 -0
  192. package/dist/src/shapes/Object/types/SerializedObjectProps.d.ts +66 -0
  193. package/dist/src/shapes/Object/types/index.d.ts +6 -0
  194. package/dist/src/shapes/Path.d.ts +130 -0
  195. package/dist/src/shapes/Polygon.d.ts +9 -0
  196. package/dist/src/shapes/Polyline.d.ts +140 -0
  197. package/dist/src/shapes/Rect.d.ts +76 -0
  198. package/dist/src/shapes/Text/StyledText.d.ts +119 -0
  199. package/dist/src/shapes/Text/Text.d.ts +673 -0
  200. package/dist/src/shapes/Text/TextSVGExportMixin.d.ts +32 -0
  201. package/dist/src/shapes/Text/constants.d.ts +7 -0
  202. package/dist/src/shapes/Textbox.d.ts +185 -0
  203. package/dist/src/shapes/Triangle.d.ts +25 -0
  204. package/dist/src/typedefs.d.ts +90 -0
  205. package/dist/src/util/animation/AnimationBase.d.ts +54 -0
  206. package/dist/src/util/animation/AnimationFrameProvider.d.ts +3 -0
  207. package/dist/src/util/animation/AnimationRegistry.d.ts +29 -0
  208. package/dist/src/util/animation/ArrayAnimation.d.ts +10 -0
  209. package/dist/src/util/animation/ColorAnimation.d.ts +11 -0
  210. package/dist/src/util/animation/ValueAnimation.d.ts +10 -0
  211. package/dist/src/util/animation/animate.d.ts +37 -0
  212. package/dist/src/util/animation/easing.d.ts +130 -0
  213. package/dist/src/util/animation/types.d.ts +87 -0
  214. package/dist/src/util/applyMixins.d.ts +8 -0
  215. package/dist/src/util/dom_event.d.ts +5 -0
  216. package/dist/src/util/dom_misc.d.ts +39 -0
  217. package/dist/src/util/dom_request.d.ts +14 -0
  218. package/dist/src/util/dom_style.d.ts +7 -0
  219. package/dist/src/util/fireEvent.d.ts +3 -0
  220. package/dist/src/util/index.d.ts +35 -0
  221. package/dist/src/util/internals/cloneDeep.d.ts +2 -0
  222. package/dist/src/util/internals/getRandomInt.d.ts +8 -0
  223. package/dist/src/util/internals/ifNaN.d.ts +8 -0
  224. package/dist/src/util/internals/index.d.ts +4 -0
  225. package/dist/src/util/internals/removeFromArray.d.ts +9 -0
  226. package/dist/src/util/internals/uid.d.ts +2 -0
  227. package/dist/src/util/lang_string.d.ts +22 -0
  228. package/dist/src/util/misc/boundingBoxFromPoints.d.ts +9 -0
  229. package/dist/src/util/misc/capValue.d.ts +2 -0
  230. package/dist/src/util/misc/cos.d.ts +10 -0
  231. package/dist/src/util/misc/dom.d.ts +28 -0
  232. package/dist/src/util/misc/findScaleTo.d.ts +29 -0
  233. package/dist/src/util/misc/groupSVGElements.d.ts +9 -0
  234. package/dist/src/util/misc/isTransparent.d.ts +11 -0
  235. package/dist/src/util/misc/matrix.d.ts +92 -0
  236. package/dist/src/util/misc/mergeClipPaths.d.ts +23 -0
  237. package/dist/src/util/misc/objectEnlive.d.ts +56 -0
  238. package/dist/src/util/misc/objectTransforms.d.ts +68 -0
  239. package/dist/src/util/misc/pick.d.ts +9 -0
  240. package/dist/src/util/misc/planeChange.d.ts +84 -0
  241. package/dist/src/util/misc/projectStroke/StrokeLineCapProjections.d.ts +51 -0
  242. package/dist/src/util/misc/projectStroke/StrokeLineJoinProjections.d.ts +81 -0
  243. package/dist/src/util/misc/projectStroke/StrokeProjectionsBase.d.ts +25 -0
  244. package/dist/src/util/misc/projectStroke/index.d.ts +11 -0
  245. package/dist/src/util/misc/projectStroke/types.d.ts +23 -0
  246. package/dist/src/util/misc/radiansDegreesConversion.d.ts +14 -0
  247. package/dist/src/util/misc/resolveOrigin.d.ts +9 -0
  248. package/dist/src/util/misc/rotatePoint.d.ts +12 -0
  249. package/dist/src/util/misc/sin.d.ts +10 -0
  250. package/dist/src/util/misc/svgParsing.d.ts +53 -0
  251. package/dist/src/util/misc/textStyles.d.ts +32 -0
  252. package/dist/src/util/misc/toFixed.d.ts +8 -0
  253. package/dist/src/util/misc/vectors.d.ts +57 -0
  254. package/dist/src/util/path/index.d.ts +96 -0
  255. package/dist/src/util/path/regex.d.ts +3 -0
  256. package/dist/src/util/path/typechecks.d.ts +24 -0
  257. package/dist/src/util/path/typedefs.d.ts +220 -0
  258. package/dist/src/util/transform_matrix_removal.d.ts +14 -0
  259. package/dist/src/util/types.d.ts +19 -0
  260. package/fabric.ts +51 -0
  261. package/index.node.ts +37 -0
  262. package/index.ts +1 -0
  263. package/package.json +100 -40
  264. package/publish.js +0 -26
  265. package/rollup.config.mjs +91 -0
  266. package/rollup.test.config.js +24 -0
  267. package/scripts/build.mjs +50 -0
  268. package/scripts/buildLock.mjs +115 -0
  269. package/scripts/buildReporter.mjs +15 -0
  270. package/scripts/buildStats.mjs +139 -0
  271. package/scripts/dirname.mjs +14 -0
  272. package/scripts/git.mjs +36 -0
  273. package/scripts/index.mjs +564 -0
  274. package/scripts/sandbox.mjs +149 -0
  275. package/src/ClassRegistry.ts +56 -0
  276. package/src/Collection.ts +346 -0
  277. package/src/CommonMethods.ts +63 -0
  278. package/src/EventTypeDefs.ts +296 -0
  279. package/src/Intersection.ts +302 -0
  280. package/src/Observable.ts +181 -0
  281. package/src/Pattern.ts +227 -0
  282. package/src/Point.ts +388 -0
  283. package/src/Shadow.ts +214 -0
  284. package/src/brushes/{base_brush.class.js → BaseBrush.ts} +65 -42
  285. package/src/brushes/CircleBrush.ts +145 -0
  286. package/src/brushes/PatternBrush.ts +70 -0
  287. package/src/brushes/PencilBrush.ts +300 -0
  288. package/src/brushes/SprayBrush.ts +219 -0
  289. package/src/cache.ts +90 -0
  290. package/src/canvas/Canvas.ts +1607 -0
  291. package/src/canvas/SelectableCanvas.ts +1608 -0
  292. package/src/canvas/StaticCanvas.ts +1734 -0
  293. package/src/canvas/TextEditingManager.ts +48 -0
  294. package/src/canvas/canvas_gestures.mixin.ts +207 -0
  295. package/src/color/Color.ts +404 -0
  296. package/src/color/color_map.ts +154 -0
  297. package/src/color/constants.ts +26 -0
  298. package/src/color/util.ts +32 -0
  299. package/src/config.ts +159 -0
  300. package/src/constants.ts +20 -0
  301. package/src/controls/Control.ts +380 -0
  302. package/src/controls/changeWidth.ts +52 -0
  303. package/src/controls/commonControls.ts +105 -0
  304. package/src/controls/controlRendering.ts +138 -0
  305. package/src/controls/drag.ts +31 -0
  306. package/src/controls/index.ts +22 -0
  307. package/src/controls/polyControl.ts +135 -0
  308. package/src/controls/rotate.ts +87 -0
  309. package/src/controls/scale.ts +277 -0
  310. package/src/controls/scaleSkew.ts +92 -0
  311. package/src/controls/skew.ts +242 -0
  312. package/src/controls/util.ts +154 -0
  313. package/src/controls/wrapWithFireEvent.ts +25 -0
  314. package/src/controls/wrapWithFixedAnchor.ts +20 -0
  315. package/src/env/browser.ts +32 -0
  316. package/src/env/index.ts +24 -0
  317. package/src/env/node.ts +56 -0
  318. package/src/env/types.ts +15 -0
  319. package/src/filters/{base_filter.class.js → BaseFilter.ts} +192 -151
  320. package/src/filters/BlendColor.ts +217 -0
  321. package/src/filters/BlendImage.ts +228 -0
  322. package/src/filters/Blur.ts +179 -0
  323. package/src/filters/Boilerplate.ts +94 -0
  324. package/src/filters/Brightness.ts +83 -0
  325. package/src/filters/Canvas2dFilterBackend.ts +65 -0
  326. package/src/filters/ColorMatrix.ts +145 -0
  327. package/src/filters/ColorMatrixFilters.ts +77 -0
  328. package/src/filters/Composed.ts +76 -0
  329. package/src/filters/Contrast.ts +82 -0
  330. package/src/filters/Convolute.ts +184 -0
  331. package/src/filters/FilterBackend.ts +34 -0
  332. package/src/filters/GLProbes/GLProbe.ts +11 -0
  333. package/src/filters/GLProbes/NodeGLProbe.ts +15 -0
  334. package/src/filters/GLProbes/WebGLProbe.ts +46 -0
  335. package/src/filters/Gamma.ts +110 -0
  336. package/src/filters/Grayscale.ts +102 -0
  337. package/src/filters/HueRotation.ts +62 -0
  338. package/src/filters/Invert.ts +99 -0
  339. package/src/filters/Noise.ts +94 -0
  340. package/src/filters/Pixelate.ts +96 -0
  341. package/src/filters/RemoveColor.ts +135 -0
  342. package/src/filters/Resize.ts +538 -0
  343. package/src/filters/Saturation.ts +87 -0
  344. package/src/filters/Vibrance.ts +88 -0
  345. package/src/filters/WebGLFilterBackend.ts +430 -0
  346. package/src/filters/filters.ts +28 -0
  347. package/src/filters/index.ts +5 -0
  348. package/src/filters/shaders/baseFilter.ts +19 -0
  349. package/src/filters/shaders/blendColor.ts +33 -0
  350. package/src/filters/shaders/blendImage.ts +32 -0
  351. package/src/filters/shaders/blur.ts +24 -0
  352. package/src/filters/shaders/brightness.ts +11 -0
  353. package/src/filters/shaders/colorMatrix.ts +12 -0
  354. package/src/filters/shaders/constrast.ts +11 -0
  355. package/src/filters/shaders/convolute.ts +154 -0
  356. package/src/filters/shaders/gamma.ts +15 -0
  357. package/src/filters/shaders/grayscale.ts +36 -0
  358. package/src/filters/shaders/invert.ts +19 -0
  359. package/src/filters/shaders/noise.ts +16 -0
  360. package/src/filters/shaders/pixelate.ts +19 -0
  361. package/src/filters/shaders/removeColor.ts +13 -0
  362. package/src/filters/shaders/saturation.ts +15 -0
  363. package/src/filters/shaders/vibrance.ts +16 -0
  364. package/src/filters/typedefs.ts +65 -0
  365. package/src/gradient/Gradient.ts +406 -0
  366. package/src/gradient/constants.ts +12 -0
  367. package/src/gradient/parser/index.ts +3 -0
  368. package/src/gradient/parser/misc.ts +13 -0
  369. package/src/gradient/parser/parseColorStops.ts +56 -0
  370. package/src/gradient/parser/parseCoords.ts +73 -0
  371. package/src/gradient/typedefs.ts +104 -0
  372. package/src/mixins/{eraser_brush.mixin.js → eraser_brush.mixin.ts} +350 -239
  373. package/src/parkinglot/canvas_animation.mixin.ts +121 -0
  374. package/src/parkinglot/straighten.ts +58 -0
  375. package/src/parser/applyViewboxTransform.ts +157 -0
  376. package/src/parser/attributes.ts +25 -0
  377. package/src/parser/constants.ts +115 -0
  378. package/src/parser/doesSomeParentMatch.ts +19 -0
  379. package/src/parser/elementById.ts +21 -0
  380. package/src/parser/elementMatchesRule.ts +16 -0
  381. package/src/parser/elements_parser.ts +191 -0
  382. package/src/parser/getCSSRules.ts +62 -0
  383. package/src/parser/getGlobalStylesForElement.ts +19 -0
  384. package/src/parser/getGradientDefs.ts +31 -0
  385. package/src/parser/getMultipleNodes.ts +15 -0
  386. package/src/parser/getSvgRegex.ts +5 -0
  387. package/src/parser/hasAncestorWithNodeName.ts +14 -0
  388. package/src/parser/index.ts +9 -0
  389. package/src/parser/loadSVGFromString.ts +26 -0
  390. package/src/parser/loadSVGFromURL.ts +40 -0
  391. package/src/parser/normalizeAttr.ts +10 -0
  392. package/src/parser/normalizeValue.ts +63 -0
  393. package/src/parser/parseAttributes.ts +90 -0
  394. package/src/parser/parseElements.ts +28 -0
  395. package/src/parser/parseFontDeclaration.ts +44 -0
  396. package/src/parser/parsePointsAttribute.ts +34 -0
  397. package/src/parser/parseSVGDocument.ts +93 -0
  398. package/src/parser/parseStyleAttribute.ts +27 -0
  399. package/src/parser/parseStyleObject.ts +15 -0
  400. package/src/parser/parseStyleString.ts +16 -0
  401. package/src/parser/parseTransformAttribute.ts +155 -0
  402. package/src/parser/parseUseDirectives.ts +78 -0
  403. package/src/parser/percent.ts +27 -0
  404. package/src/parser/recursivelyParseGradientsXlink.ts +42 -0
  405. package/src/parser/rotateMatrix.ts +21 -0
  406. package/src/parser/scaleMatrix.ts +9 -0
  407. package/src/parser/selectorMatches.ts +25 -0
  408. package/src/parser/setStrokeFillOpacity.ts +40 -0
  409. package/src/parser/skewMatrix.ts +6 -0
  410. package/src/parser/translateMatrix.ts +8 -0
  411. package/src/shapes/ActiveSelection.ts +189 -0
  412. package/src/shapes/Circle.ts +242 -0
  413. package/src/shapes/Ellipse.ts +179 -0
  414. package/src/shapes/Group.ts +1100 -0
  415. package/src/shapes/IText/DraggableTextDelegate.ts +382 -0
  416. package/src/shapes/IText/IText.ts +693 -0
  417. package/src/shapes/IText/ITextBehavior.ts +1064 -0
  418. package/src/shapes/IText/ITextClickBehavior.ts +325 -0
  419. package/src/shapes/IText/ITextKeyBehavior.ts +685 -0
  420. package/src/shapes/IText/constants.ts +47 -0
  421. package/src/shapes/Image.ts +841 -0
  422. package/src/shapes/Line.ts +346 -0
  423. package/src/shapes/Object/AnimatableObject.ts +106 -0
  424. package/src/shapes/Object/FabricObject.ts +29 -0
  425. package/src/shapes/Object/FabricObjectSVGExportMixin.ts +277 -0
  426. package/src/shapes/Object/InteractiveObject.ts +672 -0
  427. package/src/shapes/Object/Object.ts +1561 -0
  428. package/src/shapes/Object/ObjectGeometry.ts +813 -0
  429. package/src/shapes/Object/ObjectOrigin.ts +276 -0
  430. package/src/shapes/Object/StackedObject.ts +206 -0
  431. package/src/shapes/Object/defaultValues.ts +108 -0
  432. package/src/shapes/Object/types/BaseProps.ts +96 -0
  433. package/src/shapes/Object/types/BorderProps.ts +40 -0
  434. package/src/shapes/Object/types/ControlProps.ts +69 -0
  435. package/src/shapes/Object/types/FabricObjectProps.ts +111 -0
  436. package/src/shapes/Object/types/FillStrokeProps.ts +90 -0
  437. package/src/shapes/Object/types/LockInteractionProps.ts +57 -0
  438. package/src/shapes/Object/types/ObjectProps.ts +46 -0
  439. package/src/shapes/Object/types/SerializedObjectProps.ts +73 -0
  440. package/src/shapes/Object/types/index.ts +8 -0
  441. package/src/shapes/Path.ts +416 -0
  442. package/src/shapes/Polygon.ts +20 -0
  443. package/src/shapes/Polyline.ts +359 -0
  444. package/src/shapes/Rect.ts +233 -0
  445. package/src/shapes/Text/StyledText.ts +329 -0
  446. package/src/shapes/Text/Text.ts +1884 -0
  447. package/src/shapes/Text/TextSVGExportMixin.ts +288 -0
  448. package/src/shapes/Text/constants.ts +91 -0
  449. package/src/shapes/Textbox.ts +477 -0
  450. package/src/shapes/Triangle.ts +60 -0
  451. package/src/typedefs.ts +115 -0
  452. package/src/util/animation/AnimationBase.ts +166 -0
  453. package/src/util/animation/AnimationFrameProvider.ts +9 -0
  454. package/src/util/animation/AnimationRegistry.ts +58 -0
  455. package/src/util/animation/ArrayAnimation.ts +27 -0
  456. package/src/util/animation/ColorAnimation.ts +74 -0
  457. package/src/util/animation/ValueAnimation.ts +29 -0
  458. package/src/util/animation/animate.ts +74 -0
  459. package/src/util/animation/easing.ts +327 -0
  460. package/src/util/animation/types.ts +136 -0
  461. package/src/util/applyMixins.ts +22 -0
  462. package/src/util/dom_event.ts +28 -0
  463. package/src/util/dom_misc.ts +121 -0
  464. package/src/util/dom_request.ts +64 -0
  465. package/src/util/dom_style.ts +20 -0
  466. package/src/util/fireEvent.ts +15 -0
  467. package/src/util/index.ts +102 -0
  468. package/src/util/internals/cloneDeep.ts +2 -0
  469. package/src/util/internals/getRandomInt.ts +8 -0
  470. package/src/util/internals/ifNaN.ts +9 -0
  471. package/src/util/internals/index.ts +3 -0
  472. package/src/util/internals/removeFromArray.ts +14 -0
  473. package/src/util/internals/uid.ts +3 -0
  474. package/src/util/lang_string.ts +79 -0
  475. package/src/util/misc/boundingBoxFromPoints.ts +37 -0
  476. package/src/util/misc/capValue.ts +2 -0
  477. package/src/util/misc/cos.ts +24 -0
  478. package/src/util/misc/dom.ts +50 -0
  479. package/src/util/misc/findScaleTo.ts +44 -0
  480. package/src/util/misc/groupSVGElements.ts +15 -0
  481. package/src/util/misc/isTransparent.ts +28 -0
  482. package/src/util/misc/matrix.ts +207 -0
  483. package/src/util/misc/mergeClipPaths.ts +40 -0
  484. package/src/util/misc/objectEnlive.ts +189 -0
  485. package/src/util/misc/objectTransforms.ts +129 -0
  486. package/src/util/misc/pick.ts +29 -0
  487. package/src/util/misc/planeChange.ts +136 -0
  488. package/src/util/misc/projectStroke/StrokeLineCapProjections.ts +112 -0
  489. package/src/util/misc/projectStroke/StrokeLineJoinProjections.ts +226 -0
  490. package/src/util/misc/projectStroke/StrokeProjectionsBase.ts +75 -0
  491. package/src/util/misc/projectStroke/index.ts +53 -0
  492. package/src/util/misc/projectStroke/types.ts +24 -0
  493. package/src/util/misc/radiansDegreesConversion.ts +18 -0
  494. package/src/util/misc/resolveOrigin.ts +22 -0
  495. package/src/util/misc/rotatePoint.ts +15 -0
  496. package/src/util/misc/sin.ts +26 -0
  497. package/src/util/misc/svgParsing.ts +181 -0
  498. package/src/util/misc/textStyles.ts +134 -0
  499. package/src/util/misc/toFixed.ts +8 -0
  500. package/src/util/misc/vectors.ts +82 -0
  501. package/src/util/path/index.ts +1038 -0
  502. package/src/util/path/regex.ts +41 -0
  503. package/src/util/path/typechecks.ts +145 -0
  504. package/src/util/path/typedefs.ts +305 -0
  505. package/src/util/transform_matrix_removal.ts +60 -0
  506. package/src/util/types.ts +78 -0
  507. package/tsconfig.json +106 -0
  508. package/HEADER.js +0 -203
  509. package/build.js +0 -287
  510. package/dist/fabric.js +0 -31187
  511. package/dist/fabric.min.js +0 -1
  512. package/old-travis-reference.yml +0 -97
  513. package/src/brushes/circle_brush.class.js +0 -144
  514. package/src/brushes/pattern_brush.class.js +0 -61
  515. package/src/brushes/pencil_brush.class.js +0 -310
  516. package/src/brushes/spray_brush.class.js +0 -219
  517. package/src/canvas.class.js +0 -1312
  518. package/src/color.class.js +0 -636
  519. package/src/control.class.js +0 -339
  520. package/src/controls.actions.js +0 -740
  521. package/src/controls.render.js +0 -99
  522. package/src/elements_parser.js +0 -152
  523. package/src/filters/2d_backend.class.js +0 -65
  524. package/src/filters/blendcolor_filter.class.js +0 -251
  525. package/src/filters/blendimage_filter.class.js +0 -247
  526. package/src/filters/blur_filter.class.js +0 -217
  527. package/src/filters/brightness_filter.class.js +0 -113
  528. package/src/filters/colormatrix_filter.class.js +0 -159
  529. package/src/filters/composed_filter.class.js +0 -72
  530. package/src/filters/contrast_filter.class.js +0 -113
  531. package/src/filters/convolute_filter.class.js +0 -352
  532. package/src/filters/filter_boilerplate.js +0 -111
  533. package/src/filters/filter_generator.js +0 -85
  534. package/src/filters/gamma_filter.class.js +0 -136
  535. package/src/filters/grayscale_filter.class.js +0 -154
  536. package/src/filters/hue_rotation.class.js +0 -107
  537. package/src/filters/invert_filter.class.js +0 -111
  538. package/src/filters/noise_filter.class.js +0 -134
  539. package/src/filters/pixelate_filter.class.js +0 -137
  540. package/src/filters/removecolor_filter.class.js +0 -173
  541. package/src/filters/resize_filter.class.js +0 -490
  542. package/src/filters/saturate_filter.class.js +0 -119
  543. package/src/filters/vibrance_filter.class.js +0 -122
  544. package/src/filters/webgl_backend.class.js +0 -396
  545. package/src/globalFabric.js +0 -4
  546. package/src/gradient.class.js +0 -490
  547. package/src/intersection.class.js +0 -172
  548. package/src/log.js +0 -11
  549. package/src/mixins/animation.mixin.js +0 -231
  550. package/src/mixins/canvas_dataurl_exporter.mixin.js +0 -97
  551. package/src/mixins/canvas_events.mixin.js +0 -974
  552. package/src/mixins/canvas_gestures.mixin.js +0 -149
  553. package/src/mixins/canvas_grouping.mixin.js +0 -177
  554. package/src/mixins/canvas_serialization.mixin.js +0 -228
  555. package/src/mixins/collection.mixin.js +0 -170
  556. package/src/mixins/default_controls.js +0 -114
  557. package/src/mixins/itext.svg_export.js +0 -241
  558. package/src/mixins/itext_behavior.mixin.js +0 -940
  559. package/src/mixins/itext_click_behavior.mixin.js +0 -278
  560. package/src/mixins/itext_key_behavior.mixin.js +0 -694
  561. package/src/mixins/object.svg_export.js +0 -258
  562. package/src/mixins/object_geometry.mixin.js +0 -683
  563. package/src/mixins/object_interactivity.mixin.js +0 -314
  564. package/src/mixins/object_origin.mixin.js +0 -255
  565. package/src/mixins/object_stacking.mixin.js +0 -80
  566. package/src/mixins/object_straightening.mixin.js +0 -80
  567. package/src/mixins/observable.mixin.js +0 -141
  568. package/src/mixins/shared_methods.mixin.js +0 -94
  569. package/src/mixins/stateful.mixin.js +0 -107
  570. package/src/mixins/text_style.mixin.js +0 -324
  571. package/src/parser.js +0 -1090
  572. package/src/pattern.class.js +0 -189
  573. package/src/point.class.js +0 -337
  574. package/src/shadow.class.js +0 -195
  575. package/src/shapes/active_selection.class.js +0 -155
  576. package/src/shapes/circle.class.js +0 -210
  577. package/src/shapes/ellipse.class.js +0 -181
  578. package/src/shapes/group.class.js +0 -593
  579. package/src/shapes/image.class.js +0 -764
  580. package/src/shapes/itext.class.js +0 -526
  581. package/src/shapes/line.class.js +0 -324
  582. package/src/shapes/object.class.js +0 -2008
  583. package/src/shapes/path.class.js +0 -384
  584. package/src/shapes/polygon.class.js +0 -81
  585. package/src/shapes/polyline.class.js +0 -268
  586. package/src/shapes/rect.class.js +0 -187
  587. package/src/shapes/text.class.js +0 -1696
  588. package/src/shapes/textbox.class.js +0 -461
  589. package/src/shapes/triangle.class.js +0 -93
  590. package/src/static_canvas.class.js +0 -1881
  591. package/src/util/anim_ease.js +0 -398
  592. package/src/util/animate.js +0 -254
  593. package/src/util/animate_color.js +0 -74
  594. package/src/util/dom_event.js +0 -50
  595. package/src/util/dom_misc.js +0 -300
  596. package/src/util/dom_request.js +0 -54
  597. package/src/util/dom_style.js +0 -70
  598. package/src/util/lang_array.js +0 -94
  599. package/src/util/lang_class.js +0 -115
  600. package/src/util/lang_object.js +0 -75
  601. package/src/util/lang_string.js +0 -110
  602. package/src/util/misc.js +0 -1330
  603. package/src/util/named_accessors.mixin.js +0 -428
  604. package/src/util/path.js +0 -829
@@ -0,0 +1,1607 @@
1
+ import { LEFT_CLICK, MIDDLE_CLICK, RIGHT_CLICK } from '../constants';
2
+ import { getDocument, getWindow } from '../env';
3
+ import {
4
+ CanvasEvents,
5
+ DragEventData,
6
+ ObjectEvents,
7
+ TPointerEvent,
8
+ TPointerEventInfo,
9
+ TPointerEventNames,
10
+ Transform,
11
+ } from '../EventTypeDefs';
12
+ import { Point } from '../Point';
13
+ import { Group } from '../shapes/Group';
14
+ import type { IText } from '../shapes/IText/IText';
15
+ import type { FabricObject } from '../shapes/Object/FabricObject';
16
+ import { AssertKeys } from '../typedefs';
17
+ import { isTouchEvent, stopEvent } from '../util/dom_event';
18
+ import { sendPointToPlane } from '../util/misc/planeChange';
19
+ import {
20
+ isFabricObjectWithDragSupport,
21
+ isInteractiveTextObject,
22
+ } from '../util/types';
23
+ import { SelectableCanvas } from './SelectableCanvas';
24
+ import { TextEditingManager } from './TextEditingManager';
25
+
26
+ const addEventOptions = { passive: false } as EventListenerOptions;
27
+
28
+ function checkClick(e: TPointerEvent, value: number) {
29
+ return !!(e as MouseEvent).button && (e as MouseEvent).button === value - 1;
30
+ }
31
+
32
+ // just to be clear, the utils are now deprecated and those are here exactly as minifier helpers
33
+ // because el.addEventListener can't me be minified while a const yes and we use it 47 times in this file.
34
+ // few bytes but why give it away.
35
+ const addListener = (
36
+ el: HTMLElement | Document,
37
+ ...args: Parameters<HTMLElement['addEventListener']>
38
+ ) => el.addEventListener(...args);
39
+ const removeListener = (
40
+ el: HTMLElement | Document,
41
+ ...args: Parameters<HTMLElement['removeEventListener']>
42
+ ) => el.removeEventListener(...args);
43
+
44
+ const syntheticEventConfig = {
45
+ mouse: {
46
+ in: 'over',
47
+ out: 'out',
48
+ targetIn: 'mouseover',
49
+ targetOut: 'mouseout',
50
+ canvasIn: 'mouse:over',
51
+ canvasOut: 'mouse:out',
52
+ },
53
+ drag: {
54
+ in: 'enter',
55
+ out: 'leave',
56
+ targetIn: 'dragenter',
57
+ targetOut: 'dragleave',
58
+ canvasIn: 'drag:enter',
59
+ canvasOut: 'drag:leave',
60
+ },
61
+ } as const;
62
+
63
+ type TSyntheticEventContext = {
64
+ mouse: { e: TPointerEvent };
65
+ drag: DragEventData;
66
+ };
67
+
68
+ export class Canvas extends SelectableCanvas {
69
+ /**
70
+ * Contains the id of the touch event that owns the fabric transform
71
+ * @type Number
72
+ * @private
73
+ */
74
+ declare mainTouchId: null | number;
75
+
76
+ /**
77
+ * When the option is enabled, PointerEvent is used instead of TPointerEvent.
78
+ * @type Boolean
79
+ * @default
80
+ */
81
+ declare enablePointerEvents: boolean;
82
+
83
+ /**
84
+ * Holds a reference to a setTimeout timer for event synchronization
85
+ * @type number
86
+ * @private
87
+ */
88
+ private declare _willAddMouseDown: number;
89
+
90
+ /**
91
+ * Holds a reference to an object on the canvas that is receiving the drag over event.
92
+ * @type FabricObject
93
+ * @private
94
+ */
95
+ private declare _draggedoverTarget?: FabricObject;
96
+
97
+ /**
98
+ * Holds a reference to an object on the canvas from where the drag operation started
99
+ * @type FabricObject
100
+ * @private
101
+ */
102
+ private declare _dragSource?: FabricObject;
103
+
104
+ /**
105
+ * Holds a reference to an object on the canvas that is the current drop target
106
+ * May differ from {@link _draggedoverTarget}
107
+ * @todo inspect whether {@link _draggedoverTarget} and {@link _dropTarget} should be merged somehow
108
+ * @type FabricObject
109
+ * @private
110
+ */
111
+ private declare _dropTarget: FabricObject<ObjectEvents> | undefined;
112
+
113
+ declare currentTarget?: FabricObject;
114
+
115
+ declare currentSubTargets?: FabricObject[];
116
+
117
+ private _isClick: boolean;
118
+
119
+ textEditingManager = new TextEditingManager();
120
+
121
+ constructor(el: string | HTMLCanvasElement, options = {}) {
122
+ super(el, options);
123
+ // bind event handlers
124
+ (
125
+ [
126
+ '_onMouseDown',
127
+ '_onTouchStart',
128
+ '_onMouseMove',
129
+ '_onMouseUp',
130
+ '_onTouchEnd',
131
+ '_onResize',
132
+ // '_onGesture',
133
+ // '_onDrag',
134
+ // '_onShake',
135
+ // '_onLongPress',
136
+ // '_onOrientationChange',
137
+ '_onMouseWheel',
138
+ '_onMouseOut',
139
+ '_onMouseEnter',
140
+ '_onContextMenu',
141
+ '_onDoubleClick',
142
+ '_onDragStart',
143
+ '_onDragEnd',
144
+ '_onDragProgress',
145
+ '_onDragOver',
146
+ '_onDragEnter',
147
+ '_onDragLeave',
148
+ '_onDrop',
149
+ ] as (keyof this)[]
150
+ ).forEach((eventHandler) => {
151
+ this[eventHandler] = (this[eventHandler] as Function).bind(this);
152
+ });
153
+ // register event handlers
154
+ this.addOrRemove(addListener, 'add');
155
+ }
156
+
157
+ /**
158
+ * return an event prefix pointer or mouse.
159
+ * @private
160
+ */
161
+ private _getEventPrefix() {
162
+ return this.enablePointerEvents ? 'pointer' : 'mouse';
163
+ }
164
+
165
+ addOrRemove(functor: any, eventjsFunctor: 'add' | 'remove') {
166
+ const canvasElement = this.upperCanvasEl,
167
+ eventTypePrefix = this._getEventPrefix();
168
+ functor(getWindow(), 'resize', this._onResize);
169
+ functor(canvasElement, eventTypePrefix + 'down', this._onMouseDown);
170
+ functor(
171
+ canvasElement,
172
+ `${eventTypePrefix}move`,
173
+ this._onMouseMove,
174
+ addEventOptions
175
+ );
176
+ functor(canvasElement, `${eventTypePrefix}out`, this._onMouseOut);
177
+ functor(canvasElement, `${eventTypePrefix}enter`, this._onMouseEnter);
178
+ functor(canvasElement, 'wheel', this._onMouseWheel);
179
+ functor(canvasElement, 'contextmenu', this._onContextMenu);
180
+ functor(canvasElement, 'dblclick', this._onDoubleClick);
181
+ functor(canvasElement, 'dragstart', this._onDragStart);
182
+ functor(canvasElement, 'dragend', this._onDragEnd);
183
+ functor(canvasElement, 'dragover', this._onDragOver);
184
+ functor(canvasElement, 'dragenter', this._onDragEnter);
185
+ functor(canvasElement, 'dragleave', this._onDragLeave);
186
+ functor(canvasElement, 'drop', this._onDrop);
187
+ if (!this.enablePointerEvents) {
188
+ functor(canvasElement, 'touchstart', this._onTouchStart, addEventOptions);
189
+ }
190
+ // if (typeof eventjs !== 'undefined' && eventjsFunctor in eventjs) {
191
+ // eventjs[eventjsFunctor](canvasElement, 'gesture', this._onGesture);
192
+ // eventjs[eventjsFunctor](canvasElement, 'drag', this._onDrag);
193
+ // eventjs[eventjsFunctor](
194
+ // canvasElement,
195
+ // 'orientation',
196
+ // this._onOrientationChange
197
+ // );
198
+ // eventjs[eventjsFunctor](canvasElement, 'shake', this._onShake);
199
+ // eventjs[eventjsFunctor](canvasElement, 'longpress', this._onLongPress);
200
+ // }
201
+ }
202
+
203
+ /**
204
+ * Removes all event listeners
205
+ */
206
+ removeListeners() {
207
+ this.addOrRemove(removeListener, 'remove');
208
+ // if you dispose on a mouseDown, before mouse up, you need to clean document to...
209
+ const eventTypePrefix = this._getEventPrefix();
210
+ removeListener(
211
+ getDocument(),
212
+ `${eventTypePrefix}up`,
213
+ this._onMouseUp as EventListener
214
+ );
215
+ removeListener(
216
+ getDocument(),
217
+ 'touchend',
218
+ this._onTouchEnd as EventListener,
219
+ addEventOptions
220
+ );
221
+ removeListener(
222
+ getDocument(),
223
+ `${eventTypePrefix}move`,
224
+ this._onMouseMove as EventListener,
225
+ addEventOptions
226
+ );
227
+ removeListener(
228
+ getDocument(),
229
+ 'touchmove',
230
+ this._onMouseMove as EventListener,
231
+ addEventOptions
232
+ );
233
+ }
234
+
235
+ /**
236
+ * @private
237
+ * @param {Event} [e] Event object fired on wheel event
238
+ */
239
+ private _onMouseWheel(e: MouseEvent) {
240
+ this.__onMouseWheel(e);
241
+ }
242
+
243
+ /**
244
+ * @private
245
+ * @param {Event} e Event object fired on mousedown
246
+ */
247
+ private _onMouseOut(e: TPointerEvent) {
248
+ const target = this._hoveredTarget;
249
+ const shared = {
250
+ e,
251
+ isClick: false,
252
+ pointer: this.getPointer(e),
253
+ absolutePointer: this.getPointer(e, true),
254
+ };
255
+ this.fire('mouse:out', { ...shared, target });
256
+ this._hoveredTarget = undefined;
257
+ target && target.fire('mouseout', { ...shared });
258
+ this._hoveredTargets.forEach((nestedTarget) => {
259
+ this.fire('mouse:out', { ...shared, target: nestedTarget });
260
+ nestedTarget && nestedTarget.fire('mouseout', { ...shared });
261
+ });
262
+ this._hoveredTargets = [];
263
+ }
264
+
265
+ /**
266
+ * @private
267
+ * @param {Event} e Event object fired on mouseenter
268
+ */
269
+ private _onMouseEnter(e: TPointerEvent) {
270
+ // This find target and consequent 'mouse:over' is used to
271
+ // clear old instances on hovered target.
272
+ // calling findTarget has the side effect of killing target.__corner.
273
+ // as a short term fix we are not firing this if we are currently transforming.
274
+ // as a long term fix we need to separate the action of finding a target with the
275
+ // side effects we added to it.
276
+ if (!this._currentTransform && !this.findTarget(e)) {
277
+ this.fire('mouse:over', {
278
+ e,
279
+ isClick: false,
280
+ pointer: this.getPointer(e),
281
+ absolutePointer: this.getPointer(e, true),
282
+ });
283
+ this._hoveredTarget = undefined;
284
+ this._hoveredTargets = [];
285
+ }
286
+ }
287
+
288
+ /**
289
+ * supports native like text dragging
290
+ * @private
291
+ * @param {DragEvent} e
292
+ */
293
+ private _onDragStart(e: DragEvent) {
294
+ this._isClick = false;
295
+ const activeObject = this.getActiveObject();
296
+ if (
297
+ isFabricObjectWithDragSupport(activeObject) &&
298
+ activeObject.onDragStart(e)
299
+ ) {
300
+ this._dragSource = activeObject;
301
+ const options = { e, target: activeObject };
302
+ this.fire('dragstart', options);
303
+ activeObject.fire('dragstart', options);
304
+ addListener(
305
+ this.upperCanvasEl,
306
+ 'drag',
307
+ this._onDragProgress as EventListener
308
+ );
309
+ return;
310
+ }
311
+ stopEvent(e);
312
+ }
313
+
314
+ /**
315
+ * First we clear top context where the effects are being rendered.
316
+ * Then we render the effects.
317
+ * Doing so will render the correct effect for all cases including an overlap between `source` and `target`.
318
+ * @private
319
+ */
320
+ private _renderDragEffects(
321
+ e: DragEvent,
322
+ source?: FabricObject,
323
+ target?: FabricObject
324
+ ) {
325
+ let dirty = false;
326
+ // clear top context
327
+ const dropTarget = this._dropTarget;
328
+ if (dropTarget && dropTarget !== source && dropTarget !== target) {
329
+ dropTarget.clearContextTop();
330
+ dirty = true;
331
+ }
332
+ source?.clearContextTop();
333
+ target !== source && target?.clearContextTop();
334
+ // render effects
335
+ const ctx = this.contextTop;
336
+ ctx.save();
337
+ ctx.transform(...this.viewportTransform);
338
+ if (source) {
339
+ ctx.save();
340
+ source.transform(ctx);
341
+ (source as AssertKeys<FabricObject, 'canvas'>).renderDragSourceEffect(e);
342
+ ctx.restore();
343
+ dirty = true;
344
+ }
345
+ if (target) {
346
+ ctx.save();
347
+ target.transform(ctx);
348
+ (target as AssertKeys<FabricObject, 'canvas'>).renderDropTargetEffect(e);
349
+ ctx.restore();
350
+ dirty = true;
351
+ }
352
+ ctx.restore();
353
+ dirty && (this.contextTopDirty = true);
354
+ }
355
+
356
+ /**
357
+ * supports native like text dragging
358
+ * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#finishing_a_drag
359
+ * @private
360
+ * @param {DragEvent} e
361
+ */
362
+ private _onDragEnd(e: DragEvent) {
363
+ const didDrop = !!e.dataTransfer && e.dataTransfer.dropEffect !== 'none',
364
+ dropTarget = didDrop ? this._activeObject : undefined,
365
+ options = {
366
+ e,
367
+ target: this._dragSource as FabricObject,
368
+ subTargets: this.targets,
369
+ dragSource: this._dragSource as FabricObject,
370
+ didDrop,
371
+ dropTarget: dropTarget as FabricObject,
372
+ };
373
+ removeListener(
374
+ this.upperCanvasEl,
375
+ 'drag',
376
+ this._onDragProgress as EventListener
377
+ );
378
+ this.fire('dragend', options);
379
+ this._dragSource && this._dragSource.fire('dragend', options);
380
+ delete this._dragSource;
381
+ // we need to call mouse up synthetically because the browser won't
382
+ this._onMouseUp(e);
383
+ }
384
+
385
+ /**
386
+ * fire `drag` event on canvas and drag source
387
+ * @private
388
+ * @param {DragEvent} e
389
+ */
390
+ private _onDragProgress(e: DragEvent) {
391
+ const options = {
392
+ e,
393
+ target: this._dragSource as FabricObject | undefined,
394
+ dragSource: this._dragSource as FabricObject | undefined,
395
+ dropTarget: this._draggedoverTarget as FabricObject,
396
+ };
397
+ this.fire('drag', options);
398
+ this._dragSource && this._dragSource.fire('drag', options);
399
+ }
400
+
401
+ /**
402
+ * As opposed to {@link findTarget} we want the top most object to be returned w/o the active object cutting in line.
403
+ * Override at will
404
+ */
405
+ protected findDragTargets(e: DragEvent) {
406
+ this.targets = [];
407
+ const target = this._searchPossibleTargets(
408
+ this._objects,
409
+ this.getPointer(e, true)
410
+ );
411
+ return {
412
+ target,
413
+ targets: [...this.targets],
414
+ };
415
+ }
416
+
417
+ /**
418
+ * prevent default to allow drop event to be fired
419
+ * https://developer.mozilla.org/en-US/docs/Web/API/HTML_Drag_and_Drop_API/Drag_operations#specifying_drop_targets
420
+ * @private
421
+ * @param {DragEvent} [e] Event object fired on Event.js shake
422
+ */
423
+ private _onDragOver(e: DragEvent) {
424
+ const eventType = 'dragover';
425
+ const { target, targets } = this.findDragTargets(e);
426
+ const dragSource = this._dragSource as FabricObject;
427
+ const options = {
428
+ e,
429
+ target,
430
+ subTargets: targets,
431
+ dragSource,
432
+ canDrop: false,
433
+ dropTarget: undefined,
434
+ };
435
+ let dropTarget;
436
+ // fire on canvas
437
+ this.fire(eventType, options);
438
+ // make sure we fire dragenter events before dragover
439
+ // if dragleave is needed, object will not fire dragover so we don't need to trouble ourselves with it
440
+ this._fireEnterLeaveEvents(target, options);
441
+ if (target) {
442
+ if (target.canDrop(e)) {
443
+ dropTarget = target;
444
+ }
445
+ target.fire(eventType, options);
446
+ }
447
+ // propagate the event to subtargets
448
+ for (let i = 0; i < targets.length; i++) {
449
+ const subTarget = targets[i];
450
+ // accept event only if previous targets didn't (the accepting target calls `preventDefault` to inform that the event is taken)
451
+ // TODO: verify if those should loop in inverse order then?
452
+ // what is the order of subtargets?
453
+ if (subTarget.canDrop(e)) {
454
+ dropTarget = subTarget;
455
+ }
456
+ subTarget.fire(eventType, options);
457
+ }
458
+ // render drag effects now that relations between source and target is clear
459
+ this._renderDragEffects(e, dragSource, dropTarget);
460
+ this._dropTarget = dropTarget;
461
+ }
462
+
463
+ /**
464
+ * fire `dragleave` on `dragover` targets
465
+ * @private
466
+ * @param {Event} [e] Event object fired on Event.js shake
467
+ */
468
+ private _onDragEnter(e: DragEvent) {
469
+ const { target, targets } = this.findDragTargets(e);
470
+ const options = {
471
+ e,
472
+ target,
473
+ subTargets: targets,
474
+ dragSource: this._dragSource,
475
+ };
476
+ this.fire('dragenter', options);
477
+ // fire dragenter on targets
478
+ this._fireEnterLeaveEvents(target, options);
479
+ }
480
+
481
+ /**
482
+ * fire `dragleave` on `dragover` targets
483
+ * @private
484
+ * @param {Event} [e] Event object fired on Event.js shake
485
+ */
486
+ private _onDragLeave(e: DragEvent) {
487
+ const options = {
488
+ e,
489
+ target: this._draggedoverTarget,
490
+ subTargets: this.targets,
491
+ dragSource: this._dragSource,
492
+ };
493
+ this.fire('dragleave', options);
494
+
495
+ // fire dragleave on targets
496
+ this._fireEnterLeaveEvents(undefined, options);
497
+ this._renderDragEffects(e, this._dragSource);
498
+ this._dropTarget = undefined;
499
+ // clear targets
500
+ this.targets = [];
501
+ this._hoveredTargets = [];
502
+ }
503
+
504
+ /**
505
+ * `drop:before` is a an event that allows you to schedule logic
506
+ * before the `drop` event. Prefer `drop` event always, but if you need
507
+ * to run some drop-disabling logic on an event, since there is no way
508
+ * to handle event handlers ordering, use `drop:before`
509
+ * @private
510
+ * @param {Event} e
511
+ */
512
+ private _onDrop(e: DragEvent) {
513
+ const { target, targets } = this.findDragTargets(e);
514
+ const options = this._basicEventHandler('drop:before', {
515
+ e,
516
+ target,
517
+ subTargets: targets,
518
+ dragSource: this._dragSource,
519
+ pointer: this.getPointer(e),
520
+ });
521
+ // will be set by the drop target
522
+ options.didDrop = false;
523
+ // will be set by the drop target, used in case options.target refuses the drop
524
+ options.dropTarget = undefined;
525
+ // fire `drop`
526
+ this._basicEventHandler('drop', options);
527
+ // inform canvas of the drop
528
+ // we do this because canvas was unaware of what happened at the time the `drop` event was fired on it
529
+ // use for side effects
530
+ this.fire('drop:after', options);
531
+ }
532
+
533
+ /**
534
+ * @private
535
+ * @param {Event} e Event object fired on mousedown
536
+ */
537
+ private _onContextMenu(e: TPointerEvent): false {
538
+ const target = this.findTarget(e),
539
+ subTargets = this.targets || [];
540
+ const options = this._basicEventHandler('contextmenu:before', {
541
+ e,
542
+ target,
543
+ subTargets,
544
+ });
545
+ // TODO: this line is silly because the dev can subscribe to the event and prevent it themselves
546
+ this.stopContextMenu && stopEvent(e);
547
+ this._basicEventHandler('contextmenu', options);
548
+ return false;
549
+ }
550
+
551
+ /**
552
+ * @private
553
+ * @param {Event} e Event object fired on mousedown
554
+ */
555
+ private _onDoubleClick(e: TPointerEvent) {
556
+ this._cacheTransformEventData(e);
557
+ this._handleEvent(e, 'dblclick');
558
+ this._resetTransformEventData();
559
+ }
560
+
561
+ /**
562
+ * Return a the id of an event.
563
+ * returns either the pointerId or the identifier or 0 for the mouse event
564
+ * @private
565
+ * @param {Event} evt Event object
566
+ */
567
+ getPointerId(evt: TouchEvent | PointerEvent): number {
568
+ const changedTouches = (evt as TouchEvent).changedTouches;
569
+
570
+ if (changedTouches) {
571
+ return changedTouches[0] && changedTouches[0].identifier;
572
+ }
573
+
574
+ if (this.enablePointerEvents) {
575
+ return (evt as PointerEvent).pointerId;
576
+ }
577
+
578
+ return -1;
579
+ }
580
+
581
+ /**
582
+ * Determines if an event has the id of the event that is considered main
583
+ * @private
584
+ * @param {evt} event Event object
585
+ */
586
+ _isMainEvent(evt: TPointerEvent): boolean {
587
+ if ((evt as PointerEvent).isPrimary === true) {
588
+ return true;
589
+ }
590
+ if ((evt as PointerEvent).isPrimary === false) {
591
+ return false;
592
+ }
593
+ if (evt.type === 'touchend' && (evt as TouchEvent).touches.length === 0) {
594
+ return true;
595
+ }
596
+ if ((evt as TouchEvent).changedTouches) {
597
+ return (
598
+ (evt as TouchEvent).changedTouches[0].identifier === this.mainTouchId
599
+ );
600
+ }
601
+ return true;
602
+ }
603
+
604
+ /**
605
+ * @private
606
+ * @param {Event} e Event object fired on mousedown
607
+ */
608
+ _onTouchStart(e: TouchEvent) {
609
+ e.preventDefault();
610
+ if (this.mainTouchId === null) {
611
+ this.mainTouchId = this.getPointerId(e);
612
+ }
613
+ this.__onMouseDown(e);
614
+ this._resetTransformEventData();
615
+ const canvasElement = this.upperCanvasEl,
616
+ eventTypePrefix = this._getEventPrefix();
617
+ addListener(
618
+ getDocument(),
619
+ 'touchend',
620
+ this._onTouchEnd as EventListener,
621
+ addEventOptions
622
+ );
623
+ addListener(
624
+ getDocument(),
625
+ 'touchmove',
626
+ this._onMouseMove as EventListener,
627
+ addEventOptions
628
+ );
629
+ // Unbind mousedown to prevent double triggers from touch devices
630
+ removeListener(
631
+ canvasElement,
632
+ eventTypePrefix + 'down',
633
+ this._onMouseDown as EventListener
634
+ );
635
+ }
636
+
637
+ /**
638
+ * @private
639
+ * @param {Event} e Event object fired on mousedown
640
+ */
641
+ _onMouseDown(e: TPointerEvent) {
642
+ this.__onMouseDown(e);
643
+ this._resetTransformEventData();
644
+ const canvasElement = this.upperCanvasEl,
645
+ eventTypePrefix = this._getEventPrefix();
646
+ removeListener(
647
+ canvasElement,
648
+ `${eventTypePrefix}move`,
649
+ this._onMouseMove as EventListener,
650
+ addEventOptions
651
+ );
652
+ addListener(
653
+ getDocument(),
654
+ `${eventTypePrefix}up`,
655
+ this._onMouseUp as EventListener
656
+ );
657
+ addListener(
658
+ getDocument(),
659
+ `${eventTypePrefix}move`,
660
+ this._onMouseMove as EventListener,
661
+ addEventOptions
662
+ );
663
+ }
664
+
665
+ /**
666
+ * @private
667
+ * @param {Event} e Event object fired on mousedown
668
+ */
669
+ _onTouchEnd(e: TouchEvent) {
670
+ if (e.touches.length > 0) {
671
+ // if there are still touches stop here
672
+ return;
673
+ }
674
+ this.__onMouseUp(e);
675
+ this._resetTransformEventData();
676
+ this.mainTouchId = null;
677
+ const eventTypePrefix = this._getEventPrefix();
678
+ removeListener(
679
+ getDocument(),
680
+ 'touchend',
681
+ this._onTouchEnd as EventListener,
682
+ addEventOptions
683
+ );
684
+ removeListener(
685
+ getDocument(),
686
+ 'touchmove',
687
+ this._onMouseMove as EventListener,
688
+ addEventOptions
689
+ );
690
+ if (this._willAddMouseDown) {
691
+ clearTimeout(this._willAddMouseDown);
692
+ }
693
+ this._willAddMouseDown = setTimeout(() => {
694
+ // Wait 400ms before rebinding mousedown to prevent double triggers
695
+ // from touch devices
696
+ addListener(
697
+ this.upperCanvasEl,
698
+ eventTypePrefix + 'down',
699
+ this._onMouseDown as EventListener
700
+ );
701
+ this._willAddMouseDown = 0;
702
+ }, 400) as unknown as number;
703
+ }
704
+
705
+ /**
706
+ * @private
707
+ * @param {Event} e Event object fired on mouseup
708
+ */
709
+ _onMouseUp(e: TPointerEvent) {
710
+ this.__onMouseUp(e);
711
+ this._resetTransformEventData();
712
+ const canvasElement = this.upperCanvasEl,
713
+ eventTypePrefix = this._getEventPrefix();
714
+ if (this._isMainEvent(e)) {
715
+ removeListener(
716
+ getDocument(),
717
+ `${eventTypePrefix}up`,
718
+ this._onMouseUp as EventListener
719
+ );
720
+ removeListener(
721
+ getDocument(),
722
+ `${eventTypePrefix}move`,
723
+ this._onMouseMove as EventListener,
724
+ addEventOptions
725
+ );
726
+ addListener(
727
+ canvasElement,
728
+ `${eventTypePrefix}move`,
729
+ this._onMouseMove as EventListener,
730
+ addEventOptions
731
+ );
732
+ }
733
+ }
734
+
735
+ /**
736
+ * @private
737
+ * @param {Event} e Event object fired on mousemove
738
+ */
739
+ _onMouseMove(e: TPointerEvent) {
740
+ const activeObject = this.getActiveObject();
741
+ !this.allowTouchScrolling &&
742
+ (!activeObject ||
743
+ // a drag event sequence is started by the active object flagging itself on mousedown / mousedown:before
744
+ // we must not prevent the event's default behavior in order for the window to start dragging
745
+ (isFabricObjectWithDragSupport(activeObject) &&
746
+ !activeObject.shouldStartDragging())) &&
747
+ e.preventDefault &&
748
+ e.preventDefault();
749
+ this.__onMouseMove(e);
750
+ }
751
+
752
+ /**
753
+ * @private
754
+ */
755
+ _onResize() {
756
+ this.calcOffset();
757
+ this._resetTransformEventData();
758
+ }
759
+
760
+ /**
761
+ * Decides whether the canvas should be redrawn in mouseup and mousedown events.
762
+ * @private
763
+ * @param {Object} target
764
+ */
765
+ _shouldRender(target: FabricObject | undefined) {
766
+ const activeObject = this.getActiveObject();
767
+
768
+ // if just one of them is available or if they are both but are different objects
769
+ if (
770
+ !!activeObject !== !!target ||
771
+ (activeObject && target && activeObject !== target)
772
+ ) {
773
+ // this covers: switch of target, from target to no target, selection of target
774
+ // multiSelection with key and mouse
775
+ return true;
776
+ } else if (isInteractiveTextObject(activeObject)) {
777
+ // if we mouse up/down over a editing textbox a cursor change,
778
+ // there is no need to re render
779
+ return false;
780
+ }
781
+ return false;
782
+ }
783
+
784
+ /**
785
+ * Method that defines the actions when mouse is released on canvas.
786
+ * The method resets the currentTransform parameters, store the image corner
787
+ * position in the image object and render the canvas on top.
788
+ * @private
789
+ * @param {Event} e Event object fired on mouseup
790
+ */
791
+ __onMouseUp(e: TPointerEvent) {
792
+ const transform = this._currentTransform;
793
+ this._cacheTransformEventData(e);
794
+ const target = this._target;
795
+ const isClick = this._isClick;
796
+ this._handleEvent(e, 'up:before');
797
+ // if right/middle click just fire events and return
798
+ // target undefined will make the _handleEvent search the target
799
+ if (checkClick(e, RIGHT_CLICK)) {
800
+ if (this.fireRightClick) {
801
+ this._handleEvent(e, 'up', RIGHT_CLICK, isClick);
802
+ }
803
+ return;
804
+ }
805
+
806
+ if (checkClick(e, MIDDLE_CLICK)) {
807
+ if (this.fireMiddleClick) {
808
+ this._handleEvent(e, 'up', MIDDLE_CLICK, isClick);
809
+ }
810
+ this._resetTransformEventData();
811
+ return;
812
+ }
813
+
814
+ if (this.isDrawingMode && this._isCurrentlyDrawing) {
815
+ this._onMouseUpInDrawingMode(e);
816
+ return;
817
+ }
818
+
819
+ if (!this._isMainEvent(e)) {
820
+ return;
821
+ }
822
+ let shouldRender = false;
823
+ if (transform) {
824
+ this._finalizeCurrentTransform(e);
825
+ shouldRender = transform.actionPerformed;
826
+ }
827
+ if (!isClick) {
828
+ const targetWasActive = target === this._activeObject;
829
+ this.handleSelection(e);
830
+ if (!shouldRender) {
831
+ shouldRender =
832
+ this._shouldRender(target) ||
833
+ (!targetWasActive && target === this._activeObject);
834
+ }
835
+ }
836
+ let pointer, corner;
837
+ if (target) {
838
+ corner = target._findTargetCorner(
839
+ this.getPointer(e, true),
840
+ isTouchEvent(e)
841
+ );
842
+ if (
843
+ target.selectable &&
844
+ target !== this._activeObject &&
845
+ target.activeOn === 'up'
846
+ ) {
847
+ this.setActiveObject(target, e);
848
+ shouldRender = true;
849
+ } else {
850
+ const control = target.controls[corner as string];
851
+ const mouseUpHandler =
852
+ control && control.getMouseUpHandler(e, target, control);
853
+ if (mouseUpHandler) {
854
+ pointer = this.getPointer(e);
855
+ mouseUpHandler(e, transform!, pointer.x, pointer.y);
856
+ }
857
+ }
858
+ target.isMoving = false;
859
+ }
860
+ // if we are ending up a transform on a different control or a new object
861
+ // fire the original mouse up from the corner that started the transform
862
+ if (
863
+ transform &&
864
+ (transform.target !== target || transform.corner !== corner)
865
+ ) {
866
+ const originalControl =
867
+ transform.target && transform.target.controls[transform.corner],
868
+ originalMouseUpHandler =
869
+ originalControl &&
870
+ originalControl.getMouseUpHandler(
871
+ e,
872
+ transform.target,
873
+ originalControl
874
+ );
875
+ pointer = pointer || this.getPointer(e);
876
+ originalMouseUpHandler &&
877
+ originalMouseUpHandler(e, transform, pointer.x, pointer.y);
878
+ }
879
+ this._setCursorFromEvent(e, target);
880
+ this._handleEvent(e, 'up', LEFT_CLICK, isClick);
881
+ this._groupSelector = null;
882
+ this._currentTransform = null;
883
+ // reset the target information about which corner is selected
884
+ target && (target.__corner = undefined);
885
+ if (shouldRender) {
886
+ this.requestRenderAll();
887
+ } else if (
888
+ !isClick &&
889
+ !(
890
+ isInteractiveTextObject(this._activeObject) &&
891
+ this._activeObject.isEditing
892
+ )
893
+ ) {
894
+ this.renderTop();
895
+ }
896
+ }
897
+
898
+ _basicEventHandler<T extends keyof (CanvasEvents | ObjectEvents)>(
899
+ eventType: T,
900
+ options: (CanvasEvents & ObjectEvents)[T]
901
+ ) {
902
+ const { target, subTargets = [] } = options as {
903
+ target?: FabricObject;
904
+ subTargets: FabricObject[];
905
+ };
906
+ this.fire(eventType, options);
907
+ target && target.fire(eventType, options);
908
+ for (let i = 0; i < subTargets.length; i++) {
909
+ subTargets[i].fire(eventType, options);
910
+ }
911
+ return options;
912
+ }
913
+
914
+ /**
915
+ * @private
916
+ * Handle event firing for target and subtargets
917
+ * @param {Event} e event from mouse
918
+ * @param {String} eventType event to fire (up, down or move)
919
+ * @param {fabric.Object} targetObj receiving event
920
+ * @param {Number} [button] button used in the event 1 = left, 2 = middle, 3 = right
921
+ * @param {Boolean} isClick for left button only, indicates that the mouse up happened without move.
922
+ */
923
+ _handleEvent(
924
+ e: TPointerEvent,
925
+ eventType: TPointerEventNames,
926
+ button = LEFT_CLICK,
927
+ isClick = false
928
+ ) {
929
+ const target = this._target,
930
+ targets = this.targets || [],
931
+ options: TPointerEventInfo = {
932
+ e: e,
933
+ target: target,
934
+ subTargets: targets,
935
+ button,
936
+ isClick,
937
+ pointer: this.getPointer(e),
938
+ absolutePointer: this.getPointer(e, true),
939
+ transform: this._currentTransform,
940
+ };
941
+ if (eventType === 'up') {
942
+ options.currentTarget = this.findTarget(e);
943
+ options.currentSubTargets = this.targets;
944
+ }
945
+ this.fire(`mouse:${eventType}`, options);
946
+ // this may be a little be more complicated of what we want to handle
947
+ target && target.fire(`mouse${eventType}`, options);
948
+ for (let i = 0; i < targets.length; i++) {
949
+ targets[i].fire(`mouse${eventType}`, options);
950
+ }
951
+ }
952
+
953
+ /**
954
+ * End the current transform.
955
+ * You don't usually need to call this method unless you are interrupting a user initiated transform
956
+ * because of some other event ( a press of key combination, or something that block the user UX )
957
+ * @param {Event} [e] send the mouse event that generate the finalize down, so it can be used in the event
958
+ */
959
+ endCurrentTransform(e: TPointerEvent) {
960
+ const transform = this._currentTransform;
961
+ this._finalizeCurrentTransform(e);
962
+ if (transform && transform.target) {
963
+ // this could probably go inside _finalizeCurrentTransform
964
+ transform.target.isMoving = false;
965
+ }
966
+ this._currentTransform = null;
967
+ }
968
+
969
+ /**
970
+ * @private
971
+ * @param {Event} e send the mouse event that generate the finalize down, so it can be used in the event
972
+ */
973
+ _finalizeCurrentTransform(e: TPointerEvent) {
974
+ const transform = this._currentTransform!,
975
+ target = transform.target,
976
+ options = {
977
+ e,
978
+ target,
979
+ transform,
980
+ action: transform.action,
981
+ };
982
+
983
+ if (target._scaling) {
984
+ target._scaling = false;
985
+ }
986
+
987
+ target.setCoords();
988
+
989
+ if (transform.actionPerformed) {
990
+ this.fire('object:modified', options);
991
+ target.fire('modified', options);
992
+ }
993
+ }
994
+
995
+ /**
996
+ * @private
997
+ * @param {Event} e Event object fired on mousedown
998
+ */
999
+ _onMouseDownInDrawingMode(e: TPointerEvent) {
1000
+ this._isCurrentlyDrawing = true;
1001
+ if (this.getActiveObject()) {
1002
+ this.discardActiveObject(e);
1003
+ this.requestRenderAll();
1004
+ }
1005
+ const pointer = this.getPointer(e);
1006
+ this.freeDrawingBrush &&
1007
+ this.freeDrawingBrush.onMouseDown(pointer, { e, pointer });
1008
+ this._handleEvent(e, 'down');
1009
+ }
1010
+
1011
+ /**
1012
+ * @private
1013
+ * @param {Event} e Event object fired on mousemove
1014
+ */
1015
+ _onMouseMoveInDrawingMode(e: TPointerEvent) {
1016
+ if (this._isCurrentlyDrawing) {
1017
+ const pointer = this.getPointer(e);
1018
+ this.freeDrawingBrush &&
1019
+ this.freeDrawingBrush.onMouseMove(pointer, {
1020
+ e,
1021
+ pointer,
1022
+ });
1023
+ }
1024
+ this.setCursor(this.freeDrawingCursor);
1025
+ this._handleEvent(e, 'move');
1026
+ }
1027
+
1028
+ /**
1029
+ * @private
1030
+ * @param {Event} e Event object fired on mouseup
1031
+ */
1032
+ _onMouseUpInDrawingMode(e: TPointerEvent) {
1033
+ const pointer = this.getPointer(e);
1034
+ if (this.freeDrawingBrush) {
1035
+ this._isCurrentlyDrawing = !!this.freeDrawingBrush.onMouseUp({
1036
+ e: e,
1037
+ pointer: pointer,
1038
+ });
1039
+ } else {
1040
+ this._isCurrentlyDrawing = false;
1041
+ }
1042
+ this._handleEvent(e, 'up');
1043
+ }
1044
+
1045
+ /**
1046
+ * Method that defines the actions when mouse is clicked on canvas.
1047
+ * The method inits the currentTransform parameters and renders all the
1048
+ * canvas so the current image can be placed on the top canvas and the rest
1049
+ * in on the container one.
1050
+ * @private
1051
+ * @param {Event} e Event object fired on mousedown
1052
+ */
1053
+ __onMouseDown(e: TPointerEvent) {
1054
+ this._isClick = true;
1055
+ this._cacheTransformEventData(e);
1056
+ this._handleEvent(e, 'down:before');
1057
+ let target: FabricObject | undefined = this._target;
1058
+ // if right click just fire events
1059
+ if (checkClick(e, RIGHT_CLICK)) {
1060
+ if (this.fireRightClick) {
1061
+ this._handleEvent(e, 'down', RIGHT_CLICK);
1062
+ }
1063
+ return;
1064
+ }
1065
+
1066
+ if (checkClick(e, MIDDLE_CLICK)) {
1067
+ if (this.fireMiddleClick) {
1068
+ this._handleEvent(e, 'down', MIDDLE_CLICK);
1069
+ }
1070
+ return;
1071
+ }
1072
+
1073
+ if (this.isDrawingMode) {
1074
+ this._onMouseDownInDrawingMode(e);
1075
+ return;
1076
+ }
1077
+
1078
+ if (!this._isMainEvent(e)) {
1079
+ return;
1080
+ }
1081
+
1082
+ // ignore if some object is being transformed at this moment
1083
+ if (this._currentTransform) {
1084
+ return;
1085
+ }
1086
+
1087
+ let shouldRender = this._shouldRender(target);
1088
+ let grouped = false;
1089
+ if (this.handleMultiSelection(e, target)) {
1090
+ // active object might have changed while grouping
1091
+ target = this._activeObject;
1092
+ grouped = true;
1093
+ shouldRender = true;
1094
+ } else if (this._shouldClearSelection(e, target)) {
1095
+ this.discardActiveObject(e);
1096
+ }
1097
+ // we start a group selector rectangle if
1098
+ // selection is enabled
1099
+ // and there is no target, or the following 3 conditions are satisfied:
1100
+ // target is not selectable ( otherwise we selected it )
1101
+ // target is not editing
1102
+ // target is not already selected ( otherwise we drag )
1103
+ if (
1104
+ this.selection &&
1105
+ (!target ||
1106
+ (!target.selectable &&
1107
+ !(target as IText).isEditing &&
1108
+ target !== this._activeObject))
1109
+ ) {
1110
+ const p = this.getPointer(e);
1111
+ this._groupSelector = {
1112
+ x: p.x,
1113
+ y: p.y,
1114
+ deltaY: 0,
1115
+ deltaX: 0,
1116
+ };
1117
+ }
1118
+
1119
+ if (target) {
1120
+ const alreadySelected = target === this._activeObject;
1121
+ if (target.selectable && target.activeOn === 'down') {
1122
+ this.setActiveObject(target, e);
1123
+ }
1124
+ const corner = target._findTargetCorner(
1125
+ this.getPointer(e, true),
1126
+ isTouchEvent(e)
1127
+ );
1128
+ if (target === this._activeObject && (corner || !grouped)) {
1129
+ this._setupCurrentTransform(e, target, alreadySelected);
1130
+ const control = target.controls[corner],
1131
+ pointer = this.getPointer(e),
1132
+ mouseDownHandler =
1133
+ control && control.getMouseDownHandler(e, target, control);
1134
+ if (mouseDownHandler) {
1135
+ mouseDownHandler(e, this._currentTransform!, pointer.x, pointer.y);
1136
+ }
1137
+ }
1138
+ }
1139
+ // we clear `_objectsToRender` in case of a change in order to repopulate it at rendering
1140
+ // run before firing the `down` event to give the dev a chance to populate it themselves
1141
+ shouldRender && (this._objectsToRender = undefined);
1142
+ this._handleEvent(e, 'down');
1143
+ // we must renderAll so that we update the visuals
1144
+ shouldRender && this.requestRenderAll();
1145
+ }
1146
+
1147
+ /**
1148
+ * reset cache form common information needed during event processing
1149
+ * @private
1150
+ */
1151
+ _resetTransformEventData() {
1152
+ this._target = undefined;
1153
+ this._pointer = undefined;
1154
+ this._absolutePointer = undefined;
1155
+ }
1156
+
1157
+ /**
1158
+ * Cache common information needed during event processing
1159
+ * @private
1160
+ * @param {Event} e Event object fired on event
1161
+ */
1162
+ _cacheTransformEventData(e: TPointerEvent) {
1163
+ // reset in order to avoid stale caching
1164
+ this._resetTransformEventData();
1165
+ this._pointer = this.getPointer(e, true);
1166
+ this._absolutePointer = this.restorePointerVpt(this._pointer);
1167
+ this._target = this._currentTransform
1168
+ ? this._currentTransform.target
1169
+ : this.findTarget(e);
1170
+ }
1171
+
1172
+ /**
1173
+ * @private
1174
+ */
1175
+ _beforeTransform(e: TPointerEvent) {
1176
+ const t = this._currentTransform!;
1177
+ this.fire('before:transform', {
1178
+ e,
1179
+ transform: t,
1180
+ });
1181
+ }
1182
+
1183
+ /**
1184
+ * Method that defines the actions when mouse is hovering the canvas.
1185
+ * The currentTransform parameter will define whether the user is rotating/scaling/translating
1186
+ * an image or neither of them (only hovering). A group selection is also possible and would cancel
1187
+ * all any other type of action.
1188
+ * In case of an image transformation only the top canvas will be rendered.
1189
+ * @private
1190
+ * @param {Event} e Event object fired on mousemove
1191
+ */
1192
+ __onMouseMove(e: TPointerEvent) {
1193
+ this._isClick = false;
1194
+ this._handleEvent(e, 'move:before');
1195
+ this._cacheTransformEventData(e);
1196
+
1197
+ if (this.isDrawingMode) {
1198
+ this._onMouseMoveInDrawingMode(e);
1199
+ return;
1200
+ }
1201
+
1202
+ if (!this._isMainEvent(e)) {
1203
+ return;
1204
+ }
1205
+
1206
+ const groupSelector = this._groupSelector;
1207
+
1208
+ // We initially clicked in an empty area, so we draw a box for multiple selection
1209
+ if (groupSelector) {
1210
+ const pointer = this.getPointer(e);
1211
+
1212
+ groupSelector.deltaX = pointer.x - groupSelector.x;
1213
+ groupSelector.deltaY = pointer.y - groupSelector.y;
1214
+
1215
+ this.renderTop();
1216
+ } else if (!this._currentTransform) {
1217
+ const target = this.findTarget(e);
1218
+ this._setCursorFromEvent(e, target);
1219
+ this._fireOverOutEvents(e, target);
1220
+ } else {
1221
+ this._transformObject(e);
1222
+ }
1223
+ this.textEditingManager.onMouseMove(e);
1224
+ this._handleEvent(e, 'move');
1225
+ this._resetTransformEventData();
1226
+ }
1227
+
1228
+ /**
1229
+ * Manage the mouseout, mouseover events for the fabric object on the canvas
1230
+ * @param {Fabric.Object} target the target where the target from the mousemove event
1231
+ * @param {Event} e Event object fired on mousemove
1232
+ * @private
1233
+ */
1234
+ _fireOverOutEvents(e: TPointerEvent, target?: FabricObject) {
1235
+ const _hoveredTarget = this._hoveredTarget,
1236
+ _hoveredTargets = this._hoveredTargets,
1237
+ targets = this.targets,
1238
+ length = Math.max(_hoveredTargets.length, targets.length);
1239
+
1240
+ this.fireSyntheticInOutEvents('mouse', {
1241
+ e,
1242
+ target,
1243
+ oldTarget: _hoveredTarget,
1244
+ fireCanvas: true,
1245
+ });
1246
+ for (let i = 0; i < length; i++) {
1247
+ this.fireSyntheticInOutEvents('mouse', {
1248
+ e,
1249
+ target: targets[i],
1250
+ oldTarget: _hoveredTargets[i],
1251
+ });
1252
+ }
1253
+ this._hoveredTarget = target;
1254
+ this._hoveredTargets = this.targets.concat();
1255
+ }
1256
+
1257
+ /**
1258
+ * Manage the dragEnter, dragLeave events for the fabric objects on the canvas
1259
+ * @param {Fabric.Object} target the target where the target from the onDrag event
1260
+ * @param {Object} data Event object fired on dragover
1261
+ * @private
1262
+ */
1263
+ _fireEnterLeaveEvents(target: FabricObject | undefined, data: DragEventData) {
1264
+ const draggedoverTarget = this._draggedoverTarget,
1265
+ _hoveredTargets = this._hoveredTargets,
1266
+ targets = this.targets,
1267
+ length = Math.max(_hoveredTargets.length, targets.length);
1268
+
1269
+ this.fireSyntheticInOutEvents('drag', {
1270
+ ...data,
1271
+ target,
1272
+ oldTarget: draggedoverTarget,
1273
+ fireCanvas: true,
1274
+ });
1275
+ for (let i = 0; i < length; i++) {
1276
+ this.fireSyntheticInOutEvents('drag', {
1277
+ ...data,
1278
+ target: targets[i],
1279
+ oldTarget: _hoveredTargets[i],
1280
+ });
1281
+ }
1282
+ this._draggedoverTarget = target;
1283
+ }
1284
+
1285
+ /**
1286
+ * Manage the synthetic in/out events for the fabric objects on the canvas
1287
+ * @param {Fabric.Object} target the target where the target from the supported events
1288
+ * @param {Object} data Event object fired
1289
+ * @param {Object} config configuration for the function to work
1290
+ * @param {String} config.targetName property on the canvas where the old target is stored
1291
+ * @param {String} [config.canvasEvtOut] name of the event to fire at canvas level for out
1292
+ * @param {String} config.evtOut name of the event to fire for out
1293
+ * @param {String} [config.canvasEvtIn] name of the event to fire at canvas level for in
1294
+ * @param {String} config.evtIn name of the event to fire for in
1295
+ * @private
1296
+ */
1297
+ fireSyntheticInOutEvents<T extends keyof TSyntheticEventContext>(
1298
+ type: T,
1299
+ {
1300
+ target,
1301
+ oldTarget,
1302
+ fireCanvas,
1303
+ e,
1304
+ ...data
1305
+ }: TSyntheticEventContext[T] & {
1306
+ target?: FabricObject;
1307
+ oldTarget?: FabricObject;
1308
+ fireCanvas?: boolean;
1309
+ }
1310
+ ) {
1311
+ const { targetIn, targetOut, canvasIn, canvasOut } =
1312
+ syntheticEventConfig[type];
1313
+ const targetChanged = oldTarget !== target;
1314
+
1315
+ if (oldTarget && targetChanged) {
1316
+ const outOpt = {
1317
+ ...data,
1318
+ e,
1319
+ target: oldTarget,
1320
+ nextTarget: target,
1321
+ isClick: false,
1322
+ pointer: this.getPointer(e),
1323
+ absolutePointer: this.getPointer(e, true),
1324
+ };
1325
+ fireCanvas && this.fire(canvasIn, outOpt);
1326
+ oldTarget.fire(targetOut, outOpt);
1327
+ }
1328
+ if (target && targetChanged) {
1329
+ const inOpt: TPointerEventInfo = {
1330
+ ...data,
1331
+ e,
1332
+ target,
1333
+ previousTarget: oldTarget,
1334
+ isClick: false,
1335
+ pointer: this.getPointer(e),
1336
+ absolutePointer: this.getPointer(e, true),
1337
+ };
1338
+ fireCanvas && this.fire(canvasOut, inOpt);
1339
+ target.fire(targetIn, inOpt);
1340
+ }
1341
+ }
1342
+
1343
+ /**
1344
+ * Method that defines actions when an Event Mouse Wheel
1345
+ * @param {Event} e Event object fired on mouseup
1346
+ */
1347
+ __onMouseWheel(e: TPointerEvent) {
1348
+ this._cacheTransformEventData(e);
1349
+ this._handleEvent(e, 'wheel');
1350
+ this._resetTransformEventData();
1351
+ }
1352
+
1353
+ /**
1354
+ * @private
1355
+ * @param {Event} e Event fired on mousemove
1356
+ */
1357
+ _transformObject(e: TPointerEvent) {
1358
+ const pointer = this.getPointer(e),
1359
+ transform = this._currentTransform!,
1360
+ target = transform.target,
1361
+ // transform pointer to target's containing coordinate plane
1362
+ // both pointer and object should agree on every point
1363
+ localPointer = target.group
1364
+ ? sendPointToPlane(
1365
+ pointer,
1366
+ undefined,
1367
+ target.group.calcTransformMatrix()
1368
+ )
1369
+ : pointer;
1370
+ // seems used only here.
1371
+ // @TODO: investigate;
1372
+ transform.reset = false;
1373
+ transform.shiftKey = e.shiftKey;
1374
+ transform.altKey = !!this.centeredKey && e[this.centeredKey];
1375
+
1376
+ this._performTransformAction(e, transform, localPointer);
1377
+ transform.actionPerformed && this.requestRenderAll();
1378
+ }
1379
+
1380
+ /**
1381
+ * @private
1382
+ */
1383
+ _performTransformAction(
1384
+ e: TPointerEvent,
1385
+ transform: Transform,
1386
+ pointer: Point
1387
+ ) {
1388
+ const x = pointer.x,
1389
+ y = pointer.y,
1390
+ action = transform.action,
1391
+ actionHandler = transform.actionHandler;
1392
+ let actionPerformed = false;
1393
+ // this object could be created from the function in the control handlers
1394
+
1395
+ if (actionHandler) {
1396
+ actionPerformed = actionHandler(e, transform, x, y);
1397
+ }
1398
+ if (action === 'drag' && actionPerformed) {
1399
+ transform.target.isMoving = true;
1400
+ this.setCursor(transform.target.moveCursor || this.moveCursor);
1401
+ }
1402
+ transform.actionPerformed = transform.actionPerformed || actionPerformed;
1403
+ }
1404
+
1405
+ /**
1406
+ * Sets the cursor depending on where the canvas is being hovered.
1407
+ * Note: very buggy in Opera
1408
+ * @param {Event} e Event object
1409
+ * @param {Object} target Object that the mouse is hovering, if so.
1410
+ */
1411
+ _setCursorFromEvent(e: TPointerEvent, target?: FabricObject) {
1412
+ if (!target) {
1413
+ this.setCursor(this.defaultCursor);
1414
+ return;
1415
+ }
1416
+ let hoverCursor = target.hoverCursor || this.hoverCursor;
1417
+ const activeSelection =
1418
+ this._activeObject === this._activeSelection
1419
+ ? this._activeObject
1420
+ : null,
1421
+ // only show proper corner when group selection is not active
1422
+ corner =
1423
+ (!activeSelection || target.group !== activeSelection) &&
1424
+ // here we call findTargetCorner always with undefined for the touch parameter.
1425
+ // we assume that if you are using a cursor you do not need to interact with
1426
+ // the bigger touch area.
1427
+ target._findTargetCorner(this.getPointer(e, true));
1428
+
1429
+ if (!corner) {
1430
+ if ((target as Group).subTargetCheck) {
1431
+ // hoverCursor should come from top-most subTarget,
1432
+ // so we walk the array backwards
1433
+ this.targets
1434
+ .concat()
1435
+ .reverse()
1436
+ .map((_target) => {
1437
+ hoverCursor = _target.hoverCursor || hoverCursor;
1438
+ });
1439
+ }
1440
+ this.setCursor(hoverCursor);
1441
+ } else {
1442
+ const control = target.controls[corner];
1443
+ this.setCursor(control.cursorStyleHandler(e, control, target));
1444
+ }
1445
+ }
1446
+
1447
+ /**
1448
+ * ## Handles multiple selection
1449
+ * - toggles `target` selection (selects/deselects `target` if it isn't/is selected respectively)
1450
+ * - sets the active object in case it is not set or in case there is a single active object left under active selection.
1451
+ * ---
1452
+ * - If the active object is the active selection we add/remove `target` from it
1453
+ * - If not, add the active object and `target` to the active selection and make it the active object.
1454
+ * @private
1455
+ * @param {TPointerEvent} e Event object
1456
+ * @param {FabricObject} target target of event to select/deselect
1457
+ * @returns true if grouping occurred
1458
+ */
1459
+ protected handleMultiSelection(
1460
+ e: TPointerEvent,
1461
+ target?: FabricObject
1462
+ ): this is AssertKeys<this, '_activeObject'> {
1463
+ const activeObject = this._activeObject;
1464
+ const activeSelection = this._activeSelection;
1465
+ const isAS = activeObject === activeSelection;
1466
+ if (
1467
+ // check if an active object exists on canvas and if the user is pressing the `selectionKey` while canvas supports multi selection.
1468
+ !!activeObject &&
1469
+ this._isSelectionKeyPressed(e) &&
1470
+ this.selection &&
1471
+ // on top of that the user also has to hit a target that is selectable.
1472
+ !!target &&
1473
+ target.selectable &&
1474
+ // group target and active object only if they are different objects
1475
+ // else we try to find a subtarget of `ActiveSelection`
1476
+ (activeObject !== target || isAS) &&
1477
+ // make sure `activeObject` and `target` aren't ancestors of each other in case `activeObject` is not `ActiveSelection`
1478
+ // if it is then we want to remove `target` from it
1479
+ (isAS ||
1480
+ (!target.isDescendantOf(activeObject) &&
1481
+ !activeObject.isDescendantOf(target))) &&
1482
+ // target accepts selection
1483
+ !target.onSelect({ e }) &&
1484
+ // make sure we are not on top of a control
1485
+ !activeObject.__corner
1486
+ ) {
1487
+ if (isAS) {
1488
+ const prevActiveObjects =
1489
+ activeSelection.getObjects() as FabricObject[];
1490
+ if (target === activeSelection) {
1491
+ // find target from active objects
1492
+ target = this.searchPossibleTargets(
1493
+ prevActiveObjects,
1494
+ this.getPointer(e, true)
1495
+ );
1496
+ // if nothing is found bail out
1497
+ if (!target || !target.selectable) {
1498
+ return false;
1499
+ }
1500
+ }
1501
+ if (target.group === activeSelection) {
1502
+ // `target` is part of active selection => remove it
1503
+ activeSelection.remove(target);
1504
+ this._hoveredTarget = target;
1505
+ this._hoveredTargets = [...this.targets];
1506
+ if (activeSelection.size() === 1) {
1507
+ // activate last remaining object
1508
+ this._setActiveObject(activeSelection.item(0) as FabricObject, e);
1509
+ }
1510
+ } else {
1511
+ // `target` isn't part of active selection => add it
1512
+ activeSelection.multiSelectAdd(target);
1513
+ this._hoveredTarget = activeSelection;
1514
+ this._hoveredTargets = [...this.targets];
1515
+ }
1516
+ this._fireSelectionEvents(prevActiveObjects, e);
1517
+ } else {
1518
+ isInteractiveTextObject(activeObject) && activeObject.exitEditing();
1519
+ // add the active object and the target to the active selection and set it as the active object
1520
+ activeSelection.multiSelectAdd(activeObject, target);
1521
+ this._hoveredTarget = activeSelection;
1522
+ // ISSUE 4115: should we consider subTargets here?
1523
+ // this._hoveredTargets = [];
1524
+ // this._hoveredTargets = this.targets.concat();
1525
+ this._setActiveObject(activeSelection, e);
1526
+ this._fireSelectionEvents([activeObject], e);
1527
+ }
1528
+ return true;
1529
+ }
1530
+ return false;
1531
+ }
1532
+
1533
+ /**
1534
+ * ## Handles selection
1535
+ * - selects objects that are contained in (and possibly intersecting) the selection bounding box
1536
+ * - sets the active object
1537
+ * ---
1538
+ * runs on mouse up
1539
+ */
1540
+ protected handleSelection(
1541
+ e: TPointerEvent
1542
+ ): this is AssertKeys<this, '_activeObject'> {
1543
+ if (!this.selection || !this._groupSelector) {
1544
+ return false;
1545
+ }
1546
+ const { x, y, deltaX, deltaY } = this._groupSelector,
1547
+ point1 = new Point(x, y),
1548
+ point2 = point1.add(new Point(deltaX, deltaY)),
1549
+ tl = point1.min(point2),
1550
+ br = point1.max(point2),
1551
+ size = br.subtract(tl),
1552
+ isClick = point1.eq(point2);
1553
+
1554
+ const collectedObjects = this.collectObjects(
1555
+ {
1556
+ left: tl.x,
1557
+ top: tl.y,
1558
+ width: size.x,
1559
+ height: size.y,
1560
+ },
1561
+ { includeIntersecting: !this.selectionFullyContained }
1562
+ ) as FabricObject[];
1563
+
1564
+ const objects = isClick
1565
+ ? collectedObjects[0]
1566
+ ? [collectedObjects[0]]
1567
+ : []
1568
+ : collectedObjects.length > 1
1569
+ ? collectedObjects.filter((object) => !object.onSelect({ e })).reverse()
1570
+ : collectedObjects;
1571
+
1572
+ // set active object
1573
+ if (objects.length === 1) {
1574
+ // set as active object
1575
+ this.setActiveObject(objects[0], e);
1576
+ } else if (objects.length > 1) {
1577
+ // add to active selection and make it the active object
1578
+ this._activeSelection.add(...objects);
1579
+ this.setActiveObject(this._activeSelection, e);
1580
+ }
1581
+
1582
+ // cleanup
1583
+ this._groupSelector = null;
1584
+ return true;
1585
+ }
1586
+
1587
+ exitTextEditing() {
1588
+ this.textEditingManager.exitTextEditing();
1589
+ }
1590
+
1591
+ /**
1592
+ * @override clear {@link textEditingManager}
1593
+ */
1594
+ clear() {
1595
+ this.textEditingManager.dispose();
1596
+ super.clear();
1597
+ }
1598
+
1599
+ /**
1600
+ * @override clear {@link textEditingManager}
1601
+ */
1602
+ destroy() {
1603
+ this.removeListeners();
1604
+ super.destroy();
1605
+ this.textEditingManager.dispose();
1606
+ }
1607
+ }