fabric 7.0.0 → 7.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 (323) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/CHANGELOG.md +21 -0
  3. package/dist/extensions/cropping_controls/croppingControls.d.ts +16 -0
  4. package/dist/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
  5. package/dist/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
  6. package/dist/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
  7. package/dist/extensions/cropping_controls/enterCropMode.d.ts +7 -0
  8. package/dist/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
  9. package/dist/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
  10. package/dist/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
  11. package/dist/extensions/index.d.ts +3 -0
  12. package/dist/extensions/index.d.ts.map +1 -1
  13. package/dist/fabric.d.ts +1 -0
  14. package/dist/fabric.d.ts.map +1 -1
  15. package/dist/index.js +628 -537
  16. package/dist/index.js.map +1 -1
  17. package/dist/index.min.js +1 -1
  18. package/dist/index.min.js.map +1 -1
  19. package/dist/index.min.mjs +1 -1
  20. package/dist/index.min.mjs.map +1 -1
  21. package/dist/index.mjs +628 -537
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/index.node.cjs +628 -537
  24. package/dist/index.node.cjs.map +1 -1
  25. package/dist/index.node.mjs +628 -537
  26. package/dist/index.node.mjs.map +1 -1
  27. package/dist/package.json.min.mjs +1 -1
  28. package/dist/package.json.mjs +1 -1
  29. package/dist/src/EventTypeDefs.d.ts +5 -0
  30. package/dist/src/EventTypeDefs.d.ts.map +1 -1
  31. package/dist/src/Pattern/Pattern.d.ts.map +1 -1
  32. package/dist/src/Pattern/Pattern.min.mjs +1 -1
  33. package/dist/src/Pattern/Pattern.min.mjs.map +1 -1
  34. package/dist/src/Pattern/Pattern.mjs +2 -1
  35. package/dist/src/Pattern/Pattern.mjs.map +1 -1
  36. package/dist/src/Shadow.d.ts +1 -1
  37. package/dist/src/Shadow.d.ts.map +1 -1
  38. package/dist/src/Shadow.min.mjs +1 -1
  39. package/dist/src/Shadow.min.mjs.map +1 -1
  40. package/dist/src/Shadow.mjs +5 -4
  41. package/dist/src/Shadow.mjs.map +1 -1
  42. package/dist/src/canvas/CanvasOptions.d.ts.map +1 -1
  43. package/dist/src/canvas/CanvasOptions.min.mjs.map +1 -1
  44. package/dist/src/canvas/CanvasOptions.mjs.map +1 -1
  45. package/dist/src/canvas/SelectableCanvas.d.ts +2 -0
  46. package/dist/src/canvas/SelectableCanvas.d.ts.map +1 -1
  47. package/dist/src/canvas/SelectableCanvas.min.mjs +1 -1
  48. package/dist/src/canvas/SelectableCanvas.min.mjs.map +1 -1
  49. package/dist/src/canvas/SelectableCanvas.mjs +33 -13
  50. package/dist/src/canvas/SelectableCanvas.mjs.map +1 -1
  51. package/dist/src/canvas/StaticCanvas.d.ts.map +1 -1
  52. package/dist/src/canvas/StaticCanvas.min.mjs +1 -1
  53. package/dist/src/canvas/StaticCanvas.min.mjs.map +1 -1
  54. package/dist/src/canvas/StaticCanvas.mjs +3 -1
  55. package/dist/src/canvas/StaticCanvas.mjs.map +1 -1
  56. package/dist/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
  57. package/dist/src/canvas/StaticCanvasOptions.min.mjs.map +1 -1
  58. package/dist/src/canvas/StaticCanvasOptions.mjs.map +1 -1
  59. package/dist/src/constants.d.ts +1 -0
  60. package/dist/src/constants.d.ts.map +1 -1
  61. package/dist/src/constants.min.mjs.map +1 -1
  62. package/dist/src/constants.mjs.map +1 -1
  63. package/dist/src/controls/Control.d.ts +22 -1
  64. package/dist/src/controls/Control.d.ts.map +1 -1
  65. package/dist/src/controls/Control.min.mjs +1 -1
  66. package/dist/src/controls/Control.min.mjs.map +1 -1
  67. package/dist/src/controls/Control.mjs +45 -1
  68. package/dist/src/controls/Control.mjs.map +1 -1
  69. package/dist/src/controls/changeWidth.d.ts +22 -0
  70. package/dist/src/controls/changeWidth.d.ts.map +1 -1
  71. package/dist/src/controls/changeWidth.min.mjs +1 -1
  72. package/dist/src/controls/changeWidth.min.mjs.map +1 -1
  73. package/dist/src/controls/changeWidth.mjs +46 -18
  74. package/dist/src/controls/changeWidth.mjs.map +1 -1
  75. package/dist/src/controls/controlRendering.d.ts.map +1 -1
  76. package/dist/src/controls/controlRendering.min.mjs +1 -1
  77. package/dist/src/controls/controlRendering.min.mjs.map +1 -1
  78. package/dist/src/controls/controlRendering.mjs +18 -34
  79. package/dist/src/controls/controlRendering.mjs.map +1 -1
  80. package/dist/src/controls/index.d.ts +2 -1
  81. package/dist/src/controls/index.d.ts.map +1 -1
  82. package/dist/src/controls/index.min.mjs +1 -1
  83. package/dist/src/controls/index.mjs +1 -1
  84. package/dist/src/gradient/Gradient.d.ts.map +1 -1
  85. package/dist/src/gradient/Gradient.min.mjs +1 -1
  86. package/dist/src/gradient/Gradient.min.mjs.map +1 -1
  87. package/dist/src/gradient/Gradient.mjs +19 -6
  88. package/dist/src/gradient/Gradient.mjs.map +1 -1
  89. package/dist/src/shapes/Circle.d.ts.map +1 -1
  90. package/dist/src/shapes/Circle.min.mjs +1 -1
  91. package/dist/src/shapes/Circle.min.mjs.map +1 -1
  92. package/dist/src/shapes/Circle.mjs +10 -7
  93. package/dist/src/shapes/Circle.mjs.map +1 -1
  94. package/dist/src/shapes/Ellipse.d.ts.map +1 -1
  95. package/dist/src/shapes/Ellipse.min.mjs +1 -1
  96. package/dist/src/shapes/Ellipse.min.mjs.map +1 -1
  97. package/dist/src/shapes/Ellipse.mjs +2 -1
  98. package/dist/src/shapes/Ellipse.mjs.map +1 -1
  99. package/dist/src/shapes/Group.d.ts.map +1 -1
  100. package/dist/src/shapes/Group.min.mjs +1 -1
  101. package/dist/src/shapes/Group.min.mjs.map +1 -1
  102. package/dist/src/shapes/Group.mjs +2 -1
  103. package/dist/src/shapes/Group.mjs.map +1 -1
  104. package/dist/src/shapes/IText/IText.d.ts.map +1 -1
  105. package/dist/src/shapes/IText/IText.min.mjs.map +1 -1
  106. package/dist/src/shapes/IText/IText.mjs.map +1 -1
  107. package/dist/src/shapes/Image.d.ts +1 -1
  108. package/dist/src/shapes/Image.d.ts.map +1 -1
  109. package/dist/src/shapes/Image.min.mjs +1 -1
  110. package/dist/src/shapes/Image.min.mjs.map +1 -1
  111. package/dist/src/shapes/Image.mjs +4 -3
  112. package/dist/src/shapes/Image.mjs.map +1 -1
  113. package/dist/src/shapes/Line.d.ts.map +1 -1
  114. package/dist/src/shapes/Line.min.mjs +1 -1
  115. package/dist/src/shapes/Line.min.mjs.map +1 -1
  116. package/dist/src/shapes/Line.mjs +6 -10
  117. package/dist/src/shapes/Line.mjs.map +1 -1
  118. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
  119. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs +1 -1
  120. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.min.mjs.map +1 -1
  121. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs +5 -4
  122. package/dist/src/shapes/Object/FabricObjectSVGExportMixin.mjs.map +1 -1
  123. package/dist/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
  124. package/dist/src/shapes/Object/InteractiveObject.min.mjs.map +1 -1
  125. package/dist/src/shapes/Object/InteractiveObject.mjs.map +1 -1
  126. package/dist/src/shapes/Object/Object.d.ts.map +1 -1
  127. package/dist/src/shapes/Object/Object.min.mjs +1 -1
  128. package/dist/src/shapes/Object/Object.min.mjs.map +1 -1
  129. package/dist/src/shapes/Object/Object.mjs +3 -0
  130. package/dist/src/shapes/Object/Object.mjs.map +1 -1
  131. package/dist/src/shapes/Object/ObjectGeometry.min.mjs +1 -1
  132. package/dist/src/shapes/Object/ObjectGeometry.min.mjs.map +1 -1
  133. package/dist/src/shapes/Object/ObjectGeometry.mjs +1 -1
  134. package/dist/src/shapes/Object/ObjectGeometry.mjs.map +1 -1
  135. package/dist/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
  136. package/dist/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
  137. package/dist/src/shapes/Path.d.ts.map +1 -1
  138. package/dist/src/shapes/Path.min.mjs.map +1 -1
  139. package/dist/src/shapes/Path.mjs +1 -2
  140. package/dist/src/shapes/Path.mjs.map +1 -1
  141. package/dist/src/shapes/Polyline.d.ts.map +1 -1
  142. package/dist/src/shapes/Polyline.min.mjs +1 -1
  143. package/dist/src/shapes/Polyline.min.mjs.map +1 -1
  144. package/dist/src/shapes/Polyline.mjs +10 -6
  145. package/dist/src/shapes/Polyline.mjs.map +1 -1
  146. package/dist/src/shapes/Rect.d.ts.map +1 -1
  147. package/dist/src/shapes/Rect.min.mjs +1 -1
  148. package/dist/src/shapes/Rect.min.mjs.map +1 -1
  149. package/dist/src/shapes/Rect.mjs +2 -1
  150. package/dist/src/shapes/Rect.mjs.map +1 -1
  151. package/dist/src/shapes/Text/StyledText.d.ts.map +1 -1
  152. package/dist/src/shapes/Text/StyledText.min.mjs.map +1 -1
  153. package/dist/src/shapes/Text/StyledText.mjs +0 -3
  154. package/dist/src/shapes/Text/StyledText.mjs.map +1 -1
  155. package/dist/src/shapes/Text/Text.d.ts.map +1 -1
  156. package/dist/src/shapes/Text/Text.min.mjs.map +1 -1
  157. package/dist/src/shapes/Text/Text.mjs.map +1 -1
  158. package/dist/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
  159. package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs +1 -1
  160. package/dist/src/shapes/Text/TextSVGExportMixin.min.mjs.map +1 -1
  161. package/dist/src/shapes/Text/TextSVGExportMixin.mjs +5 -6
  162. package/dist/src/shapes/Text/TextSVGExportMixin.mjs.map +1 -1
  163. package/dist/src/shapes/Textbox.d.ts.map +1 -1
  164. package/dist/src/shapes/Textbox.min.mjs.map +1 -1
  165. package/dist/src/shapes/Textbox.mjs.map +1 -1
  166. package/dist/src/shapes/Triangle.d.ts.map +1 -1
  167. package/dist/src/shapes/Triangle.min.mjs.map +1 -1
  168. package/dist/src/shapes/Triangle.mjs.map +1 -1
  169. package/dist/src/util/lang_string.d.ts +1 -1
  170. package/dist/src/util/lang_string.d.ts.map +1 -1
  171. package/dist/src/util/lang_string.min.mjs +1 -1
  172. package/dist/src/util/lang_string.min.mjs.map +1 -1
  173. package/dist/src/util/lang_string.mjs +1 -1
  174. package/dist/src/util/lang_string.mjs.map +1 -1
  175. package/dist/src/util/misc/svgParsing.d.ts.map +1 -1
  176. package/dist/src/util/misc/svgParsing.min.mjs +1 -1
  177. package/dist/src/util/misc/svgParsing.min.mjs.map +1 -1
  178. package/dist/src/util/misc/svgParsing.mjs +2 -1
  179. package/dist/src/util/misc/svgParsing.mjs.map +1 -1
  180. package/dist-extensions/cropping_controls/croppingControls.mjs +140 -0
  181. package/dist-extensions/cropping_controls/croppingControls.mjs.map +1 -0
  182. package/dist-extensions/cropping_controls/croppingHandlers.mjs +228 -0
  183. package/dist-extensions/cropping_controls/croppingHandlers.mjs.map +1 -0
  184. package/dist-extensions/cropping_controls/enterCropMode.mjs +38 -0
  185. package/dist-extensions/cropping_controls/enterCropMode.mjs.map +1 -0
  186. package/dist-extensions/cropping_controls/renderCornerControl.mjs +45 -0
  187. package/dist-extensions/cropping_controls/renderCornerControl.mjs.map +1 -0
  188. package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts +16 -0
  189. package/dist-extensions/extensions/cropping_controls/croppingControls.d.ts.map +1 -0
  190. package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts +39 -0
  191. package/dist-extensions/extensions/cropping_controls/croppingHandlers.d.ts.map +1 -0
  192. package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts +7 -0
  193. package/dist-extensions/extensions/cropping_controls/enterCropMode.d.ts.map +1 -0
  194. package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts +14 -0
  195. package/dist-extensions/extensions/cropping_controls/renderCornerControl.d.ts.map +1 -0
  196. package/dist-extensions/extensions/index.d.ts +3 -0
  197. package/dist-extensions/extensions/index.d.ts.map +1 -1
  198. package/dist-extensions/fabric-extensions.min.js +1 -1
  199. package/dist-extensions/fabric-extensions.min.js.map +1 -1
  200. package/dist-extensions/fabric.d.ts +1 -0
  201. package/dist-extensions/fabric.d.ts.map +1 -1
  202. package/dist-extensions/index.mjs +3 -0
  203. package/dist-extensions/index.mjs.map +1 -1
  204. package/dist-extensions/src/EventTypeDefs.d.ts +5 -0
  205. package/dist-extensions/src/EventTypeDefs.d.ts.map +1 -1
  206. package/dist-extensions/src/Pattern/Pattern.d.ts.map +1 -1
  207. package/dist-extensions/src/Shadow.d.ts +1 -1
  208. package/dist-extensions/src/Shadow.d.ts.map +1 -1
  209. package/dist-extensions/src/canvas/CanvasOptions.d.ts.map +1 -1
  210. package/dist-extensions/src/canvas/SelectableCanvas.d.ts +2 -0
  211. package/dist-extensions/src/canvas/SelectableCanvas.d.ts.map +1 -1
  212. package/dist-extensions/src/canvas/StaticCanvas.d.ts.map +1 -1
  213. package/dist-extensions/src/canvas/StaticCanvasOptions.d.ts.map +1 -1
  214. package/dist-extensions/src/constants.d.ts +1 -0
  215. package/dist-extensions/src/constants.d.ts.map +1 -1
  216. package/dist-extensions/src/controls/Control.d.ts +22 -1
  217. package/dist-extensions/src/controls/Control.d.ts.map +1 -1
  218. package/dist-extensions/src/controls/changeWidth.d.ts +22 -0
  219. package/dist-extensions/src/controls/changeWidth.d.ts.map +1 -1
  220. package/dist-extensions/src/controls/controlRendering.d.ts.map +1 -1
  221. package/dist-extensions/src/controls/index.d.ts +2 -1
  222. package/dist-extensions/src/controls/index.d.ts.map +1 -1
  223. package/dist-extensions/src/gradient/Gradient.d.ts.map +1 -1
  224. package/dist-extensions/src/shapes/Circle.d.ts.map +1 -1
  225. package/dist-extensions/src/shapes/Ellipse.d.ts.map +1 -1
  226. package/dist-extensions/src/shapes/Group.d.ts.map +1 -1
  227. package/dist-extensions/src/shapes/IText/IText.d.ts.map +1 -1
  228. package/dist-extensions/src/shapes/Image.d.ts.map +1 -1
  229. package/dist-extensions/src/shapes/Line.d.ts.map +1 -1
  230. package/dist-extensions/src/shapes/Object/FabricObjectSVGExportMixin.d.ts.map +1 -1
  231. package/dist-extensions/src/shapes/Object/InteractiveObject.d.ts.map +1 -1
  232. package/dist-extensions/src/shapes/Object/Object.d.ts.map +1 -1
  233. package/dist-extensions/src/shapes/Object/types/FabricObjectProps.d.ts.map +1 -1
  234. package/dist-extensions/src/shapes/Object/types/ObjectProps.d.ts.map +1 -1
  235. package/dist-extensions/src/shapes/Path.d.ts +1 -1
  236. package/dist-extensions/src/shapes/Path.d.ts.map +1 -1
  237. package/dist-extensions/src/shapes/Polyline.d.ts.map +1 -1
  238. package/dist-extensions/src/shapes/Rect.d.ts.map +1 -1
  239. package/dist-extensions/src/shapes/Text/StyledText.d.ts.map +1 -1
  240. package/dist-extensions/src/shapes/Text/Text.d.ts.map +1 -1
  241. package/dist-extensions/src/shapes/Text/TextSVGExportMixin.d.ts.map +1 -1
  242. package/dist-extensions/src/shapes/Textbox.d.ts.map +1 -1
  243. package/dist-extensions/src/shapes/Triangle.d.ts.map +1 -1
  244. package/dist-extensions/src/util/lang_string.d.ts +1 -1
  245. package/dist-extensions/src/util/lang_string.d.ts.map +1 -1
  246. package/dist-extensions/src/util/misc/svgParsing.d.ts.map +1 -1
  247. package/eslint.config.mjs +2 -0
  248. package/extensions/cropping_controls/croppingControls.spec.ts +115 -0
  249. package/extensions/cropping_controls/croppingControls.ts +150 -0
  250. package/extensions/cropping_controls/croppingHandlers.spec.ts +579 -0
  251. package/extensions/cropping_controls/croppingHandlers.ts +285 -0
  252. package/extensions/cropping_controls/enterCropMode.ts +30 -0
  253. package/extensions/cropping_controls/renderCornerControl.ts +53 -0
  254. package/extensions/index.ts +9 -0
  255. package/fabric.ts +1 -0
  256. package/package.json +17 -8
  257. package/src/ClassRegistry.spec.ts +18 -19
  258. package/src/EventTypeDefs.ts +15 -11
  259. package/src/Pattern/Pattern.spec.ts +12 -0
  260. package/src/Pattern/Pattern.ts +3 -2
  261. package/src/Shadow.ts +9 -8
  262. package/src/brushes/PencilBrush.spec.ts +11 -11
  263. package/src/canvas/Canvas-dispose.spec.ts +8 -7
  264. package/src/canvas/Canvas.spec.ts +27 -29
  265. package/src/canvas/CanvasOptions.ts +2 -1
  266. package/src/canvas/SelectableCanvas.ts +38 -15
  267. package/src/canvas/StaticCanvas.spec.ts +20 -0
  268. package/src/canvas/StaticCanvas.ts +7 -4
  269. package/src/canvas/StaticCanvasOptions.ts +1 -3
  270. package/src/constants.ts +1 -0
  271. package/src/controls/Control.spec.ts +102 -0
  272. package/src/controls/Control.ts +71 -2
  273. package/src/controls/changeHeight.spec.ts +147 -0
  274. package/src/controls/changeWidth.ts +68 -35
  275. package/src/controls/controlRendering.ts +20 -48
  276. package/src/controls/index.ts +7 -1
  277. package/src/gradient/Gradient.spec.ts +101 -46
  278. package/src/gradient/Gradient.ts +27 -14
  279. package/src/shapes/Circle.spec.ts +10 -39
  280. package/src/shapes/Circle.ts +11 -11
  281. package/src/shapes/Ellipse.spec.ts +8 -37
  282. package/src/shapes/Ellipse.ts +7 -7
  283. package/src/shapes/Group.ts +3 -3
  284. package/src/shapes/IText/IText-click-behavior.spec.ts +36 -49
  285. package/src/shapes/IText/IText.ts +5 -6
  286. package/src/shapes/IText/ITextKeyBehavior.test.ts +0 -1
  287. package/src/shapes/IText/__snapshots__/ITextBehavior.test.ts.snap +6 -6
  288. package/src/shapes/Image.spec.ts +17 -33
  289. package/src/shapes/Image.ts +15 -11
  290. package/src/shapes/Line.spec.ts +4 -30
  291. package/src/shapes/Line.ts +11 -16
  292. package/src/shapes/Object/FabricObjectSVGExportMixin.ts +11 -4
  293. package/src/shapes/Object/InteractiveObject.ts +4 -4
  294. package/src/shapes/Object/Object.ts +6 -5
  295. package/src/shapes/Object/ObjectGeometry.spec.ts +15 -0
  296. package/src/shapes/Object/ObjectGeometry.ts +1 -1
  297. package/src/shapes/Object/objectSvgExport.spec.ts +112 -0
  298. package/src/shapes/Object/types/FabricObjectProps.ts +1 -4
  299. package/src/shapes/Object/types/ObjectProps.ts +1 -3
  300. package/src/shapes/Path.spec.ts +4 -27
  301. package/src/shapes/Path.ts +2 -4
  302. package/src/shapes/Polygon.spec.ts +4 -31
  303. package/src/shapes/Polyline.spec.ts +4 -31
  304. package/src/shapes/Polyline.ts +11 -12
  305. package/src/shapes/Rect.spec.ts +25 -33
  306. package/src/shapes/Rect.ts +7 -7
  307. package/src/shapes/Text/StyledText.ts +0 -3
  308. package/src/shapes/Text/Text.spec.ts +3 -32
  309. package/src/shapes/Text/Text.ts +5 -6
  310. package/src/shapes/Text/TextSVGExportMixin.spec.ts +9 -0
  311. package/src/shapes/Text/TextSVGExportMixin.ts +14 -16
  312. package/src/shapes/Text/__snapshots__/Text.spec.ts.snap +1 -1
  313. package/src/shapes/Text/__snapshots__/TextSVGExportMixin.spec.ts.snap +1 -1
  314. package/src/shapes/Textbox.spec.ts +5 -5
  315. package/src/shapes/Textbox.ts +6 -5
  316. package/src/shapes/Triangle.ts +4 -4
  317. package/src/shapes/__snapshots__/Image.spec.ts.snap +4 -4
  318. package/src/shapes/__snapshots__/Textbox.spec.ts.snap +5 -5
  319. package/src/util/lang_string.ts +3 -2
  320. package/src/util/misc/svgParsing.ts +2 -1
  321. package/tsconfig.spec.json +1 -0
  322. package/vitest.config.ts +12 -2
  323. package/vitest.extend.ts +6 -2
@@ -77,12 +77,12 @@ export class TextSVGExportMixin extends FabricObjectSVGExportMixin {
77
77
  return [
78
78
  textBgRects.join(''),
79
79
  '\t\t<text xml:space="preserve" ',
80
- `font-family="${this.fontFamily.replace(dblQuoteRegex, "'")}" `,
81
- `font-size="${this.fontSize}" `,
82
- this.fontStyle ? `font-style="${this.fontStyle}" ` : '',
83
- this.fontWeight ? `font-weight="${this.fontWeight}" ` : '',
80
+ `font-family="${escapeXml(this.fontFamily.replace(dblQuoteRegex, "'"))}" `,
81
+ `font-size="${escapeXml(this.fontSize)}" `,
82
+ this.fontStyle ? `font-style="${escapeXml(this.fontStyle)}" ` : '',
83
+ this.fontWeight ? `font-weight="${escapeXml(this.fontWeight)}" ` : '',
84
84
  textDecoration ? `text-decoration="${textDecoration}" ` : '',
85
- this.direction === 'rtl' ? `direction="${this.direction}" ` : '',
85
+ this.direction === 'rtl' ? `direction="rtl" ` : '',
86
86
  'style="',
87
87
  this.getSvgStyles(noShadow),
88
88
  '"',
@@ -112,7 +112,7 @@ export class TextSVGExportMixin extends FabricObjectSVGExportMixin {
112
112
  // bounding-box background
113
113
  this.backgroundColor &&
114
114
  textBgRects.push(
115
- ...createSVGInlineRect(
115
+ createSVGInlineRect(
116
116
  this.backgroundColor,
117
117
  -this.width / 2,
118
118
  -this.height / 2,
@@ -270,7 +270,7 @@ export class TextSVGExportMixin extends FabricObjectSVGExportMixin {
270
270
  if (currentColor !== lastColor) {
271
271
  lastColor &&
272
272
  textBgRects.push(
273
- ...createSVGInlineRect(
273
+ createSVGInlineRect(
274
274
  lastColor,
275
275
  leftOffset + boxStart,
276
276
  textTopOffset,
@@ -287,7 +287,7 @@ export class TextSVGExportMixin extends FabricObjectSVGExportMixin {
287
287
  }
288
288
  currentColor &&
289
289
  textBgRects.push(
290
- ...createSVGInlineRect(
290
+ createSVGInlineRect(
291
291
  lastColor,
292
292
  leftOffset + boxStart,
293
293
  textTopOffset,
@@ -325,7 +325,6 @@ export class TextSVGExportMixin extends FabricObjectSVGExportMixin {
325
325
  fontSize,
326
326
  fontStyle,
327
327
  fontWeight,
328
- deltaY,
329
328
  textDecorationThickness,
330
329
  linethrough,
331
330
  overline,
@@ -340,22 +339,21 @@ export class TextSVGExportMixin extends FabricObjectSVGExportMixin {
340
339
  const thickness = textDecorationThickness || this.textDecorationThickness;
341
340
  return [
342
341
  stroke ? colorPropToSVG(STROKE, stroke) : '',
343
- strokeWidth ? `stroke-width: ${strokeWidth}; ` : '',
342
+ strokeWidth ? `stroke-width: ${escapeXml(strokeWidth)}; ` : '',
344
343
  fontFamily
345
344
  ? `font-family: ${
346
345
  !fontFamily.includes("'") && !fontFamily.includes('"')
347
- ? `'${fontFamily}'`
348
- : fontFamily
346
+ ? `'${escapeXml(fontFamily)}'`
347
+ : escapeXml(fontFamily)
349
348
  }; `
350
349
  : '',
351
- fontSize ? `font-size: ${fontSize}px; ` : '',
352
- fontStyle ? `font-style: ${fontStyle}; ` : '',
353
- fontWeight ? `font-weight: ${fontWeight}; ` : '',
350
+ fontSize ? `font-size: ${escapeXml(fontSize)}px; ` : '',
351
+ fontStyle ? `font-style: ${escapeXml(fontStyle)}; ` : '',
352
+ fontWeight ? `font-weight: ${escapeXml(fontWeight)}; ` : '',
354
353
  textDecoration
355
354
  ? `text-decoration: ${textDecoration}; text-decoration-thickness: ${toFixed((thickness * this.getObjectScaling().y) / 10, config.NUM_FRACTION_DIGITS)}%; `
356
355
  : '',
357
356
  fill ? colorPropToSVG(FILL, fill) : '',
358
- deltaY ? `baseline-shift: ${-deltaY}; ` : '',
359
357
  useWhiteSpace ? 'white-space: pre; ' : '',
360
358
  ].join('');
361
359
  }
@@ -196,7 +196,7 @@ exports[`FabricText > toObject 1`] = `
196
196
  "type": "Text",
197
197
  "underline": false,
198
198
  "visible": true,
199
- "width": 60,
199
+ "width": 59.98,
200
200
  }
201
201
  `;
202
202
 
@@ -23,7 +23,7 @@ exports[`TextSvgExport > toSVG > toSVG justified 1`] = `
23
23
 
24
24
  exports[`TextSvgExport > toSVG > toSVG with deltaY 1`] = `
25
25
  "<g transform="matrix(1 0 0 1 17 23)" style="" >
26
- <text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; text-decoration-thickness: 7%; white-space: pre;" ><tspan x="-16" y="13" >x</tspan><tspan x="4" y="13" dy="-14" style="font-size: 24px; baseline-shift: 14; ">x</tspan></text>
26
+ <text xml:space="preserve" font-family="Times New Roman" font-size="40" font-style="normal" font-weight="normal" style="stroke: none; stroke-width: 1; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1; text-decoration-thickness: 7%; white-space: pre;" ><tspan x="-16" y="13" >x</tspan><tspan x="4" y="13" dy="-14" style="font-size: 24px; ">x</tspan></text>
27
27
  </g>
28
28
  "
29
29
  `;
@@ -6,8 +6,8 @@ import { Canvas } from '../canvas/Canvas';
6
6
  import { stylesFromArray } from '../util';
7
7
  import { FabricText } from './Text/Text';
8
8
  import { IText } from './IText/IText';
9
- import type { TPointerEvent } from '../EventTypeDefs';
10
9
  import { Point } from '../Point';
10
+ import { createPointerEvent } from '../../test/utils';
11
11
 
12
12
  describe('Textbox', () => {
13
13
  let canvas: Canvas;
@@ -564,12 +564,12 @@ describe('Textbox', () => {
564
564
  canvas.add(text);
565
565
  canvas.setActiveObject(text);
566
566
 
567
- const eventStub = {
567
+ const eventStub = createPointerEvent({
568
568
  clientX: text.width,
569
569
  clientY: text.oCoords.mr.corner.tl.y + 1,
570
570
  type: 'mousedown',
571
571
  target: canvas.upperCanvasEl,
572
- } as unknown as TPointerEvent & { clientX: number; clientY: number };
572
+ });
573
573
 
574
574
  const originalWidth = text.width;
575
575
 
@@ -599,12 +599,12 @@ describe('Textbox', () => {
599
599
  canvas.add(text);
600
600
  canvas.setActiveObject(text);
601
601
 
602
- const eventStub = {
602
+ const eventStub = createPointerEvent({
603
603
  clientX: text.left - text.width / 2,
604
604
  clientY: text.oCoords.ml.corner.tl.y + 2,
605
605
  type: 'mousedown',
606
606
  target: canvas.upperCanvasEl,
607
- } as unknown as TPointerEvent & { clientX: number; clientY: number };
607
+ });
608
608
 
609
609
  const originalWidth = text.width;
610
610
 
@@ -40,7 +40,8 @@ interface UniqueTextboxProps {
40
40
  }
41
41
 
42
42
  export interface SerializedTextboxProps
43
- extends SerializedITextProps,
43
+ extends
44
+ SerializedITextProps,
44
45
  Pick<UniqueTextboxProps, 'minWidth' | 'splitByGrapheme'> {}
45
46
 
46
47
  export interface TextboxProps extends ITextProps, UniqueTextboxProps {}
@@ -52,10 +53,10 @@ export interface TextboxProps extends ITextProps, UniqueTextboxProps {}
52
53
  * wrapping of lines.
53
54
  */
54
55
  export class Textbox<
55
- Props extends TOptions<TextboxProps> = Partial<TextboxProps>,
56
- SProps extends SerializedTextboxProps = SerializedTextboxProps,
57
- EventSpec extends ITextEvents = ITextEvents,
58
- >
56
+ Props extends TOptions<TextboxProps> = Partial<TextboxProps>,
57
+ SProps extends SerializedTextboxProps = SerializedTextboxProps,
58
+ EventSpec extends ITextEvents = ITextEvents,
59
+ >
59
60
  extends IText<Props, SProps, EventSpec>
60
61
  implements UniqueTextboxProps
61
62
  {
@@ -10,10 +10,10 @@ export const triangleDefaultValues: Partial<TClassProperties<Triangle>> = {
10
10
  };
11
11
 
12
12
  export class Triangle<
13
- Props extends TOptions<FabricObjectProps> = Partial<FabricObjectProps>,
14
- SProps extends SerializedObjectProps = SerializedObjectProps,
15
- EventSpec extends ObjectEvents = ObjectEvents,
16
- >
13
+ Props extends TOptions<FabricObjectProps> = Partial<FabricObjectProps>,
14
+ SProps extends SerializedObjectProps = SerializedObjectProps,
15
+ EventSpec extends ObjectEvents = ObjectEvents,
16
+ >
17
17
  extends FabricObject<Props, SProps, EventSpec>
18
18
  implements FabricObjectProps
19
19
  {
@@ -2,7 +2,7 @@
2
2
 
3
3
  exports[`FabricImage > Svg export > It exports an svg with styles for an image with stroke 1`] = `
4
4
  "<g transform="matrix(1 0 0 1 83.5 83.5)" >
5
- <filter id="SVGID_0" y="-45.33%" height="190.66%" x="-36%" width="172%" >
5
+ <filter id="SVGID" y="-45.33%" height="190.66%" x="-36%" width="172%" >
6
6
  <feGaussianBlur in="SourceAlpha" stdDeviation="12"></feGaussianBlur>
7
7
  <feOffset dx="0" dy="14" result="oBlur" ></feOffset>
8
8
  <feFlood flood-color="rgb(0,0,0)" flood-opacity="0.5"/>
@@ -12,11 +12,11 @@ exports[`FabricImage > Svg export > It exports an svg with styles for an image w
12
12
  <feMergeNode in="SourceGraphic"></feMergeNode>
13
13
  </feMerge>
14
14
  </filter>
15
- <clipPath id="imageCrop_2">
15
+ <clipPath id="SVGID">
16
16
  <rect x="-75" y="-75" width="150" height="150" />
17
17
  </clipPath>
18
- <image style="stroke: rgb(255,0,0); stroke-width: 11; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;filter: url(#SVGID_0);" xlink:href="" x="-85" y="-85" width="200" height="200" clip-path="url(#imageCrop_2)" ></image>
19
- <rect x="-75" y="-75" width="150" height="150" style="stroke: rgb(255,0,0); stroke-width: 11; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: none; fill-rule: nonzero; opacity: 1;filter: url(#SVGID_0);" />
18
+ <image style="stroke: rgb(255,0,0); stroke-width: 11; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: rgb(0,0,0); fill-rule: nonzero; opacity: 1;filter: url(#SVGID);" xlink:href="assets/xlink:href=" x="-85" y="-85" width="200" height="200" clip-path="url(#SVGID)" ></image>
19
+ <rect x="-75" y="-75" width="150" height="150" style="stroke: rgb(255,0,0); stroke-width: 11; stroke-dasharray: none; stroke-linecap: butt; stroke-dashoffset: 0; stroke-linejoin: miter; stroke-miterlimit: 4; fill: none; fill-rule: nonzero; opacity: 1;filter: url(#SVGID);" />
20
20
  </g>
21
21
  "
22
22
  `;
@@ -15,7 +15,7 @@ exports[`Textbox > fromObject 1`] = `
15
15
  "fontStyle": "normal",
16
16
  "fontWeight": "normal",
17
17
  "globalCompositeOperation": "source-over",
18
- "height": 254.928,
18
+ "height": 254.93,
19
19
  "left": 0,
20
20
  "lineHeight": 1.16,
21
21
  "linethrough": false,
@@ -54,13 +54,13 @@ fox",
54
54
  "type": "Textbox",
55
55
  "underline": false,
56
56
  "visible": true,
57
- "width": 102,
57
+ "width": 102.21,
58
58
  }
59
59
  `;
60
60
 
61
61
  exports[`Textbox > fromObject 2`] = `
62
62
  {
63
- "height": 254.928,
63
+ "height": 254.93,
64
64
  "left": 0,
65
65
  "styles": [],
66
66
  "text": "The quick
@@ -68,7 +68,7 @@ brown
68
68
  fox",
69
69
  "top": 0,
70
70
  "type": "Textbox",
71
- "width": 102,
71
+ "width": 102.21,
72
72
  }
73
73
  `;
74
74
 
@@ -106,7 +106,7 @@ exports[`Textbox > toObject with styles 1`] = `
106
106
  "fontStyle": "normal",
107
107
  "fontWeight": "normal",
108
108
  "globalCompositeOperation": "source-over",
109
- "height": 202.496,
109
+ "height": 202.5,
110
110
  "left": 0,
111
111
  "lineHeight": 1.16,
112
112
  "linethrough": false,
@@ -18,8 +18,9 @@ export const capitalize = (string: string, firstLetterOnly = false): string =>
18
18
  * @param {String} string String to escape
19
19
  * @return {String} Escaped version of a string
20
20
  */
21
- export const escapeXml = (string: string): string =>
22
- string
21
+ export const escapeXml = (stringOrNumber: string | number): string =>
22
+ stringOrNumber
23
+ .toString()
23
24
  .replace(/&/g, '&amp;')
24
25
  .replace(/"/g, '&quot;')
25
26
  .replace(/'/g, '&apos;')
@@ -2,6 +2,7 @@ import { Color } from '../../color/Color';
2
2
  import { config } from '../../config';
3
3
  import { DEFAULT_SVG_FONT_SIZE, FILL, NONE } from '../../constants';
4
4
  import type { TBBox, SVGElementName, SupportedSVGUnit } from '../../typedefs';
5
+ import { escapeXml } from '../lang_string';
5
6
  import { toFixed } from './toFixed';
6
7
 
7
8
  /**
@@ -133,7 +134,7 @@ export const colorPropToSVG = (
133
134
  if (!value) {
134
135
  colorValue = 'none';
135
136
  } else if (value.toLive) {
136
- colorValue = `url(#SVGID_${value.id})`;
137
+ colorValue = `url(#SVGID_${escapeXml(value.id)})`;
137
138
  } else {
138
139
  const color = new Color(value),
139
140
  opacity = color.getAlpha();
@@ -12,6 +12,7 @@
12
12
  },
13
13
  "include": [
14
14
  "src/**/*",
15
+ "e2e/**/*",
15
16
  "extensions/**/*",
16
17
  "vitest.d.ts",
17
18
  "vitest.env.d.ts",
package/vitest.config.ts CHANGED
@@ -9,6 +9,10 @@ if (!fixturesUrl.endsWith('/')) {
9
9
  fixturesUrl += '/';
10
10
  }
11
11
 
12
+ // Node 20 requires vmThreads, newer versions can use threads
13
+ const nodeMajor = parseInt(process.version.slice(1).split('.')[0]);
14
+ const pool = nodeMajor <= 20 ? 'vmThreads' : 'threads';
15
+
12
16
  export default defineConfig({
13
17
  resolve: {
14
18
  alias: {
@@ -16,7 +20,7 @@ export default defineConfig({
16
20
  },
17
21
  },
18
22
  test: {
19
- pool: 'vmThreads',
23
+ pool,
20
24
  clearMocks: true,
21
25
  mockReset: true,
22
26
  snapshotSerializers: [
@@ -44,7 +48,12 @@ export default defineConfig({
44
48
  provider: playwright(),
45
49
  enabled: true,
46
50
  headless: true,
47
- instances: [{ browser: 'chromium' }],
51
+ instances: [
52
+ {
53
+ browser: 'chromium',
54
+ isolate: true,
55
+ },
56
+ ],
48
57
  },
49
58
  name: 'unit-chromium',
50
59
  },
@@ -63,6 +72,7 @@ export default defineConfig({
63
72
  instances: [
64
73
  {
65
74
  browser: 'firefox',
75
+ isolate: true,
66
76
  },
67
77
  ],
68
78
  },
package/vitest.extend.ts CHANGED
@@ -73,9 +73,13 @@ chai.util.addMethod(
73
73
  delete snap.version;
74
74
 
75
75
  const value = cloneDeepWith(snap, (v, k, obj, stack) => {
76
- const c = customiser?.(v, k, obj, stack);
76
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
77
+ const c = (customiser as any)?.(v, k, obj, stack);
77
78
  if (c !== undefined) return c;
78
- if (k === 'width') return Math.round(v as number);
79
+ if ((k === 'width' || k === 'height') && typeof v === 'number')
80
+ return Math.round(v * 100) / 100;
81
+ // Normalize uid-based ids which vary by test execution order
82
+ if (k === 'id' && typeof v === 'number') return 0;
79
83
  });
80
84
 
81
85
  chai.util.flag(this, 'object', value);