js-draw 0.25.1 → 1.0.1

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 (750) hide show
  1. package/README.md +80 -26
  2. package/build-config.json +22 -21
  3. package/dist/Editor.css +1281 -0
  4. package/dist/bundle.js +3 -3
  5. package/dist/bundledStyles.js +1 -1
  6. package/dist/cjs/Editor.d.ts +91 -12
  7. package/dist/cjs/Editor.js +619 -590
  8. package/dist/cjs/EditorImage.d.ts +5 -2
  9. package/dist/cjs/EditorImage.js +258 -297
  10. package/dist/cjs/EventDispatcher.js +17 -19
  11. package/dist/cjs/Pointer.d.ts +3 -1
  12. package/dist/cjs/Pointer.js +41 -44
  13. package/dist/cjs/SVGLoader.d.ts +7 -1
  14. package/dist/cjs/SVGLoader.js +373 -474
  15. package/dist/cjs/UndoRedoHistory.js +28 -40
  16. package/dist/cjs/Viewport.d.ts +1 -4
  17. package/dist/cjs/Viewport.js +150 -193
  18. package/dist/cjs/bundle/bundled.js +4 -1
  19. package/dist/cjs/commands/Command.js +22 -49
  20. package/dist/cjs/commands/Duplicate.js +28 -44
  21. package/dist/cjs/commands/Erase.js +36 -54
  22. package/dist/cjs/commands/SerializableCommand.js +20 -35
  23. package/dist/cjs/commands/UnresolvedCommand.js +14 -29
  24. package/dist/cjs/commands/invertCommand.js +29 -51
  25. package/dist/cjs/commands/lib.js +9 -6
  26. package/dist/cjs/commands/localization.d.ts +1 -1
  27. package/dist/cjs/commands/localization.js +9 -9
  28. package/dist/cjs/commands/uniteCommands.js +57 -87
  29. package/dist/cjs/components/AbstractComponent.d.ts +11 -3
  30. package/dist/cjs/components/AbstractComponent.js +141 -169
  31. package/dist/cjs/components/BackgroundComponent.d.ts +3 -6
  32. package/dist/cjs/components/BackgroundComponent.js +124 -149
  33. package/dist/cjs/components/ImageComponent.d.ts +3 -5
  34. package/dist/cjs/components/ImageComponent.js +95 -175
  35. package/dist/cjs/components/RestylableComponent.d.ts +1 -1
  36. package/dist/cjs/components/RestylableComponent.js +41 -56
  37. package/dist/cjs/components/SVGGlobalAttributesObject.d.ts +1 -3
  38. package/dist/cjs/components/SVGGlobalAttributesObject.js +34 -51
  39. package/dist/cjs/components/Stroke.d.ts +4 -6
  40. package/dist/cjs/components/Stroke.js +95 -121
  41. package/dist/cjs/components/TextComponent.d.ts +2 -4
  42. package/dist/cjs/components/TextComponent.js +189 -234
  43. package/dist/cjs/components/UnknownSVGObject.d.ts +1 -3
  44. package/dist/cjs/components/UnknownSVGObject.js +30 -43
  45. package/dist/cjs/components/builders/ArrowBuilder.d.ts +1 -1
  46. package/dist/cjs/components/builders/ArrowBuilder.js +43 -42
  47. package/dist/cjs/components/builders/CircleBuilder.js +43 -43
  48. package/dist/cjs/components/builders/FreehandLineBuilder.d.ts +3 -2
  49. package/dist/cjs/components/builders/FreehandLineBuilder.js +73 -86
  50. package/dist/cjs/components/builders/LineBuilder.d.ts +1 -1
  51. package/dist/cjs/components/builders/LineBuilder.js +38 -36
  52. package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -1
  53. package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.js +131 -139
  54. package/dist/cjs/components/builders/RectangleBuilder.d.ts +1 -1
  55. package/dist/cjs/components/builders/RectangleBuilder.js +31 -31
  56. package/dist/cjs/components/builders/types.d.ts +1 -1
  57. package/dist/cjs/components/lib.d.ts +3 -1
  58. package/dist/cjs/components/lib.js +10 -7
  59. package/dist/cjs/components/localization.js +4 -4
  60. package/dist/cjs/components/util/StrokeSmoother.d.ts +1 -2
  61. package/dist/cjs/components/util/StrokeSmoother.js +67 -72
  62. package/dist/cjs/components/util/describeComponentList.d.ts +1 -1
  63. package/dist/cjs/components/util/describeComponentList.js +4 -5
  64. package/dist/cjs/dialogs/makeAboutDialog.d.ts +15 -0
  65. package/dist/cjs/dialogs/makeAboutDialog.js +54 -0
  66. package/dist/cjs/inputEvents.d.ts +84 -0
  67. package/dist/cjs/inputEvents.js +40 -0
  68. package/dist/cjs/lib.d.ts +29 -13
  69. package/dist/cjs/lib.js +38 -23
  70. package/dist/cjs/localization.js +19 -18
  71. package/dist/cjs/localizations/de.js +117 -13
  72. package/dist/cjs/localizations/en.js +4 -13
  73. package/dist/cjs/localizations/es.js +62 -23
  74. package/dist/cjs/localizations/getLocalizationTable.js +15 -13
  75. package/dist/cjs/rendering/Display.d.ts +1 -2
  76. package/dist/cjs/rendering/Display.js +70 -83
  77. package/dist/cjs/rendering/RenderablePathSpec.d.ts +15 -0
  78. package/dist/cjs/rendering/RenderablePathSpec.js +70 -0
  79. package/dist/cjs/rendering/RenderingStyle.d.ts +4 -4
  80. package/dist/cjs/rendering/RenderingStyle.js +18 -28
  81. package/dist/cjs/rendering/TextRenderingStyle.d.ts +10 -10
  82. package/dist/cjs/rendering/TextRenderingStyle.js +13 -18
  83. package/dist/cjs/rendering/caching/CacheRecord.d.ts +1 -2
  84. package/dist/cjs/rendering/caching/CacheRecord.js +20 -22
  85. package/dist/cjs/rendering/caching/CacheRecordManager.d.ts +1 -1
  86. package/dist/cjs/rendering/caching/CacheRecordManager.js +17 -15
  87. package/dist/cjs/rendering/caching/RenderingCache.js +19 -19
  88. package/dist/cjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
  89. package/dist/cjs/rendering/caching/RenderingCacheNode.js +98 -118
  90. package/dist/cjs/rendering/caching/testUtils.js +24 -23
  91. package/dist/cjs/rendering/caching/types.d.ts +3 -3
  92. package/dist/cjs/rendering/lib.js +8 -5
  93. package/dist/cjs/rendering/localization.js +5 -5
  94. package/dist/cjs/rendering/renderers/AbstractRenderer.d.ts +2 -11
  95. package/dist/cjs/rendering/renderers/AbstractRenderer.js +53 -57
  96. package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +3 -5
  97. package/dist/cjs/rendering/renderers/CanvasRenderer.js +91 -106
  98. package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -4
  99. package/dist/cjs/rendering/renderers/DummyRenderer.js +56 -76
  100. package/dist/cjs/rendering/renderers/SVGRenderer.d.ts +5 -5
  101. package/dist/cjs/rendering/renderers/SVGRenderer.js +194 -176
  102. package/dist/cjs/rendering/renderers/TextOnlyRenderer.d.ts +1 -3
  103. package/dist/cjs/rendering/renderers/TextOnlyRenderer.js +47 -72
  104. package/dist/cjs/shortcuts/KeyBinding.d.ts +5 -0
  105. package/dist/cjs/shortcuts/KeyBinding.js +94 -70
  106. package/dist/cjs/shortcuts/KeyboardShortcutManager.d.ts +1 -1
  107. package/dist/cjs/shortcuts/KeyboardShortcutManager.js +36 -45
  108. package/dist/cjs/shortcuts/lib.js +5 -2
  109. package/dist/cjs/testing/createEditor.js +7 -4
  110. package/dist/cjs/testing/getUniquePointerId.js +4 -5
  111. package/dist/cjs/testing/lib.js +5 -2
  112. package/dist/cjs/testing/sendPenEvent.d.ts +2 -2
  113. package/dist/cjs/testing/sendPenEvent.js +10 -7
  114. package/dist/cjs/testing/sendTouchEvent.d.ts +2 -2
  115. package/dist/cjs/testing/sendTouchEvent.js +34 -16
  116. package/dist/cjs/toolbar/AbstractToolbar.d.ts +166 -0
  117. package/dist/cjs/toolbar/AbstractToolbar.js +410 -0
  118. package/dist/cjs/toolbar/DropdownToolbar.d.ts +43 -0
  119. package/dist/cjs/toolbar/DropdownToolbar.js +176 -0
  120. package/dist/cjs/toolbar/EdgeToolbar.d.ts +47 -0
  121. package/dist/cjs/toolbar/EdgeToolbar.js +422 -0
  122. package/dist/cjs/toolbar/IconProvider.d.ts +54 -30
  123. package/dist/cjs/toolbar/IconProvider.js +652 -224
  124. package/dist/cjs/toolbar/constants.d.ts +1 -0
  125. package/dist/cjs/toolbar/constants.js +4 -0
  126. package/dist/cjs/toolbar/lib.d.ts +4 -2
  127. package/dist/cjs/toolbar/lib.js +10 -3
  128. package/dist/cjs/toolbar/localization.d.ts +9 -2
  129. package/dist/cjs/toolbar/localization.js +26 -19
  130. package/dist/cjs/toolbar/types.d.ts +7 -0
  131. package/dist/cjs/toolbar/widgets/ActionButtonWidget.d.ts +1 -1
  132. package/dist/cjs/toolbar/widgets/ActionButtonWidget.js +23 -39
  133. package/dist/cjs/toolbar/widgets/BaseToolWidget.d.ts +1 -1
  134. package/dist/cjs/toolbar/widgets/BaseToolWidget.js +35 -37
  135. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +60 -5
  136. package/dist/cjs/toolbar/widgets/BaseWidget.js +232 -177
  137. package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +130 -117
  138. package/dist/cjs/toolbar/widgets/EraserToolWidget.d.ts +1 -3
  139. package/dist/cjs/toolbar/widgets/EraserToolWidget.js +45 -73
  140. package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  141. package/dist/cjs/toolbar/widgets/HandToolWidget.js +126 -141
  142. package/dist/cjs/toolbar/widgets/InsertImageWidget.d.ts +9 -7
  143. package/dist/cjs/toolbar/widgets/InsertImageWidget.js +147 -212
  144. package/dist/cjs/toolbar/widgets/OverflowWidget.js +33 -61
  145. package/dist/cjs/toolbar/widgets/PenToolWidget.d.ts +8 -1
  146. package/dist/cjs/toolbar/widgets/PenToolWidget.js +162 -234
  147. package/dist/cjs/toolbar/widgets/SelectionToolWidget.d.ts +3 -1
  148. package/dist/cjs/toolbar/widgets/SelectionToolWidget.js +105 -177
  149. package/dist/cjs/toolbar/widgets/TextToolWidget.js +64 -87
  150. package/dist/cjs/toolbar/widgets/components/makeColorInput.d.ts +10 -0
  151. package/dist/cjs/toolbar/{makeColorInput.js → widgets/components/makeColorInput.js} +57 -34
  152. package/dist/cjs/toolbar/widgets/components/makeFileInput.d.ts +12 -0
  153. package/dist/cjs/toolbar/widgets/components/makeFileInput.js +111 -0
  154. package/dist/cjs/toolbar/widgets/components/makeGridSelector.d.ts +24 -0
  155. package/dist/cjs/toolbar/widgets/components/makeGridSelector.js +127 -0
  156. package/dist/cjs/toolbar/widgets/components/makeSeparator.d.ts +7 -0
  157. package/dist/cjs/toolbar/widgets/components/makeSeparator.js +16 -0
  158. package/dist/cjs/toolbar/widgets/components/makeThicknessSlider.d.ts +8 -0
  159. package/dist/cjs/toolbar/widgets/components/makeThicknessSlider.js +47 -0
  160. package/dist/cjs/toolbar/widgets/keybindings.js +8 -5
  161. package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.d.ts +21 -0
  162. package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.js +199 -0
  163. package/dist/cjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.d.ts +14 -0
  164. package/dist/cjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.js +60 -0
  165. package/dist/cjs/toolbar/widgets/layout/types.d.ts +63 -0
  166. package/dist/cjs/toolbar/widgets/layout/types.js +2 -0
  167. package/dist/cjs/toolbar/widgets/lib.d.ts +1 -1
  168. package/dist/cjs/toolbar/widgets/lib.js +15 -11
  169. package/dist/cjs/tools/BaseTool.d.ts +28 -9
  170. package/dist/cjs/tools/BaseTool.js +128 -51
  171. package/dist/cjs/tools/Eraser.d.ts +8 -1
  172. package/dist/cjs/tools/Eraser.js +82 -92
  173. package/dist/cjs/tools/FindTool.d.ts +1 -1
  174. package/dist/cjs/tools/FindTool.js +61 -77
  175. package/dist/cjs/tools/InputFilter/FunctionMapper.d.ts +12 -0
  176. package/dist/cjs/tools/InputFilter/FunctionMapper.js +21 -0
  177. package/dist/cjs/tools/InputFilter/InputMapper.d.ts +23 -0
  178. package/dist/cjs/tools/InputFilter/InputMapper.js +38 -0
  179. package/dist/cjs/tools/InputFilter/InputPipeline.d.ts +15 -0
  180. package/dist/cjs/tools/InputFilter/InputPipeline.js +54 -0
  181. package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
  182. package/dist/cjs/tools/InputFilter/InputStabilizer.js +181 -0
  183. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
  184. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +84 -0
  185. package/dist/cjs/tools/PanZoom.d.ts +4 -2
  186. package/dist/cjs/tools/PanZoom.js +186 -248
  187. package/dist/cjs/tools/PasteHandler.d.ts +1 -1
  188. package/dist/cjs/tools/PasteHandler.js +49 -148
  189. package/dist/cjs/tools/Pen.d.ts +12 -11
  190. package/dist/cjs/tools/Pen.js +123 -158
  191. package/dist/cjs/tools/PipetteTool.d.ts +11 -2
  192. package/dist/cjs/tools/PipetteTool.js +51 -48
  193. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -1
  194. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +15 -30
  195. package/dist/cjs/tools/SelectionTool/Selection.d.ts +5 -5
  196. package/dist/cjs/tools/SelectionTool/Selection.js +308 -415
  197. package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +15 -5
  198. package/dist/cjs/tools/SelectionTool/SelectionHandle.js +63 -37
  199. package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +4 -4
  200. package/dist/cjs/tools/SelectionTool/SelectionTool.js +164 -187
  201. package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +1 -1
  202. package/dist/cjs/tools/SelectionTool/TransformMode.js +65 -66
  203. package/dist/cjs/tools/SoundUITool.d.ts +2 -1
  204. package/dist/cjs/tools/SoundUITool.js +70 -84
  205. package/dist/cjs/tools/TextTool.d.ts +5 -3
  206. package/dist/cjs/tools/TextTool.js +169 -173
  207. package/dist/cjs/tools/ToolController.d.ts +16 -2
  208. package/dist/cjs/tools/ToolController.js +124 -100
  209. package/dist/cjs/tools/ToolEnabledGroup.js +6 -9
  210. package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +1 -1
  211. package/dist/cjs/tools/ToolSwitcherShortcut.js +16 -32
  212. package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +1 -1
  213. package/dist/cjs/tools/ToolbarShortcutHandler.js +17 -33
  214. package/dist/cjs/tools/UndoRedoShortcut.d.ts +1 -1
  215. package/dist/cjs/tools/UndoRedoShortcut.js +12 -27
  216. package/dist/cjs/tools/keybindings.js +21 -18
  217. package/dist/cjs/tools/lib.js +17 -14
  218. package/dist/cjs/tools/localization.d.ts +2 -1
  219. package/dist/cjs/tools/localization.js +8 -7
  220. package/dist/cjs/types.d.ts +22 -80
  221. package/dist/cjs/types.js +8 -16
  222. package/dist/cjs/util/ReactiveValue.d.ts +65 -0
  223. package/dist/cjs/util/ReactiveValue.js +166 -0
  224. package/dist/cjs/util/assertions.js +5 -8
  225. package/dist/cjs/util/fileToBase64.js +6 -6
  226. package/dist/cjs/util/guessKeyCodeFromKey.d.ts +9 -0
  227. package/dist/cjs/util/guessKeyCodeFromKey.js +32 -0
  228. package/dist/cjs/util/listPrefixMatch.d.ts +6 -0
  229. package/dist/cjs/util/listPrefixMatch.js +17 -0
  230. package/dist/cjs/util/stopPropagationOfScrollingWheelEvents.d.ts +2 -0
  231. package/dist/cjs/util/stopPropagationOfScrollingWheelEvents.js +17 -0
  232. package/dist/cjs/util/untilNextAnimationFrame.js +3 -3
  233. package/dist/cjs/util/waitForAll.js +3 -3
  234. package/dist/cjs/util/waitForTimeout.js +3 -3
  235. package/dist/cjs/version.d.ts +4 -0
  236. package/dist/cjs/version.js +5 -0
  237. package/dist/mjs/Editor.d.ts +91 -12
  238. package/dist/mjs/Editor.mjs +565 -563
  239. package/dist/mjs/EditorImage.d.ts +5 -2
  240. package/dist/mjs/EditorImage.mjs +248 -291
  241. package/dist/mjs/EventDispatcher.mjs +17 -20
  242. package/dist/mjs/Pointer.d.ts +3 -1
  243. package/dist/mjs/Pointer.mjs +40 -44
  244. package/dist/mjs/SVGLoader.d.ts +7 -1
  245. package/dist/mjs/SVGLoader.mjs +338 -466
  246. package/dist/mjs/UndoRedoHistory.mjs +27 -39
  247. package/dist/mjs/Viewport.d.ts +1 -4
  248. package/dist/mjs/Viewport.mjs +139 -187
  249. package/dist/mjs/commands/Command.mjs +21 -49
  250. package/dist/mjs/commands/Duplicate.mjs +22 -41
  251. package/dist/mjs/commands/Erase.mjs +30 -51
  252. package/dist/mjs/commands/SerializableCommand.mjs +16 -34
  253. package/dist/mjs/commands/UnresolvedCommand.mjs +10 -29
  254. package/dist/mjs/commands/invertCommand.mjs +24 -49
  255. package/dist/mjs/commands/localization.d.ts +1 -1
  256. package/dist/mjs/commands/localization.mjs +10 -10
  257. package/dist/mjs/commands/uniteCommands.mjs +52 -85
  258. package/dist/mjs/components/AbstractComponent.d.ts +11 -3
  259. package/dist/mjs/components/AbstractComponent.mjs +135 -166
  260. package/dist/mjs/components/BackgroundComponent.d.ts +3 -6
  261. package/dist/mjs/components/BackgroundComponent.mjs +107 -136
  262. package/dist/mjs/components/ImageComponent.d.ts +3 -5
  263. package/dist/mjs/components/ImageComponent.mjs +90 -174
  264. package/dist/mjs/components/RestylableComponent.d.ts +1 -1
  265. package/dist/mjs/components/RestylableComponent.mjs +35 -53
  266. package/dist/mjs/components/SVGGlobalAttributesObject.d.ts +1 -3
  267. package/dist/mjs/components/SVGGlobalAttributesObject.mjs +29 -50
  268. package/dist/mjs/components/Stroke.d.ts +4 -6
  269. package/dist/mjs/components/Stroke.mjs +89 -119
  270. package/dist/mjs/components/TextComponent.d.ts +2 -4
  271. package/dist/mjs/components/TextComponent.mjs +180 -228
  272. package/dist/mjs/components/UnknownSVGObject.d.ts +1 -3
  273. package/dist/mjs/components/UnknownSVGObject.mjs +26 -43
  274. package/dist/mjs/components/builders/ArrowBuilder.d.ts +1 -1
  275. package/dist/mjs/components/builders/ArrowBuilder.mjs +32 -35
  276. package/dist/mjs/components/builders/CircleBuilder.mjs +35 -38
  277. package/dist/mjs/components/builders/FreehandLineBuilder.d.ts +3 -2
  278. package/dist/mjs/components/builders/FreehandLineBuilder.mjs +52 -69
  279. package/dist/mjs/components/builders/LineBuilder.d.ts +1 -1
  280. package/dist/mjs/components/builders/LineBuilder.mjs +30 -32
  281. package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.d.ts +1 -1
  282. package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.mjs +103 -115
  283. package/dist/mjs/components/builders/RectangleBuilder.d.ts +1 -1
  284. package/dist/mjs/components/builders/RectangleBuilder.mjs +27 -31
  285. package/dist/mjs/components/builders/types.d.ts +1 -1
  286. package/dist/mjs/components/lib.d.ts +3 -1
  287. package/dist/mjs/components/lib.mjs +1 -1
  288. package/dist/mjs/components/localization.mjs +5 -5
  289. package/dist/mjs/components/util/StrokeSmoother.d.ts +1 -2
  290. package/dist/mjs/components/util/StrokeSmoother.mjs +63 -69
  291. package/dist/mjs/components/util/describeComponentList.d.ts +1 -1
  292. package/dist/mjs/components/util/describeComponentList.mjs +4 -5
  293. package/dist/mjs/dialogs/makeAboutDialog.d.ts +15 -0
  294. package/dist/mjs/dialogs/makeAboutDialog.mjs +52 -0
  295. package/dist/mjs/inputEvents.d.ts +84 -0
  296. package/dist/mjs/inputEvents.mjs +34 -0
  297. package/dist/mjs/lib.d.ts +29 -13
  298. package/dist/mjs/lib.mjs +30 -13
  299. package/dist/mjs/localization.mjs +14 -13
  300. package/dist/mjs/localizations/de.mjs +116 -12
  301. package/dist/mjs/localizations/en.mjs +3 -12
  302. package/dist/mjs/localizations/es.mjs +61 -22
  303. package/dist/mjs/localizations/getLocalizationTable.mjs +12 -13
  304. package/dist/mjs/rendering/Display.d.ts +1 -2
  305. package/dist/mjs/rendering/Display.mjs +62 -79
  306. package/dist/mjs/rendering/RenderablePathSpec.d.ts +15 -0
  307. package/dist/mjs/rendering/RenderablePathSpec.mjs +64 -0
  308. package/dist/mjs/rendering/RenderingStyle.d.ts +4 -4
  309. package/dist/mjs/rendering/RenderingStyle.mjs +16 -26
  310. package/dist/mjs/rendering/TextRenderingStyle.d.ts +10 -10
  311. package/dist/mjs/rendering/TextRenderingStyle.mjs +12 -17
  312. package/dist/mjs/rendering/caching/CacheRecord.d.ts +1 -2
  313. package/dist/mjs/rendering/caching/CacheRecord.mjs +20 -23
  314. package/dist/mjs/rendering/caching/CacheRecordManager.d.ts +1 -1
  315. package/dist/mjs/rendering/caching/CacheRecordManager.mjs +13 -15
  316. package/dist/mjs/rendering/caching/RenderingCache.mjs +13 -17
  317. package/dist/mjs/rendering/caching/RenderingCacheNode.d.ts +1 -1
  318. package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +94 -115
  319. package/dist/mjs/rendering/caching/testUtils.mjs +19 -21
  320. package/dist/mjs/rendering/caching/types.d.ts +3 -3
  321. package/dist/mjs/rendering/localization.mjs +6 -6
  322. package/dist/mjs/rendering/renderers/AbstractRenderer.d.ts +2 -11
  323. package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +47 -52
  324. package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +3 -5
  325. package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +84 -103
  326. package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -4
  327. package/dist/mjs/rendering/renderers/DummyRenderer.mjs +51 -75
  328. package/dist/mjs/rendering/renderers/SVGRenderer.d.ts +5 -5
  329. package/dist/mjs/rendering/renderers/SVGRenderer.mjs +185 -171
  330. package/dist/mjs/rendering/renderers/TextOnlyRenderer.d.ts +1 -3
  331. package/dist/mjs/rendering/renderers/TextOnlyRenderer.mjs +43 -72
  332. package/dist/mjs/shortcuts/KeyBinding.d.ts +5 -0
  333. package/dist/mjs/shortcuts/KeyBinding.mjs +94 -71
  334. package/dist/mjs/shortcuts/KeyboardShortcutManager.d.ts +1 -1
  335. package/dist/mjs/shortcuts/KeyboardShortcutManager.mjs +32 -44
  336. package/dist/mjs/testing/createEditor.mjs +2 -2
  337. package/dist/mjs/testing/getUniquePointerId.mjs +4 -5
  338. package/dist/mjs/testing/sendPenEvent.d.ts +2 -2
  339. package/dist/mjs/testing/sendPenEvent.mjs +5 -5
  340. package/dist/mjs/testing/sendTouchEvent.d.ts +2 -2
  341. package/dist/mjs/testing/sendTouchEvent.mjs +8 -16
  342. package/dist/mjs/toolbar/AbstractToolbar.d.ts +166 -0
  343. package/dist/mjs/toolbar/AbstractToolbar.mjs +405 -0
  344. package/dist/mjs/toolbar/DropdownToolbar.d.ts +43 -0
  345. package/dist/mjs/toolbar/DropdownToolbar.mjs +168 -0
  346. package/dist/mjs/toolbar/EdgeToolbar.d.ts +47 -0
  347. package/dist/mjs/toolbar/EdgeToolbar.mjs +414 -0
  348. package/dist/mjs/toolbar/IconProvider.d.ts +54 -30
  349. package/dist/mjs/toolbar/IconProvider.mjs +644 -219
  350. package/dist/mjs/toolbar/constants.d.ts +1 -0
  351. package/dist/mjs/toolbar/constants.mjs +1 -0
  352. package/dist/mjs/toolbar/lib.d.ts +4 -2
  353. package/dist/mjs/toolbar/lib.mjs +3 -1
  354. package/dist/mjs/toolbar/localization.d.ts +9 -2
  355. package/dist/mjs/toolbar/localization.mjs +27 -20
  356. package/dist/mjs/toolbar/types.d.ts +7 -0
  357. package/dist/mjs/toolbar/widgets/ActionButtonWidget.d.ts +1 -1
  358. package/dist/mjs/toolbar/widgets/ActionButtonWidget.mjs +19 -39
  359. package/dist/mjs/toolbar/widgets/BaseToolWidget.d.ts +1 -1
  360. package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +30 -36
  361. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +60 -5
  362. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +227 -176
  363. package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +98 -111
  364. package/dist/mjs/toolbar/widgets/EraserToolWidget.d.ts +1 -3
  365. package/dist/mjs/toolbar/widgets/EraserToolWidget.mjs +41 -73
  366. package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  367. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +94 -136
  368. package/dist/mjs/toolbar/widgets/InsertImageWidget.d.ts +9 -7
  369. package/dist/mjs/toolbar/widgets/InsertImageWidget.mjs +140 -208
  370. package/dist/mjs/toolbar/widgets/OverflowWidget.mjs +30 -62
  371. package/dist/mjs/toolbar/widgets/PenToolWidget.d.ts +8 -1
  372. package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +150 -225
  373. package/dist/mjs/toolbar/widgets/SelectionToolWidget.d.ts +3 -1
  374. package/dist/mjs/toolbar/widgets/SelectionToolWidget.mjs +97 -173
  375. package/dist/mjs/toolbar/widgets/TextToolWidget.mjs +59 -85
  376. package/dist/mjs/toolbar/widgets/components/makeColorInput.d.ts +10 -0
  377. package/dist/mjs/toolbar/{makeColorInput.mjs → widgets/components/makeColorInput.mjs} +53 -33
  378. package/dist/mjs/toolbar/widgets/components/makeFileInput.d.ts +12 -0
  379. package/dist/mjs/toolbar/widgets/components/makeFileInput.mjs +106 -0
  380. package/dist/mjs/toolbar/widgets/components/makeGridSelector.d.ts +24 -0
  381. package/dist/mjs/toolbar/widgets/components/makeGridSelector.mjs +122 -0
  382. package/dist/mjs/toolbar/widgets/components/makeSeparator.d.ts +7 -0
  383. package/dist/mjs/toolbar/widgets/components/makeSeparator.mjs +14 -0
  384. package/dist/mjs/toolbar/widgets/components/makeThicknessSlider.d.ts +8 -0
  385. package/dist/mjs/toolbar/widgets/components/makeThicknessSlider.mjs +45 -0
  386. package/dist/mjs/toolbar/widgets/keybindings.mjs +5 -5
  387. package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.d.ts +21 -0
  388. package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.mjs +193 -0
  389. package/dist/mjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.d.ts +14 -0
  390. package/dist/mjs/toolbar/widgets/layout/EdgeToolbarLayoutManager.mjs +57 -0
  391. package/dist/mjs/toolbar/widgets/layout/types.d.ts +63 -0
  392. package/dist/mjs/toolbar/widgets/lib.d.ts +1 -1
  393. package/dist/mjs/toolbar/widgets/lib.mjs +1 -1
  394. package/dist/mjs/tools/BaseTool.d.ts +28 -9
  395. package/dist/mjs/tools/BaseTool.mjs +127 -50
  396. package/dist/mjs/tools/Eraser.d.ts +8 -1
  397. package/dist/mjs/tools/Eraser.mjs +72 -86
  398. package/dist/mjs/tools/FindTool.d.ts +1 -1
  399. package/dist/mjs/tools/FindTool.mjs +55 -75
  400. package/dist/mjs/tools/InputFilter/FunctionMapper.d.ts +12 -0
  401. package/dist/mjs/tools/InputFilter/FunctionMapper.mjs +15 -0
  402. package/dist/mjs/tools/InputFilter/InputMapper.d.ts +23 -0
  403. package/dist/mjs/tools/InputFilter/InputMapper.mjs +36 -0
  404. package/dist/mjs/tools/InputFilter/InputPipeline.d.ts +15 -0
  405. package/dist/mjs/tools/InputFilter/InputPipeline.mjs +49 -0
  406. package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +29 -0
  407. package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +175 -0
  408. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +21 -0
  409. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +78 -0
  410. package/dist/mjs/tools/PanZoom.d.ts +4 -2
  411. package/dist/mjs/tools/PanZoom.mjs +169 -235
  412. package/dist/mjs/tools/PasteHandler.d.ts +1 -1
  413. package/dist/mjs/tools/PasteHandler.mjs +42 -145
  414. package/dist/mjs/tools/Pen.d.ts +12 -11
  415. package/dist/mjs/tools/Pen.mjs +115 -154
  416. package/dist/mjs/tools/PipetteTool.d.ts +11 -2
  417. package/dist/mjs/tools/PipetteTool.mjs +47 -48
  418. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +1 -1
  419. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +9 -28
  420. package/dist/mjs/tools/SelectionTool/Selection.d.ts +5 -5
  421. package/dist/mjs/tools/SelectionTool/Selection.mjs +268 -401
  422. package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +15 -5
  423. package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +62 -37
  424. package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +4 -4
  425. package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +153 -179
  426. package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +1 -1
  427. package/dist/mjs/tools/SelectionTool/TransformMode.mjs +52 -59
  428. package/dist/mjs/tools/SoundUITool.d.ts +2 -1
  429. package/dist/mjs/tools/SoundUITool.mjs +66 -84
  430. package/dist/mjs/tools/TextTool.d.ts +5 -3
  431. package/dist/mjs/tools/TextTool.mjs +155 -163
  432. package/dist/mjs/tools/ToolController.d.ts +16 -2
  433. package/dist/mjs/tools/ToolController.mjs +81 -84
  434. package/dist/mjs/tools/ToolEnabledGroup.mjs +6 -10
  435. package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +1 -1
  436. package/dist/mjs/tools/ToolSwitcherShortcut.mjs +12 -32
  437. package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +1 -1
  438. package/dist/mjs/tools/ToolbarShortcutHandler.mjs +13 -33
  439. package/dist/mjs/tools/UndoRedoShortcut.d.ts +1 -1
  440. package/dist/mjs/tools/UndoRedoShortcut.mjs +7 -26
  441. package/dist/mjs/tools/keybindings.mjs +34 -34
  442. package/dist/mjs/tools/localization.d.ts +2 -1
  443. package/dist/mjs/tools/localization.mjs +9 -8
  444. package/dist/mjs/types.d.ts +22 -80
  445. package/dist/mjs/types.mjs +7 -15
  446. package/dist/mjs/util/ReactiveValue.d.ts +65 -0
  447. package/dist/mjs/util/ReactiveValue.mjs +161 -0
  448. package/dist/mjs/util/assertions.mjs +5 -8
  449. package/dist/mjs/util/fileToBase64.mjs +6 -6
  450. package/dist/mjs/util/guessKeyCodeFromKey.d.ts +9 -0
  451. package/dist/mjs/util/guessKeyCodeFromKey.mjs +30 -0
  452. package/dist/mjs/util/listPrefixMatch.d.ts +6 -0
  453. package/dist/mjs/util/listPrefixMatch.mjs +15 -0
  454. package/dist/mjs/util/stopPropagationOfScrollingWheelEvents.d.ts +2 -0
  455. package/dist/mjs/util/stopPropagationOfScrollingWheelEvents.mjs +15 -0
  456. package/dist/mjs/util/untilNextAnimationFrame.mjs +3 -3
  457. package/dist/mjs/util/waitForAll.mjs +3 -3
  458. package/dist/mjs/util/waitForTimeout.mjs +3 -3
  459. package/dist/mjs/version.d.ts +4 -0
  460. package/dist/mjs/version.mjs +3 -0
  461. package/dist-test/test_imports/package.json +1 -1
  462. package/dist-test/test_imports/test-imports.js +5 -11
  463. package/dist-test/test_imports/test-require.cjs +6 -11
  464. package/package.json +11 -22
  465. package/src/Coloris.css +8 -8
  466. package/src/Editor.loadFrom.test.ts +1 -1
  467. package/src/Editor.scss +148 -0
  468. package/src/Editor.test.ts +107 -0
  469. package/src/Editor.toSVG.test.ts +184 -1
  470. package/src/Editor.ts +325 -53
  471. package/src/EditorImage.test.ts +4 -7
  472. package/src/EditorImage.ts +10 -4
  473. package/src/Pointer.ts +18 -5
  474. package/src/SVGLoader.ts +77 -15
  475. package/src/UndoRedoHistory.test.ts +2 -1
  476. package/src/Viewport.ts +1 -4
  477. package/src/commands/Erase.ts +1 -0
  478. package/src/commands/localization.ts +1 -1
  479. package/src/commands/uniteCommands.test.ts +3 -3
  480. package/src/components/AbstractComponent.transformBy.test.ts +2 -1
  481. package/src/components/AbstractComponent.ts +12 -3
  482. package/src/components/BackgroundComponent.test.ts +1 -2
  483. package/src/components/BackgroundComponent.ts +3 -8
  484. package/src/components/ImageComponent.ts +1 -3
  485. package/src/components/RestylableComponent.ts +1 -1
  486. package/src/components/SVGGlobalAttributesObject.ts +1 -3
  487. package/src/components/Stroke.test.ts +4 -6
  488. package/src/components/Stroke.ts +5 -7
  489. package/src/components/TextComponent.test.ts +1 -3
  490. package/src/components/TextComponent.ts +1 -4
  491. package/src/components/UnknownSVGObject.ts +3 -3
  492. package/src/components/builders/ArrowBuilder.ts +1 -2
  493. package/src/components/builders/CircleBuilder.ts +3 -5
  494. package/src/components/builders/FreehandLineBuilder.test.ts +2 -3
  495. package/src/components/builders/FreehandLineBuilder.ts +3 -5
  496. package/src/components/builders/LineBuilder.ts +3 -3
  497. package/src/components/builders/PressureSensitiveFreehandLineBuilder.ts +3 -4
  498. package/src/components/builders/RectangleBuilder.ts +3 -4
  499. package/src/components/builders/types.ts +1 -1
  500. package/src/components/lib.ts +1 -1
  501. package/src/components/util/StrokeSmoother.ts +7 -7
  502. package/src/dialogs/dialogs.scss +36 -0
  503. package/src/dialogs/makeAboutDialog.scss +41 -0
  504. package/src/dialogs/makeAboutDialog.ts +82 -0
  505. package/src/inputEvents.ts +143 -0
  506. package/src/lib.ts +35 -13
  507. package/src/localizations/de.ts +2 -2
  508. package/src/localizations/es.ts +5 -5
  509. package/src/rendering/Display.ts +1 -2
  510. package/src/rendering/RenderablePathSpec.ts +88 -0
  511. package/src/rendering/RenderingStyle.test.ts +1 -1
  512. package/src/rendering/RenderingStyle.ts +1 -1
  513. package/src/rendering/caching/CacheRecord.test.ts +1 -2
  514. package/src/rendering/caching/CacheRecord.ts +1 -2
  515. package/src/rendering/caching/CacheRecordManager.ts +1 -1
  516. package/src/rendering/caching/RenderingCache.test.ts +3 -4
  517. package/src/rendering/caching/RenderingCache.ts +1 -1
  518. package/src/rendering/caching/RenderingCacheNode.ts +1 -2
  519. package/src/rendering/caching/testUtils.ts +1 -1
  520. package/src/rendering/caching/types.ts +3 -3
  521. package/src/rendering/renderers/AbstractRenderer.ts +4 -14
  522. package/src/rendering/renderers/CanvasRenderer.ts +17 -12
  523. package/src/rendering/renderers/DummyRenderer.test.ts +1 -2
  524. package/src/rendering/renderers/DummyRenderer.ts +1 -4
  525. package/src/rendering/renderers/SVGRenderer.ts +68 -11
  526. package/src/rendering/renderers/TextOnlyRenderer.ts +1 -4
  527. package/src/shortcuts/KeyBinding.test.ts +10 -0
  528. package/src/shortcuts/KeyBinding.ts +74 -35
  529. package/src/shortcuts/KeyboardShortcutManager.test.ts +1 -1
  530. package/src/styles.js +1 -1
  531. package/src/testing/sendPenEvent.ts +2 -2
  532. package/src/testing/sendTouchEvent.ts +2 -2
  533. package/src/toolbar/{toolbar.css → AbstractToolbar.scss} +47 -85
  534. package/src/toolbar/AbstractToolbar.ts +542 -0
  535. package/src/toolbar/DropdownToolbar.scss +46 -0
  536. package/src/toolbar/DropdownToolbar.ts +220 -0
  537. package/src/toolbar/EdgeToolbar.scss +511 -0
  538. package/src/toolbar/EdgeToolbar.test.ts +54 -0
  539. package/src/toolbar/EdgeToolbar.ts +543 -0
  540. package/src/toolbar/IconProvider.ts +189 -133
  541. package/src/toolbar/constants.ts +1 -0
  542. package/src/toolbar/lib.ts +4 -2
  543. package/src/toolbar/localization.ts +39 -17
  544. package/src/toolbar/toolbar.scss +11 -0
  545. package/src/toolbar/types.ts +8 -0
  546. package/src/toolbar/widgets/ActionButtonWidget.ts +2 -2
  547. package/src/toolbar/widgets/BaseToolWidget.ts +17 -1
  548. package/src/toolbar/widgets/BaseWidget.ts +179 -112
  549. package/src/toolbar/widgets/DocumentPropertiesWidget.scss +7 -0
  550. package/src/toolbar/widgets/DocumentPropertiesWidget.ts +26 -10
  551. package/src/toolbar/widgets/EraserToolWidget.ts +21 -22
  552. package/src/toolbar/widgets/HandToolWidget.scss +14 -0
  553. package/src/toolbar/widgets/HandToolWidget.ts +21 -32
  554. package/src/toolbar/widgets/InsertImageWidget.scss +41 -0
  555. package/src/toolbar/widgets/InsertImageWidget.ts +90 -65
  556. package/src/toolbar/widgets/PenToolWidget.css +0 -51
  557. package/src/toolbar/widgets/PenToolWidget.ts +106 -146
  558. package/src/toolbar/widgets/SelectionToolWidget.scss +6 -0
  559. package/src/toolbar/widgets/SelectionToolWidget.ts +83 -85
  560. package/src/toolbar/widgets/TextToolWidget.ts +9 -5
  561. package/src/toolbar/widgets/components/components.scss +5 -0
  562. package/src/toolbar/widgets/components/makeColorInput.scss +82 -0
  563. package/src/toolbar/{makeColorInput.ts → widgets/components/makeColorInput.ts} +39 -14
  564. package/src/toolbar/widgets/components/makeFileInput.scss +77 -0
  565. package/src/toolbar/widgets/components/makeFileInput.ts +128 -0
  566. package/src/toolbar/widgets/components/makeGridSelector.scss +60 -0
  567. package/src/toolbar/widgets/components/makeGridSelector.ts +179 -0
  568. package/src/toolbar/widgets/components/makeSeparator.scss +14 -0
  569. package/src/toolbar/widgets/components/makeSeparator.ts +17 -0
  570. package/src/toolbar/widgets/components/makeThicknessSlider.scss +9 -0
  571. package/src/toolbar/widgets/components/makeThicknessSlider.ts +62 -0
  572. package/src/toolbar/widgets/keybindings.ts +1 -3
  573. package/src/toolbar/widgets/layout/DropdownLayoutManager.ts +262 -0
  574. package/src/toolbar/widgets/layout/EdgeToolbarLayoutManager.ts +71 -0
  575. package/src/toolbar/widgets/layout/types.ts +74 -0
  576. package/src/toolbar/widgets/lib.ts +2 -2
  577. package/src/tools/BaseTool.ts +102 -30
  578. package/src/tools/Eraser.test.ts +2 -2
  579. package/src/tools/Eraser.ts +24 -11
  580. package/src/tools/FindTool.css +3 -3
  581. package/src/tools/FindTool.test.ts +67 -0
  582. package/src/tools/FindTool.ts +3 -3
  583. package/src/tools/InputFilter/FunctionMapper.ts +17 -0
  584. package/src/tools/InputFilter/InputMapper.ts +41 -0
  585. package/src/tools/InputFilter/InputPipeline.test.ts +41 -0
  586. package/src/tools/InputFilter/InputPipeline.ts +34 -0
  587. package/src/tools/InputFilter/InputStabilizer.ts +254 -0
  588. package/src/tools/InputFilter/StrokeKeyboardControl.ts +104 -0
  589. package/src/tools/PanZoom.test.ts +3 -13
  590. package/src/tools/PanZoom.ts +33 -10
  591. package/src/tools/PasteHandler.ts +2 -3
  592. package/src/tools/Pen.test.ts +2 -4
  593. package/src/tools/Pen.ts +54 -70
  594. package/src/tools/PipetteTool.ts +31 -2
  595. package/src/tools/SelectionTool/SelectAllShortcutHandler.ts +1 -1
  596. package/src/tools/SelectionTool/Selection.ts +52 -16
  597. package/src/tools/SelectionTool/SelectionHandle.ts +46 -12
  598. package/src/tools/SelectionTool/SelectionTool.css +23 -11
  599. package/src/tools/SelectionTool/SelectionTool.test.ts +130 -21
  600. package/src/tools/SelectionTool/SelectionTool.ts +62 -48
  601. package/src/tools/SelectionTool/TransformMode.ts +1 -3
  602. package/src/tools/SoundUITool.ts +13 -4
  603. package/src/tools/TextTool.ts +29 -30
  604. package/src/tools/ToolController.ts +60 -36
  605. package/src/tools/ToolSwitcherShortcut.ts +1 -1
  606. package/src/tools/ToolbarShortcutHandler.ts +1 -1
  607. package/src/tools/UndoRedoShortcut.test.ts +10 -4
  608. package/src/tools/UndoRedoShortcut.ts +1 -1
  609. package/src/tools/keybindings.ts +17 -17
  610. package/src/tools/localization.ts +4 -2
  611. package/src/tools/tools.scss +4 -0
  612. package/src/types.ts +25 -113
  613. package/src/util/ReactiveValue.test.ts +168 -0
  614. package/src/util/ReactiveValue.ts +241 -0
  615. package/src/util/guessKeyCodeFromKey.ts +36 -0
  616. package/src/util/listPrefixMatch.ts +19 -0
  617. package/src/util/stopPropagationOfScrollingWheelEvents.ts +20 -0
  618. package/src/version.test.ts +12 -0
  619. package/src/version.ts +3 -0
  620. package/tsconfig.json +1 -1
  621. package/typedoc.json +4 -0
  622. package/dist/cjs/Color4.d.ts +0 -69
  623. package/dist/cjs/Color4.js +0 -263
  624. package/dist/cjs/math/Mat33.d.ts +0 -123
  625. package/dist/cjs/math/Mat33.js +0 -340
  626. package/dist/cjs/math/Vec2.d.ts +0 -33
  627. package/dist/cjs/math/Vec2.js +0 -37
  628. package/dist/cjs/math/Vec3.d.ts +0 -106
  629. package/dist/cjs/math/Vec3.js +0 -183
  630. package/dist/cjs/math/lib.d.ts +0 -7
  631. package/dist/cjs/math/lib.js +0 -15
  632. package/dist/cjs/math/polynomial/solveQuadratic.d.ts +0 -9
  633. package/dist/cjs/math/polynomial/solveQuadratic.js +0 -39
  634. package/dist/cjs/math/rounding.d.ts +0 -4
  635. package/dist/cjs/math/rounding.js +0 -140
  636. package/dist/cjs/math/shapes/Abstract2DShape.d.ts +0 -49
  637. package/dist/cjs/math/shapes/Abstract2DShape.js +0 -42
  638. package/dist/cjs/math/shapes/BezierJSWrapper.d.ts +0 -36
  639. package/dist/cjs/math/shapes/BezierJSWrapper.js +0 -109
  640. package/dist/cjs/math/shapes/CubicBezier.d.ts +0 -17
  641. package/dist/cjs/math/shapes/CubicBezier.js +0 -50
  642. package/dist/cjs/math/shapes/LineSegment2.d.ts +0 -70
  643. package/dist/cjs/math/shapes/LineSegment2.js +0 -204
  644. package/dist/cjs/math/shapes/Path.d.ts +0 -93
  645. package/dist/cjs/math/shapes/Path.js +0 -865
  646. package/dist/cjs/math/shapes/PointShape2D.d.ts +0 -18
  647. package/dist/cjs/math/shapes/PointShape2D.js +0 -46
  648. package/dist/cjs/math/shapes/QuadraticBezier.d.ts +0 -34
  649. package/dist/cjs/math/shapes/QuadraticBezier.js +0 -133
  650. package/dist/cjs/math/shapes/Rect2.d.ts +0 -57
  651. package/dist/cjs/math/shapes/Rect2.js +0 -311
  652. package/dist/cjs/math/shapes/Triangle.d.ts +0 -46
  653. package/dist/cjs/math/shapes/Triangle.js +0 -148
  654. package/dist/cjs/toolbar/HTMLToolbar.d.ts +0 -105
  655. package/dist/cjs/toolbar/HTMLToolbar.js +0 -465
  656. package/dist/cjs/toolbar/makeColorInput.d.ts +0 -6
  657. package/dist/mjs/Color4.d.ts +0 -69
  658. package/dist/mjs/Color4.mjs +0 -260
  659. package/dist/mjs/Color4.test.d.ts +0 -1
  660. package/dist/mjs/math/Mat33.d.ts +0 -123
  661. package/dist/mjs/math/Mat33.mjs +0 -338
  662. package/dist/mjs/math/Mat33.test.d.ts +0 -1
  663. package/dist/mjs/math/Vec2.d.ts +0 -33
  664. package/dist/mjs/math/Vec2.mjs +0 -34
  665. package/dist/mjs/math/Vec2.test.d.ts +0 -1
  666. package/dist/mjs/math/Vec3.d.ts +0 -106
  667. package/dist/mjs/math/Vec3.mjs +0 -181
  668. package/dist/mjs/math/Vec3.test.d.ts +0 -1
  669. package/dist/mjs/math/lib.d.ts +0 -7
  670. package/dist/mjs/math/lib.mjs +0 -7
  671. package/dist/mjs/math/polynomial/solveQuadratic.d.ts +0 -9
  672. package/dist/mjs/math/polynomial/solveQuadratic.mjs +0 -37
  673. package/dist/mjs/math/polynomial/solveQuadratic.test.d.ts +0 -1
  674. package/dist/mjs/math/rounding.d.ts +0 -4
  675. package/dist/mjs/math/rounding.mjs +0 -133
  676. package/dist/mjs/math/rounding.test.d.ts +0 -1
  677. package/dist/mjs/math/shapes/Abstract2DShape.d.ts +0 -49
  678. package/dist/mjs/math/shapes/Abstract2DShape.mjs +0 -40
  679. package/dist/mjs/math/shapes/BezierJSWrapper.d.ts +0 -36
  680. package/dist/mjs/math/shapes/BezierJSWrapper.mjs +0 -107
  681. package/dist/mjs/math/shapes/CubicBezier.d.ts +0 -17
  682. package/dist/mjs/math/shapes/CubicBezier.mjs +0 -48
  683. package/dist/mjs/math/shapes/LineSegment2.d.ts +0 -70
  684. package/dist/mjs/math/shapes/LineSegment2.mjs +0 -202
  685. package/dist/mjs/math/shapes/LineSegment2.test.d.ts +0 -1
  686. package/dist/mjs/math/shapes/Path.d.ts +0 -93
  687. package/dist/mjs/math/shapes/Path.fromString.test.d.ts +0 -1
  688. package/dist/mjs/math/shapes/Path.mjs +0 -862
  689. package/dist/mjs/math/shapes/Path.test.d.ts +0 -1
  690. package/dist/mjs/math/shapes/Path.toString.test.d.ts +0 -1
  691. package/dist/mjs/math/shapes/PointShape2D.d.ts +0 -18
  692. package/dist/mjs/math/shapes/PointShape2D.mjs +0 -44
  693. package/dist/mjs/math/shapes/QuadraticBezier.d.ts +0 -34
  694. package/dist/mjs/math/shapes/QuadraticBezier.mjs +0 -131
  695. package/dist/mjs/math/shapes/QuadraticBezier.test.d.ts +0 -1
  696. package/dist/mjs/math/shapes/Rect2.d.ts +0 -57
  697. package/dist/mjs/math/shapes/Rect2.mjs +0 -309
  698. package/dist/mjs/math/shapes/Rect2.test.d.ts +0 -1
  699. package/dist/mjs/math/shapes/Triangle.d.ts +0 -46
  700. package/dist/mjs/math/shapes/Triangle.mjs +0 -146
  701. package/dist/mjs/math/shapes/Triangle.test.d.ts +0 -1
  702. package/dist/mjs/toolbar/HTMLToolbar.d.ts +0 -105
  703. package/dist/mjs/toolbar/HTMLToolbar.mjs +0 -462
  704. package/dist/mjs/toolbar/makeColorInput.d.ts +0 -6
  705. package/src/Color4.test.ts +0 -47
  706. package/src/Color4.ts +0 -304
  707. package/src/Editor.css +0 -98
  708. package/src/math/Mat33.test.ts +0 -244
  709. package/src/math/Mat33.ts +0 -442
  710. package/src/math/Vec2.test.ts +0 -30
  711. package/src/math/Vec2.ts +0 -40
  712. package/src/math/Vec3.test.ts +0 -44
  713. package/src/math/Vec3.ts +0 -218
  714. package/src/math/lib.ts +0 -15
  715. package/src/math/polynomial/solveQuadratic.test.ts +0 -39
  716. package/src/math/polynomial/solveQuadratic.ts +0 -43
  717. package/src/math/rounding.test.ts +0 -65
  718. package/src/math/rounding.ts +0 -156
  719. package/src/math/shapes/Abstract2DShape.ts +0 -63
  720. package/src/math/shapes/BezierJSWrapper.ts +0 -93
  721. package/src/math/shapes/CubicBezier.ts +0 -35
  722. package/src/math/shapes/LineSegment2.test.ts +0 -99
  723. package/src/math/shapes/LineSegment2.ts +0 -231
  724. package/src/math/shapes/Path.fromString.test.ts +0 -223
  725. package/src/math/shapes/Path.test.ts +0 -309
  726. package/src/math/shapes/Path.toString.test.ts +0 -77
  727. package/src/math/shapes/Path.ts +0 -1027
  728. package/src/math/shapes/PointShape2D.ts +0 -33
  729. package/src/math/shapes/QuadraticBezier.test.ts +0 -31
  730. package/src/math/shapes/QuadraticBezier.ts +0 -141
  731. package/src/math/shapes/Rect2.test.ts +0 -209
  732. package/src/math/shapes/Rect2.ts +0 -344
  733. package/src/math/shapes/Triangle.test.ts +0 -61
  734. package/src/math/shapes/Triangle.ts +0 -139
  735. package/src/toolbar/HTMLToolbar.ts +0 -567
  736. package/src/toolbar/widgets/InsertImageWidget.css +0 -44
  737. package/src/tools/tools.css +0 -4
  738. /package/dist/cjs/{Color4.test.d.ts → Editor.test.d.ts} +0 -0
  739. /package/dist/cjs/{math/Mat33.test.d.ts → toolbar/EdgeToolbar.test.d.ts} +0 -0
  740. /package/dist/cjs/{math/Vec2.test.d.ts → tools/FindTool.test.d.ts} +0 -0
  741. /package/dist/cjs/{math/Vec3.test.d.ts → tools/InputFilter/InputPipeline.test.d.ts} +0 -0
  742. /package/dist/cjs/{math/polynomial/solveQuadratic.test.d.ts → util/ReactiveValue.test.d.ts} +0 -0
  743. /package/dist/cjs/{math/rounding.test.d.ts → version.test.d.ts} +0 -0
  744. /package/dist/{cjs/math/shapes/LineSegment2.test.d.ts → mjs/Editor.test.d.ts} +0 -0
  745. /package/dist/{cjs/math/shapes/Path.fromString.test.d.ts → mjs/toolbar/EdgeToolbar.test.d.ts} +0 -0
  746. /package/dist/{cjs/math/shapes/Path.test.d.ts → mjs/toolbar/widgets/layout/types.mjs} +0 -0
  747. /package/dist/{cjs/math/shapes/Path.toString.test.d.ts → mjs/tools/FindTool.test.d.ts} +0 -0
  748. /package/dist/{cjs/math/shapes/QuadraticBezier.test.d.ts → mjs/tools/InputFilter/InputPipeline.test.d.ts} +0 -0
  749. /package/dist/{cjs/math/shapes/Rect2.test.d.ts → mjs/util/ReactiveValue.test.d.ts} +0 -0
  750. /package/dist/{cjs/math/shapes/Triangle.test.d.ts → mjs/version.test.d.ts} +0 -0
@@ -1,89 +1,60 @@
1
1
  "use strict";
2
- var __assign = (this && this.__assign) || function () {
3
- __assign = Object.assign || function(t) {
4
- for (var s, i = 1, n = arguments.length; i < n; i++) {
5
- s = arguments[i];
6
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
- t[p] = s[p];
8
- }
9
- return t;
10
- };
11
- return __assign.apply(this, arguments);
12
- };
13
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
- return new (P || (P = Promise))(function (resolve, reject) {
16
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
- step((generator = generator.apply(thisArg, _arguments || [])).next());
20
- });
21
- };
22
- var __generator = (this && this.__generator) || function (thisArg, body) {
23
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
24
- return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
- function verb(n) { return function (v) { return step([n, v]); }; }
26
- function step(op) {
27
- if (f) throw new TypeError("Generator is already executing.");
28
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
- if (y = 0, t) op = [op[0] & 2, t.value];
31
- switch (op[0]) {
32
- case 0: case 1: t = op; break;
33
- case 4: _.label++; return { value: op[1], done: false };
34
- case 5: _.label++; y = op[1]; op = [0]; continue;
35
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
- default:
37
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
- if (t[2]) _.ops.pop();
42
- _.trys.pop(); continue;
43
- }
44
- op = body.call(thisArg, _);
45
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
47
7
  }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
48
24
  };
49
- var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
50
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
51
- if (ar || !(i in from)) {
52
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
53
- ar[i] = from[i];
54
- }
55
- }
56
- return to.concat(ar || Array.prototype.slice.call(from));
25
+ var __importDefault = (this && this.__importDefault) || function (mod) {
26
+ return (mod && mod.__esModule) ? mod : { "default": mod };
57
27
  };
58
28
  Object.defineProperty(exports, "__esModule", { value: true });
59
29
  exports.Editor = void 0;
60
- var EditorImage_1 = require("./EditorImage");
61
- var ToolController_1 = require("./tools/ToolController");
62
- var types_1 = require("./types");
63
- var UndoRedoHistory_1 = require("./UndoRedoHistory");
64
- var Viewport_1 = require("./Viewport");
65
- var EventDispatcher_1 = require("./EventDispatcher");
66
- var Vec2_1 = require("./math/Vec2");
67
- var Vec3_1 = require("./math/Vec3");
68
- var HTMLToolbar_1 = require("./toolbar/HTMLToolbar");
69
- var Display_1 = require("./rendering/Display");
70
- var SVGRenderer_1 = require("./rendering/renderers/SVGRenderer");
71
- var Color4_1 = require("./Color4");
72
- var SVGLoader_1 = require("./SVGLoader");
73
- var Pointer_1 = require("./Pointer");
74
- var Mat33_1 = require("./math/Mat33");
75
- var getLocalizationTable_1 = require("./localizations/getLocalizationTable");
76
- var IconProvider_1 = require("./toolbar/IconProvider");
77
- var rounding_1 = require("./math/rounding");
78
- var CanvasRenderer_1 = require("./rendering/renderers/CanvasRenderer");
79
- var untilNextAnimationFrame_1 = require("./util/untilNextAnimationFrame");
80
- var fileToBase64_1 = require("./util/fileToBase64");
81
- var uniteCommands_1 = require("./commands/uniteCommands");
82
- var SelectionTool_1 = require("./tools/SelectionTool/SelectionTool");
83
- var Erase_1 = require("./commands/Erase");
84
- var BackgroundComponent_1 = require("./components/BackgroundComponent");
85
- var sendPenEvent_1 = require("./testing/sendPenEvent");
86
- var KeyboardShortcutManager_1 = require("./shortcuts/KeyboardShortcutManager");
30
+ const EditorImage_1 = __importDefault(require("./EditorImage"));
31
+ const ToolController_1 = __importDefault(require("./tools/ToolController"));
32
+ const types_1 = require("./types");
33
+ const inputEvents_1 = require("./inputEvents");
34
+ const UndoRedoHistory_1 = __importDefault(require("./UndoRedoHistory"));
35
+ const Viewport_1 = __importDefault(require("./Viewport"));
36
+ const EventDispatcher_1 = __importDefault(require("./EventDispatcher"));
37
+ const math_1 = require("@js-draw/math");
38
+ const Display_1 = __importStar(require("./rendering/Display"));
39
+ const SVGRenderer_1 = __importDefault(require("./rendering/renderers/SVGRenderer"));
40
+ const SVGLoader_1 = __importDefault(require("./SVGLoader"));
41
+ const Pointer_1 = __importDefault(require("./Pointer"));
42
+ const getLocalizationTable_1 = __importDefault(require("./localizations/getLocalizationTable"));
43
+ const IconProvider_1 = __importDefault(require("./toolbar/IconProvider"));
44
+ const CanvasRenderer_1 = __importDefault(require("./rendering/renderers/CanvasRenderer"));
45
+ const untilNextAnimationFrame_1 = __importDefault(require("./util/untilNextAnimationFrame"));
46
+ const fileToBase64_1 = __importDefault(require("./util/fileToBase64"));
47
+ const uniteCommands_1 = __importDefault(require("./commands/uniteCommands"));
48
+ const SelectionTool_1 = __importDefault(require("./tools/SelectionTool/SelectionTool"));
49
+ const Erase_1 = __importDefault(require("./commands/Erase"));
50
+ const BackgroundComponent_1 = __importStar(require("./components/BackgroundComponent"));
51
+ const sendPenEvent_1 = __importDefault(require("./testing/sendPenEvent"));
52
+ const KeyboardShortcutManager_1 = __importDefault(require("./shortcuts/KeyboardShortcutManager"));
53
+ const EdgeToolbar_1 = __importDefault(require("./toolbar/EdgeToolbar"));
54
+ const StrokeKeyboardControl_1 = __importDefault(require("./tools/InputFilter/StrokeKeyboardControl"));
55
+ const guessKeyCodeFromKey_1 = __importDefault(require("./util/guessKeyCodeFromKey"));
56
+ const makeAboutDialog_1 = __importDefault(require("./dialogs/makeAboutDialog"));
57
+ const version_1 = __importDefault(require("./version"));
87
58
  /**
88
59
  * The main entrypoint for the full editor.
89
60
  *
@@ -102,7 +73,7 @@ var KeyboardShortcutManager_1 = require("./shortcuts/KeyboardShortcutManager");
102
73
  * See also
103
74
  * [`docs/example/example.ts`](https://github.com/personalizedrefrigerator/js-draw/blob/main/docs/demo/example.ts#L15).
104
75
  */
105
- var Editor = /** @class */ (function () {
76
+ class Editor {
106
77
  /**
107
78
  * @example
108
79
  * ```
@@ -128,39 +99,41 @@ var Editor = /** @class */ (function () {
128
99
  * });
129
100
  * ```
130
101
  */
131
- function Editor(parent, settings) {
132
- if (settings === void 0) { settings = {}; }
133
- var _this = this;
134
- var _a, _b, _c, _d, _e, _f;
102
+ constructor(parent, settings = {}) {
135
103
  this.eventListenerTargets = [];
136
104
  this.previousAccessibilityAnnouncement = '';
137
105
  this.pointers = {};
138
- this.announceUndoCallback = function (command) {
139
- _this.announceForAccessibility(_this.localization.undoAnnouncement(command.description(_this, _this.localization)));
106
+ this.announceUndoCallback = (command) => {
107
+ this.announceForAccessibility(this.localization.undoAnnouncement(command.description(this, this.localization)));
140
108
  };
141
- this.announceRedoCallback = function (command) {
142
- _this.announceForAccessibility(_this.localization.redoAnnouncement(command.description(_this, _this.localization)));
109
+ this.announceRedoCallback = (command) => {
110
+ this.announceForAccessibility(this.localization.redoAnnouncement(command.description(this, this.localization)));
143
111
  };
144
112
  // Listeners to be called once at the end of the next re-render.
145
113
  this.nextRerenderListeners = [];
146
114
  this.rerenderQueued = false;
147
- this.localization = __assign(__assign({}, (0, getLocalizationTable_1.default)()), settings.localization);
115
+ this.closeAboutDialog = null;
116
+ this.localization = {
117
+ ...(0, getLocalizationTable_1.default)(),
118
+ ...settings.localization,
119
+ };
148
120
  // Fill default settings.
149
121
  this.settings = {
150
- wheelEventsEnabled: (_a = settings.wheelEventsEnabled) !== null && _a !== void 0 ? _a : true,
151
- renderingMode: (_b = settings.renderingMode) !== null && _b !== void 0 ? _b : Display_1.RenderingMode.CanvasRenderer,
122
+ wheelEventsEnabled: settings.wheelEventsEnabled ?? true,
123
+ renderingMode: settings.renderingMode ?? Display_1.RenderingMode.CanvasRenderer,
152
124
  localization: this.localization,
153
- minZoom: (_c = settings.minZoom) !== null && _c !== void 0 ? _c : 2e-10,
154
- maxZoom: (_d = settings.maxZoom) !== null && _d !== void 0 ? _d : 1e12,
155
- keyboardShortcutOverrides: (_e = settings.keyboardShortcutOverrides) !== null && _e !== void 0 ? _e : {},
156
- iconProvider: (_f = settings.iconProvider) !== null && _f !== void 0 ? _f : new IconProvider_1.default(),
125
+ minZoom: settings.minZoom ?? 2e-10,
126
+ maxZoom: settings.maxZoom ?? 1e12,
127
+ keyboardShortcutOverrides: settings.keyboardShortcutOverrides ?? {},
128
+ iconProvider: settings.iconProvider ?? new IconProvider_1.default(),
129
+ notices: [],
157
130
  };
158
131
  this.icons = this.settings.iconProvider;
159
132
  this.shortcuts = new KeyboardShortcutManager_1.default(this.settings.keyboardShortcutOverrides);
160
133
  this.container = document.createElement('div');
161
134
  this.renderingRegion = document.createElement('div');
162
135
  this.container.appendChild(this.renderingRegion);
163
- this.container.className = 'imageEditorContainer';
136
+ this.container.classList.add('imageEditorContainer', 'js-draw');
164
137
  this.loadingWarning = document.createElement('div');
165
138
  this.loadingWarning.classList.add('loadingMessage');
166
139
  this.loadingWarning.ariaLive = 'polite';
@@ -181,33 +154,35 @@ var Editor = /** @class */ (function () {
181
154
  this.renderingRegion.setAttribute('tabIndex', '0');
182
155
  this.renderingRegion.setAttribute('alt', '');
183
156
  this.notifier = new EventDispatcher_1.default();
184
- this.viewport = new Viewport_1.default(function (oldTransform, newTransform) {
185
- _this.notifier.dispatch(types_1.EditorEventType.ViewportChanged, {
157
+ this.viewport = new Viewport_1.default((oldTransform, newTransform) => {
158
+ this.notifier.dispatch(types_1.EditorEventType.ViewportChanged, {
186
159
  kind: types_1.EditorEventType.ViewportChanged,
187
- newTransform: newTransform,
188
- oldTransform: oldTransform,
160
+ newTransform,
161
+ oldTransform,
189
162
  });
190
163
  });
191
164
  this.display = new Display_1.default(this, this.settings.renderingMode, this.renderingRegion);
192
165
  this.image = new EditorImage_1.default();
193
166
  this.history = new UndoRedoHistory_1.default(this, this.announceRedoCallback, this.announceUndoCallback);
194
167
  this.toolController = new ToolController_1.default(this, this.localization);
168
+ // TODO: Make this pipeline configurable (e.g. allow users to add global input stabilization)
169
+ this.toolController.addInputMapper(StrokeKeyboardControl_1.default.fromEditor(this));
195
170
  parent.appendChild(this.container);
196
- this.viewport.updateScreenSize(Vec2_1.Vec2.of(this.display.width, this.display.height));
171
+ this.viewport.updateScreenSize(math_1.Vec2.of(this.display.width, this.display.height));
197
172
  this.registerListeners();
198
173
  this.queueRerender();
199
174
  this.hideLoadingWarning();
200
175
  // Enforce zoom limits.
201
- this.notifier.on(types_1.EditorEventType.ViewportChanged, function (evt) {
176
+ this.notifier.on(types_1.EditorEventType.ViewportChanged, evt => {
202
177
  if (evt.kind === types_1.EditorEventType.ViewportChanged) {
203
- var zoom = evt.newTransform.transformVec3(Vec2_1.Vec2.unitX).length();
204
- if (zoom > _this.settings.maxZoom || zoom < _this.settings.minZoom) {
205
- var oldZoom = evt.oldTransform.transformVec3(Vec2_1.Vec2.unitX).length();
206
- var resetTransform = Mat33_1.default.identity;
207
- if (oldZoom <= _this.settings.maxZoom && oldZoom >= _this.settings.minZoom) {
178
+ const zoom = evt.newTransform.transformVec3(math_1.Vec2.unitX).length();
179
+ if (zoom > this.settings.maxZoom || zoom < this.settings.minZoom) {
180
+ const oldZoom = evt.oldTransform.transformVec3(math_1.Vec2.unitX).length();
181
+ let resetTransform = math_1.Mat33.identity;
182
+ if (oldZoom <= this.settings.maxZoom && oldZoom >= this.settings.minZoom) {
208
183
  resetTransform = evt.oldTransform;
209
184
  }
210
- _this.viewport.resetTransform(resetTransform);
185
+ this.viewport.resetTransform(resetTransform);
211
186
  }
212
187
  }
213
188
  });
@@ -221,57 +196,55 @@ var Editor = /** @class */ (function () {
221
196
  * editor.getRootElement().style.height = '500px';
222
197
  * ```
223
198
  */
224
- Editor.prototype.getRootElement = function () {
199
+ getRootElement() {
225
200
  return this.container;
226
- };
201
+ }
227
202
  /** @param fractionLoaded - should be a number from 0 to 1, where 1 represents completely loaded. */
228
- Editor.prototype.showLoadingWarning = function (fractionLoaded) {
229
- var loadingPercent = Math.round(fractionLoaded * 100);
203
+ showLoadingWarning(fractionLoaded) {
204
+ const loadingPercent = Math.round(fractionLoaded * 100);
230
205
  this.loadingWarning.innerText = this.localization.loading(loadingPercent);
231
206
  this.loadingWarning.style.display = 'block';
232
- };
233
- Editor.prototype.hideLoadingWarning = function () {
207
+ }
208
+ hideLoadingWarning() {
234
209
  this.loadingWarning.style.display = 'none';
235
210
  this.announceForAccessibility(this.localization.doneLoading);
236
- };
211
+ }
237
212
  /**
238
213
  * Announce `message` for screen readers. If `message` is the same as the previous
239
214
  * message, it is re-announced.
240
215
  */
241
- Editor.prototype.announceForAccessibility = function (message) {
216
+ announceForAccessibility(message) {
242
217
  // Force re-announcing an announcement if announced again.
243
218
  if (message === this.previousAccessibilityAnnouncement) {
244
219
  message = message + '. ';
245
220
  }
246
221
  this.accessibilityAnnounceArea.innerText = message;
247
222
  this.previousAccessibilityAnnouncement = message;
248
- };
223
+ }
249
224
  /**
250
225
  * Creates a toolbar. If `defaultLayout` is true, default buttons are used.
251
226
  * @returns a reference to the toolbar.
252
227
  */
253
- Editor.prototype.addToolbar = function (defaultLayout) {
254
- if (defaultLayout === void 0) { defaultLayout = true; }
255
- var toolbar = new HTMLToolbar_1.default(this, this.container, this.localization);
228
+ addToolbar(defaultLayout = true) {
229
+ const toolbar = new EdgeToolbar_1.default(this, this.container, this.localization);
256
230
  if (defaultLayout) {
257
231
  toolbar.addDefaults();
258
232
  }
259
233
  return toolbar;
260
- };
261
- Editor.prototype.registerListeners = function () {
262
- var _this = this;
234
+ }
235
+ registerListeners() {
263
236
  this.handlePointerEventsFrom(this.renderingRegion);
264
237
  this.handleKeyEventsFrom(this.renderingRegion);
265
- this.container.addEventListener('wheel', function (evt) {
266
- var delta = Vec3_1.default.of(evt.deltaX, evt.deltaY, evt.deltaZ);
238
+ this.container.addEventListener('wheel', evt => {
239
+ let delta = math_1.Vec3.of(evt.deltaX, evt.deltaY, evt.deltaZ);
267
240
  // Process wheel events if the ctrl key is down, even if disabled -- we do want to handle
268
241
  // pinch-zooming.
269
242
  if (!evt.ctrlKey && !evt.metaKey) {
270
- if (!_this.settings.wheelEventsEnabled) {
243
+ if (!this.settings.wheelEventsEnabled) {
271
244
  return;
272
245
  }
273
- else if (_this.settings.wheelEventsEnabled === 'only-if-focused') {
274
- var focusedChild = _this.container.querySelector(':focus');
246
+ else if (this.settings.wheelEventsEnabled === 'only-if-focused') {
247
+ const focusedChild = this.container.querySelector(':focus');
275
248
  if (!focusedChild) {
276
249
  return;
277
250
  }
@@ -284,14 +257,14 @@ var Editor = /** @class */ (function () {
284
257
  delta = delta.times(100);
285
258
  }
286
259
  if (evt.ctrlKey || evt.metaKey) {
287
- delta = Vec3_1.default.of(0, 0, evt.deltaY);
260
+ delta = math_1.Vec3.of(0, 0, evt.deltaY);
288
261
  }
289
262
  // Ensure that `pos` is relative to `this.renderingRegion`
290
- var bbox = _this.renderingRegion.getBoundingClientRect();
291
- var pos = Vec2_1.Vec2.of(evt.clientX, evt.clientY).minus(Vec2_1.Vec2.of(bbox.left, bbox.top));
292
- if (_this.toolController.dispatchInputEvent({
293
- kind: types_1.InputEvtType.WheelEvt,
294
- delta: delta,
263
+ const bbox = this.renderingRegion.getBoundingClientRect();
264
+ const pos = math_1.Vec2.of(evt.clientX, evt.clientY).minus(math_1.Vec2.of(bbox.left, bbox.top));
265
+ if (this.toolController.dispatchInputEvent({
266
+ kind: inputEvents_1.InputEvtType.WheelEvt,
267
+ delta,
295
268
  screenPos: pos,
296
269
  })) {
297
270
  evt.preventDefault();
@@ -299,81 +272,82 @@ var Editor = /** @class */ (function () {
299
272
  }
300
273
  return false;
301
274
  });
302
- this.notifier.on(types_1.EditorEventType.DisplayResized, function (_event) {
303
- _this.viewport.updateScreenSize(Vec2_1.Vec2.of(_this.display.width, _this.display.height));
304
- _this.queueRerender();
305
- });
306
- var handleResize = function () {
307
- _this.notifier.dispatch(types_1.EditorEventType.DisplayResized, {
308
- kind: types_1.EditorEventType.DisplayResized,
309
- newSize: Vec2_1.Vec2.of(_this.display.width, _this.display.height),
310
- });
275
+ const handleResize = () => {
276
+ this.viewport.updateScreenSize(math_1.Vec2.of(this.display.width, this.display.height));
277
+ this.rerender();
278
+ this.updateEditorSizeVariables();
311
279
  };
312
280
  if ('ResizeObserver' in window) {
313
- var resizeObserver = new ResizeObserver(handleResize);
281
+ const resizeObserver = new ResizeObserver(handleResize);
282
+ resizeObserver.observe(this.renderingRegion);
314
283
  resizeObserver.observe(this.container);
315
284
  }
316
285
  else {
317
286
  addEventListener('resize', handleResize);
318
287
  }
319
- this.accessibilityControlArea.addEventListener('input', function () {
320
- _this.accessibilityControlArea.value = '';
288
+ this.accessibilityControlArea.addEventListener('input', () => {
289
+ this.accessibilityControlArea.value = '';
321
290
  });
322
- document.addEventListener('copy', function (evt) {
323
- if (!_this.isEventSink(document.querySelector(':focus'))) {
291
+ document.addEventListener('copy', evt => {
292
+ if (!this.isEventSink(document.querySelector(':focus'))) {
324
293
  return;
325
294
  }
326
- var clipboardData = evt.clipboardData;
327
- if (_this.toolController.dispatchInputEvent({
328
- kind: types_1.InputEvtType.CopyEvent,
329
- setData: function (mime, data) {
330
- clipboardData === null || clipboardData === void 0 ? void 0 : clipboardData.setData(mime, data);
295
+ const clipboardData = evt.clipboardData;
296
+ if (this.toolController.dispatchInputEvent({
297
+ kind: inputEvents_1.InputEvtType.CopyEvent,
298
+ setData: (mime, data) => {
299
+ clipboardData?.setData(mime, data);
331
300
  },
332
301
  })) {
333
302
  evt.preventDefault();
334
303
  }
335
304
  });
336
- document.addEventListener('paste', function (evt) {
337
- _this.handlePaste(evt);
305
+ document.addEventListener('paste', evt => {
306
+ this.handlePaste(evt);
338
307
  });
339
- };
340
- Editor.prototype.getPointerList = function () {
341
- var nowTime = (new Date()).getTime();
342
- var res = [];
343
- for (var id in this.pointers) {
344
- var maxUnupdatedTime = 2000; // Maximum time without a pointer update (ms)
308
+ }
309
+ updateEditorSizeVariables() {
310
+ // Add CSS variables so that absolutely-positioned children of the editor can
311
+ // still fill the screen.
312
+ this.container.style.setProperty('--editor-current-width-px', `${this.container.clientWidth}px`);
313
+ this.container.style.setProperty('--editor-current-height-px', `${this.container.clientHeight}px`);
314
+ }
315
+ getPointerList() {
316
+ const nowTime = performance.now();
317
+ const res = [];
318
+ for (const id in this.pointers) {
319
+ const maxUnupdatedTime = 2000; // Maximum time without a pointer update (ms)
345
320
  if (this.pointers[id] && (nowTime - this.pointers[id].timeStamp) < maxUnupdatedTime) {
346
321
  res.push(this.pointers[id]);
347
322
  }
348
323
  }
349
324
  return res;
350
- };
325
+ }
351
326
  /**
352
327
  * Dispatches a `PointerEvent` to the editor. The target element for `evt` must have the same top left
353
328
  * as the content of the editor.
354
329
  */
355
- Editor.prototype.handleHTMLPointerEvent = function (eventType, evt) {
356
- var _a, _b, _c;
357
- var eventsRelativeTo = this.renderingRegion;
358
- var eventTarget = (_a = evt.target) !== null && _a !== void 0 ? _a : this.renderingRegion;
330
+ handleHTMLPointerEvent(eventType, evt) {
331
+ const eventsRelativeTo = this.renderingRegion;
332
+ const eventTarget = evt.target ?? this.renderingRegion;
359
333
  if (eventType === 'pointerdown') {
360
- var pointer = Pointer_1.default.ofEvent(evt, true, this.viewport, eventsRelativeTo);
334
+ const pointer = Pointer_1.default.ofEvent(evt, true, this.viewport, eventsRelativeTo);
361
335
  this.pointers[pointer.id] = pointer;
362
336
  eventTarget.setPointerCapture(pointer.id);
363
- var event_1 = {
364
- kind: types_1.InputEvtType.PointerDownEvt,
337
+ const event = {
338
+ kind: inputEvents_1.InputEvtType.PointerDownEvt,
365
339
  current: pointer,
366
340
  allPointers: this.getPointerList(),
367
341
  };
368
- this.toolController.dispatchInputEvent(event_1);
342
+ this.toolController.dispatchInputEvent(event);
369
343
  return true;
370
344
  }
371
345
  else if (eventType === 'pointermove') {
372
- var pointer = Pointer_1.default.ofEvent(evt, (_c = (_b = this.pointers[evt.pointerId]) === null || _b === void 0 ? void 0 : _b.down) !== null && _c !== void 0 ? _c : false, this.viewport, eventsRelativeTo);
346
+ const pointer = Pointer_1.default.ofEvent(evt, this.pointers[evt.pointerId]?.down ?? false, this.viewport, eventsRelativeTo);
373
347
  if (pointer.down) {
374
- var prevData = this.pointers[pointer.id];
348
+ const prevData = this.pointers[pointer.id];
375
349
  if (prevData) {
376
- var distanceMoved = pointer.screenPos.minus(prevData.screenPos).magnitude();
350
+ const distanceMoved = pointer.screenPos.minus(prevData.screenPos).magnitude();
377
351
  // If the pointer moved less than two pixels, don't send a new event.
378
352
  if (distanceMoved < 2) {
379
353
  return false;
@@ -381,7 +355,7 @@ var Editor = /** @class */ (function () {
381
355
  }
382
356
  this.pointers[pointer.id] = pointer;
383
357
  if (this.toolController.dispatchInputEvent({
384
- kind: types_1.InputEvtType.PointerMoveEvt,
358
+ kind: inputEvents_1.InputEvtType.PointerMoveEvt,
385
359
  current: pointer,
386
360
  allPointers: this.getPointerList(),
387
361
  })) {
@@ -391,14 +365,14 @@ var Editor = /** @class */ (function () {
391
365
  return true;
392
366
  }
393
367
  else if (eventType === 'pointercancel' || eventType === 'pointerup') {
394
- var pointer = Pointer_1.default.ofEvent(evt, false, this.viewport, eventsRelativeTo);
368
+ const pointer = Pointer_1.default.ofEvent(evt, false, this.viewport, eventsRelativeTo);
395
369
  if (!this.pointers[pointer.id]) {
396
370
  return false;
397
371
  }
398
372
  this.pointers[pointer.id] = pointer;
399
373
  eventTarget.releasePointerCapture(pointer.id);
400
374
  if (this.toolController.dispatchInputEvent({
401
- kind: types_1.InputEvtType.PointerUpEvt,
375
+ kind: inputEvents_1.InputEvtType.PointerUpEvt,
402
376
  current: pointer,
403
377
  allPointers: this.getPointerList(),
404
378
  })) {
@@ -408,12 +382,11 @@ var Editor = /** @class */ (function () {
408
382
  return true;
409
383
  }
410
384
  return eventType;
411
- };
412
- Editor.prototype.isEventSink = function (evtTarget) {
413
- var currentElem = evtTarget;
385
+ }
386
+ isEventSink(evtTarget) {
387
+ let currentElem = evtTarget;
414
388
  while (currentElem !== null) {
415
- for (var _i = 0, _a = this.eventListenerTargets; _i < _a.length; _i++) {
416
- var elem = _a[_i];
389
+ for (const elem of this.eventListenerTargets) {
417
390
  if (elem === currentElem) {
418
391
  return true;
419
392
  }
@@ -421,108 +394,84 @@ var Editor = /** @class */ (function () {
421
394
  currentElem = currentElem.parentElement;
422
395
  }
423
396
  return false;
424
- };
425
- Editor.prototype.handlePaste = function (evt) {
426
- var _a, _b;
427
- return __awaiter(this, void 0, void 0, function () {
428
- var target, clipboardData, _i, _c, file, text, _d, _e, file, fileType, onprogress_1, data, e_1, supportedMIMEs, _f, supportedMIMEs_1, mime, data;
429
- var _this = this;
430
- return __generator(this, function (_g) {
431
- switch (_g.label) {
432
- case 0:
433
- target = (_a = document.querySelector(':focus')) !== null && _a !== void 0 ? _a : evt.target;
434
- if (!this.isEventSink(target)) {
435
- return [2 /*return*/];
436
- }
437
- clipboardData = (_b = evt.dataTransfer) !== null && _b !== void 0 ? _b : evt.clipboardData;
438
- if (!clipboardData) {
439
- return [2 /*return*/];
440
- }
441
- _i = 0, _c = clipboardData.files;
442
- _g.label = 1;
443
- case 1:
444
- if (!(_i < _c.length)) return [3 /*break*/, 4];
445
- file = _c[_i];
446
- if (!(file.type.toLowerCase() === 'image/svg+xml')) return [3 /*break*/, 3];
447
- return [4 /*yield*/, file.text()];
448
- case 2:
449
- text = _g.sent();
450
- if (this.toolController.dispatchInputEvent({
451
- kind: types_1.InputEvtType.PasteEvent,
452
- mime: file.type,
453
- data: text,
454
- })) {
455
- evt.preventDefault();
456
- return [2 /*return*/];
457
- }
458
- _g.label = 3;
459
- case 3:
460
- _i++;
461
- return [3 /*break*/, 1];
462
- case 4:
463
- _d = 0, _e = clipboardData.files;
464
- _g.label = 5;
465
- case 5:
466
- if (!(_d < _e.length)) return [3 /*break*/, 11];
467
- file = _e[_d];
468
- fileType = file.type.toLowerCase();
469
- if (!(fileType === 'image/png' || fileType === 'image/jpg')) return [3 /*break*/, 10];
470
- this.showLoadingWarning(0);
471
- onprogress_1 = function (evt) {
472
- _this.showLoadingWarning(evt.loaded / evt.total);
473
- };
474
- _g.label = 6;
475
- case 6:
476
- _g.trys.push([6, 8, , 9]);
477
- return [4 /*yield*/, (0, fileToBase64_1.default)(file, onprogress_1)];
478
- case 7:
479
- data = _g.sent();
480
- if (data && this.toolController.dispatchInputEvent({
481
- kind: types_1.InputEvtType.PasteEvent,
482
- mime: fileType,
483
- data: data,
484
- })) {
485
- evt.preventDefault();
486
- this.hideLoadingWarning();
487
- return [2 /*return*/];
488
- }
489
- return [3 /*break*/, 9];
490
- case 8:
491
- e_1 = _g.sent();
492
- console.error('Error reading image:', e_1);
493
- return [3 /*break*/, 9];
494
- case 9:
397
+ }
398
+ async handlePaste(evt) {
399
+ const target = document.querySelector(':focus') ?? evt.target;
400
+ if (!this.isEventSink(target)) {
401
+ return;
402
+ }
403
+ const clipboardData = evt.dataTransfer ?? evt.clipboardData;
404
+ if (!clipboardData) {
405
+ return;
406
+ }
407
+ // Handle SVG files (prefer to PNG/JPEG)
408
+ for (const file of clipboardData.files) {
409
+ if (file.type.toLowerCase() === 'image/svg+xml') {
410
+ const text = await file.text();
411
+ if (this.toolController.dispatchInputEvent({
412
+ kind: inputEvents_1.InputEvtType.PasteEvent,
413
+ mime: file.type,
414
+ data: text,
415
+ })) {
416
+ evt.preventDefault();
417
+ return;
418
+ }
419
+ }
420
+ }
421
+ // Handle image files.
422
+ for (const file of clipboardData.files) {
423
+ const fileType = file.type.toLowerCase();
424
+ if (fileType === 'image/png' || fileType === 'image/jpg') {
425
+ this.showLoadingWarning(0);
426
+ const onprogress = (evt) => {
427
+ this.showLoadingWarning(evt.loaded / evt.total);
428
+ };
429
+ try {
430
+ const data = await (0, fileToBase64_1.default)(file, onprogress);
431
+ if (data && this.toolController.dispatchInputEvent({
432
+ kind: inputEvents_1.InputEvtType.PasteEvent,
433
+ mime: fileType,
434
+ data: data,
435
+ })) {
436
+ evt.preventDefault();
495
437
  this.hideLoadingWarning();
496
- _g.label = 10;
497
- case 10:
498
- _d++;
499
- return [3 /*break*/, 5];
500
- case 11:
501
- supportedMIMEs = [
502
- 'image/svg+xml',
503
- 'text/plain',
504
- ];
505
- for (_f = 0, supportedMIMEs_1 = supportedMIMEs; _f < supportedMIMEs_1.length; _f++) {
506
- mime = supportedMIMEs_1[_f];
507
- data = clipboardData.getData(mime);
508
- if (data && this.toolController.dispatchInputEvent({
509
- kind: types_1.InputEvtType.PasteEvent,
510
- mime: mime,
511
- data: data,
512
- })) {
513
- evt.preventDefault();
514
- return [2 /*return*/];
515
- }
516
- }
517
- return [2 /*return*/];
438
+ return;
439
+ }
518
440
  }
519
- });
520
- });
521
- };
441
+ catch (e) {
442
+ console.error('Error reading image:', e);
443
+ }
444
+ this.hideLoadingWarning();
445
+ }
446
+ }
447
+ // Supported MIMEs for text data, in order of preference
448
+ const supportedMIMEs = [
449
+ 'image/svg+xml',
450
+ 'text/plain',
451
+ ];
452
+ for (const mime of supportedMIMEs) {
453
+ const data = clipboardData.getData(mime);
454
+ if (data && this.toolController.dispatchInputEvent({
455
+ kind: inputEvents_1.InputEvtType.PasteEvent,
456
+ mime,
457
+ data,
458
+ })) {
459
+ evt.preventDefault();
460
+ return;
461
+ }
462
+ }
463
+ }
522
464
  /**
523
465
  * Forward pointer events from `elem` to this editor. Such that right-click/right-click drag
524
466
  * events are also forwarded, `elem`'s contextmenu is disabled.
525
467
  *
468
+ * `filter` is called once per pointer event, before doing any other processing. If `filter` returns `true` the event is
469
+ * forwarded to the editor.
470
+ *
471
+ * **Note**: `otherEventsFilter` is like `filter`, but is called for other pointer-related
472
+ * events that could also be forwarded to the editor. To forward just pointer events,
473
+ * for example, `otherEventsFilter` could be given as `()=>false`.
474
+ *
526
475
  * @example
527
476
  * ```ts
528
477
  * const overlay = document.createElement('div');
@@ -538,94 +487,196 @@ var Editor = /** @class */ (function () {
538
487
  * });
539
488
  * ```
540
489
  */
541
- Editor.prototype.handlePointerEventsFrom = function (elem, filter) {
542
- var _this = this;
490
+ handlePointerEventsFrom(elem, filter, otherEventsFilter) {
543
491
  // May be required to prevent text selection on iOS/Safari:
544
492
  // See https://stackoverflow.com/a/70992717/17055750
545
- var touchstartListener = function (evt) { return evt.preventDefault(); };
546
- var contextmenuListener = function (evt) {
493
+ const touchstartListener = (evt) => {
494
+ if (otherEventsFilter && !otherEventsFilter('touchstart', evt)) {
495
+ return;
496
+ }
497
+ evt.preventDefault();
498
+ };
499
+ const contextmenuListener = (evt) => {
500
+ if (otherEventsFilter && !otherEventsFilter('contextmenu', evt)) {
501
+ return;
502
+ }
547
503
  // Don't show a context menu
548
504
  evt.preventDefault();
549
505
  };
550
- var listeners = {
506
+ const listeners = {
551
507
  'touchstart': touchstartListener,
552
508
  'contextmenu': contextmenuListener,
553
509
  };
554
- var eventNames = ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'];
555
- var _loop_1 = function (eventName) {
556
- listeners[eventName] = function (evt) {
510
+ const eventNames = ['pointerdown', 'pointermove', 'pointerup', 'pointercancel'];
511
+ for (const eventName of eventNames) {
512
+ listeners[eventName] = (evt) => {
557
513
  // This listener will only be called in the context of PointerEvents.
558
- var event = evt;
514
+ const event = evt;
559
515
  if (filter && !filter(eventName, event)) {
560
- return true;
516
+ return undefined;
561
517
  }
562
- return _this.handleHTMLPointerEvent(eventName, event);
518
+ return this.handleHTMLPointerEvent(eventName, event);
563
519
  };
564
- };
565
- for (var _i = 0, eventNames_1 = eventNames; _i < eventNames_1.length; _i++) {
566
- var eventName = eventNames_1[_i];
567
- _loop_1(eventName);
568
520
  }
569
521
  // Add all listeners.
570
- for (var eventName in listeners) {
522
+ for (const eventName in listeners) {
571
523
  elem.addEventListener(eventName, listeners[eventName]);
572
524
  }
573
525
  return {
574
526
  /** Remove all event listeners registered by this function. */
575
- remove: function () {
576
- for (var eventName in listeners) {
527
+ remove: () => {
528
+ for (const eventName in listeners) {
577
529
  elem.removeEventListener(eventName, listeners[eventName]);
578
530
  }
579
531
  },
580
532
  };
581
- };
582
- /** Adds event listners for keypresses to `elem` and forwards those events to the editor. */
583
- Editor.prototype.handleKeyEventsFrom = function (elem) {
584
- var _this = this;
585
- elem.addEventListener('keydown', function (evt) {
586
- if (evt.key === 't' || evt.key === 'T') {
587
- evt.preventDefault();
588
- _this.display.rerenderAsText();
533
+ }
534
+ /**
535
+ * Like {@link handlePointerEventsFrom} except ignores short input gestures like clicks.
536
+ *
537
+ * `filter` is called once per event, before doing any other processing. If `filter` returns `true` the event is
538
+ * forwarded to the editor.
539
+ *
540
+ * `otherEventsFilter` is passed unmodified to `handlePointerEventsFrom`.
541
+ */
542
+ handlePointerEventsExceptClicksFrom(elem, filter, otherEventsFilter) {
543
+ // Maps pointer IDs to gesture start points
544
+ const gestureData = Object.create(null);
545
+ return this.handlePointerEventsFrom(elem, (eventName, event) => {
546
+ if (filter && !filter(eventName, event)) {
547
+ return false;
589
548
  }
590
- else if (_this.toolController.dispatchInputEvent({
591
- kind: types_1.InputEvtType.KeyPressEvent,
592
- key: evt.key,
593
- ctrlKey: evt.ctrlKey || evt.metaKey,
594
- altKey: evt.altKey,
595
- })) {
596
- evt.preventDefault();
549
+ // Position of the current event.
550
+ const currentPos = math_1.Vec2.of(event.pageX, event.pageY);
551
+ const pointerId = event.pointerId ?? 0;
552
+ // Whether to send the current event to the editor
553
+ let sendToEditor = true;
554
+ if (eventName === 'pointerdown') {
555
+ // Buffer the event, but don't send it to the editor yet.
556
+ // We don't want to send single-click events, but we do want to send full strokes.
557
+ gestureData[pointerId] = {
558
+ eventBuffer: [[eventName, event]],
559
+ startPoint: currentPos,
560
+ };
561
+ // Capture the pointer so we receive future events even if the overlay is hidden.
562
+ elem.setPointerCapture(event.pointerId);
563
+ // Don't send to the editor.
564
+ sendToEditor = false;
565
+ }
566
+ else if (eventName === 'pointermove' && gestureData[pointerId]) {
567
+ const gestureStartPos = gestureData[pointerId].startPoint;
568
+ const eventBuffer = gestureData[pointerId].eventBuffer;
569
+ // Skip if the pointer hasn't moved enough to not be a "click".
570
+ const strokeStartThreshold = 10;
571
+ const isWithinClickThreshold = gestureStartPos && currentPos.minus(gestureStartPos).magnitude() < strokeStartThreshold;
572
+ if (isWithinClickThreshold) {
573
+ eventBuffer.push([eventName, event]);
574
+ sendToEditor = false;
575
+ }
576
+ else {
577
+ // Send all buffered events to the editor -- start the stroke.
578
+ for (const [eventName, event] of eventBuffer) {
579
+ this.handleHTMLPointerEvent(eventName, event);
580
+ }
581
+ gestureData[pointerId].eventBuffer = [];
582
+ sendToEditor = true;
583
+ }
584
+ }
585
+ // Pointers that aren't down -- send to the editor.
586
+ else if (eventName === 'pointermove') {
587
+ sendToEditor = true;
588
+ }
589
+ // Otherwise, if we received a pointerup/pointercancel without flushing all pointerevents from the
590
+ // buffer, the gesture wasn't recognised as a stroke. Thus, the editor isn't expecting a pointerup/
591
+ // pointercancel event.
592
+ else if ((eventName === 'pointerup' || eventName === 'pointercancel')
593
+ && gestureData[pointerId] && gestureData[pointerId].eventBuffer.length > 0) {
594
+ elem.releasePointerCapture(event.pointerId);
595
+ // Don't send to the editor.
596
+ sendToEditor = false;
597
+ delete gestureData[pointerId];
598
+ }
599
+ // Forward all other events to the editor.
600
+ return sendToEditor;
601
+ }, otherEventsFilter);
602
+ }
603
+ /**
604
+ * Adds event listners for keypresses (and drop events) on `elem` and forwards those
605
+ * events to the editor.
606
+ *
607
+ * If the given `filter` returns `false` for an event, the event is ignored and not
608
+ * passed to the editor.
609
+ */
610
+ handleKeyEventsFrom(elem, filter = () => true) {
611
+ // Track which keys are down so we can release them when the element
612
+ // loses focus. This is particularly important for keys like Control
613
+ // that can trigger shortcuts that cause the editor to lose focus before
614
+ // the keyup event is triggered.
615
+ let keysDown = [];
616
+ // Return whether two objects that are similar to keyboard events represent the
617
+ // same key.
618
+ const keyEventsMatch = (a, b) => {
619
+ return a.key === b.key && a.code === b.code;
620
+ };
621
+ elem.addEventListener('keydown', htmlEvent => {
622
+ if (!filter(htmlEvent)) {
623
+ return;
624
+ }
625
+ const event = (0, inputEvents_1.keyPressEventFromHTMLEvent)(htmlEvent);
626
+ // Add event to the list of keys that are down (so long as it
627
+ // isn't a duplicate).
628
+ if (!keysDown.some(other => keyEventsMatch(other, event))) {
629
+ keysDown.push(event);
597
630
  }
598
- else if (evt.key === 'Escape') {
599
- _this.renderingRegion.blur();
631
+ if (event.key === 't' || event.key === 'T') {
632
+ htmlEvent.preventDefault();
633
+ this.display.rerenderAsText();
634
+ }
635
+ else if (this.toolController.dispatchInputEvent(event)) {
636
+ htmlEvent.preventDefault();
637
+ }
638
+ else if (event.key === 'Escape') {
639
+ this.renderingRegion.blur();
600
640
  }
601
641
  });
602
- elem.addEventListener('keyup', function (evt) {
603
- if (_this.toolController.dispatchInputEvent({
604
- kind: types_1.InputEvtType.KeyUpEvent,
605
- key: evt.key,
606
- ctrlKey: evt.ctrlKey || evt.metaKey,
607
- altKey: evt.altKey,
608
- })) {
609
- evt.preventDefault();
642
+ elem.addEventListener('keyup', htmlEvent => {
643
+ // Remove the key from keysDown -- it's no longer down.
644
+ keysDown = keysDown.filter(event => {
645
+ const matches = keyEventsMatch(event, htmlEvent);
646
+ return !matches;
647
+ });
648
+ if (!filter(htmlEvent)) {
649
+ return;
650
+ }
651
+ const event = (0, inputEvents_1.keyUpEventFromHTMLEvent)(htmlEvent);
652
+ if (this.toolController.dispatchInputEvent(event)) {
653
+ htmlEvent.preventDefault();
654
+ }
655
+ });
656
+ elem.addEventListener('blur', () => {
657
+ for (const event of keysDown) {
658
+ this.toolController.dispatchInputEvent({
659
+ ...event,
660
+ kind: inputEvents_1.InputEvtType.KeyUpEvent,
661
+ });
610
662
  }
611
663
  });
612
664
  // Allow drop.
613
- elem.ondragover = function (evt) {
665
+ elem.ondragover = evt => {
614
666
  evt.preventDefault();
615
667
  };
616
- elem.ondrop = function (evt) {
668
+ elem.ondrop = evt => {
617
669
  evt.preventDefault();
618
- _this.handlePaste(evt);
670
+ this.handlePaste(evt);
619
671
  };
620
672
  this.eventListenerTargets.push(elem);
621
- };
673
+ }
622
674
  /** `apply` a command. `command` will be announced for accessibility. */
623
- Editor.prototype.dispatch = function (command, addToHistory) {
624
- if (addToHistory === void 0) { addToHistory = true; }
625
- var dispatchResult = this.dispatchNoAnnounce(command, addToHistory);
675
+ dispatch(command, addToHistory = true) {
676
+ const dispatchResult = this.dispatchNoAnnounce(command, addToHistory);
626
677
  this.announceForAccessibility(command.description(this, this.localization));
627
678
  return dispatchResult;
628
- };
679
+ }
629
680
  /**
630
681
  * Dispatches a command without announcing it. By default, does not add to history.
631
682
  * Use this to show finalized commands that don't need to have `announceForAccessibility`
@@ -641,158 +692,132 @@ var Editor = /** @class */ (function () {
641
692
  * editor.dispatchNoAnnounce(editor.viewport.zoomTo(someRectangle), addToHistory);
642
693
  * ```
643
694
  */
644
- Editor.prototype.dispatchNoAnnounce = function (command, addToHistory) {
645
- if (addToHistory === void 0) { addToHistory = false; }
646
- var result = command.apply(this);
695
+ dispatchNoAnnounce(command, addToHistory = false) {
696
+ const result = command.apply(this);
647
697
  if (addToHistory) {
648
- var apply = false; // Don't double-apply
698
+ const apply = false; // Don't double-apply
649
699
  this.history.push(command, apply);
650
700
  }
651
701
  return result;
652
- };
702
+ }
653
703
  /**
654
704
  * Apply a large transformation in chunks.
655
705
  * If `apply` is `false`, the commands are unapplied.
656
706
  * Triggers a re-render after each `updateChunkSize`-sized group of commands
657
707
  * has been applied.
658
708
  */
659
- Editor.prototype.asyncApplyOrUnapplyCommands = function (commands, apply, updateChunkSize) {
660
- return __awaiter(this, void 0, void 0, function () {
661
- var i, j, cmd;
662
- var _this = this;
663
- return __generator(this, function (_a) {
664
- switch (_a.label) {
665
- case 0:
666
- console.assert(updateChunkSize > 0);
667
- this.display.setDraftMode(true);
668
- i = 0;
669
- _a.label = 1;
670
- case 1:
671
- if (!(i < commands.length)) return [3 /*break*/, 4];
672
- this.showLoadingWarning(i / commands.length);
673
- for (j = i; j < commands.length && j < i + updateChunkSize; j++) {
674
- cmd = commands[j];
675
- if (apply) {
676
- cmd.apply(this);
677
- }
678
- else {
679
- cmd.unapply(this);
680
- }
681
- }
682
- if (!(i + updateChunkSize < commands.length)) return [3 /*break*/, 3];
683
- return [4 /*yield*/, new Promise(function (resolve) {
684
- _this.rerender();
685
- requestAnimationFrame(resolve);
686
- })];
687
- case 2:
688
- _a.sent();
689
- _a.label = 3;
690
- case 3:
691
- i += updateChunkSize;
692
- return [3 /*break*/, 1];
693
- case 4:
694
- this.display.setDraftMode(false);
695
- this.hideLoadingWarning();
696
- return [2 /*return*/];
709
+ async asyncApplyOrUnapplyCommands(commands, apply, updateChunkSize) {
710
+ console.assert(updateChunkSize > 0);
711
+ this.display.setDraftMode(true);
712
+ for (let i = 0; i < commands.length; i += updateChunkSize) {
713
+ this.showLoadingWarning(i / commands.length);
714
+ for (let j = i; j < commands.length && j < i + updateChunkSize; j++) {
715
+ const cmd = commands[j];
716
+ if (apply) {
717
+ cmd.apply(this);
697
718
  }
698
- });
699
- });
700
- };
719
+ else {
720
+ cmd.unapply(this);
721
+ }
722
+ }
723
+ // Re-render to show progress, but only if we're not done.
724
+ if (i + updateChunkSize < commands.length) {
725
+ await new Promise(resolve => {
726
+ this.rerender();
727
+ requestAnimationFrame(resolve);
728
+ });
729
+ }
730
+ }
731
+ this.display.setDraftMode(false);
732
+ this.hideLoadingWarning();
733
+ }
701
734
  // @see {@link #asyncApplyOrUnapplyCommands }
702
- Editor.prototype.asyncApplyCommands = function (commands, chunkSize) {
735
+ asyncApplyCommands(commands, chunkSize) {
703
736
  return this.asyncApplyOrUnapplyCommands(commands, true, chunkSize);
704
- };
737
+ }
705
738
  // If `unapplyInReverseOrder`, commands are reversed before unapplying.
706
739
  // @see {@link #asyncApplyOrUnapplyCommands }
707
- Editor.prototype.asyncUnapplyCommands = function (commands, chunkSize, unapplyInReverseOrder) {
708
- if (unapplyInReverseOrder === void 0) { unapplyInReverseOrder = false; }
740
+ asyncUnapplyCommands(commands, chunkSize, unapplyInReverseOrder = false) {
709
741
  if (unapplyInReverseOrder) {
710
- commands = __spreadArray([], commands, true); // copy
742
+ commands = [...commands]; // copy
711
743
  commands.reverse();
712
744
  }
713
745
  return this.asyncApplyOrUnapplyCommands(commands, false, chunkSize);
714
- };
746
+ }
715
747
  /**
716
748
  * Schedule a re-render for some time in the near future. Does not schedule an additional
717
749
  * re-render if a re-render is already queued.
718
750
  *
719
751
  * @returns a promise that resolves when re-rendering has completed.
720
752
  */
721
- Editor.prototype.queueRerender = function () {
722
- var _this = this;
753
+ queueRerender() {
723
754
  if (!this.rerenderQueued) {
724
755
  this.rerenderQueued = true;
725
- requestAnimationFrame(function () {
756
+ requestAnimationFrame(() => {
726
757
  // If .rerender was called manually, we might not need to
727
758
  // re-render.
728
- if (_this.rerenderQueued) {
729
- _this.rerender();
730
- _this.rerenderQueued = false;
759
+ if (this.rerenderQueued) {
760
+ this.rerender();
761
+ this.rerenderQueued = false;
731
762
  }
732
763
  });
733
764
  }
734
- return new Promise(function (resolve) {
735
- _this.nextRerenderListeners.push(function () { return resolve(); });
765
+ return new Promise(resolve => {
766
+ this.nextRerenderListeners.push(() => resolve());
736
767
  });
737
- };
768
+ }
738
769
  // @internal
739
- Editor.prototype.isRerenderQueued = function () {
770
+ isRerenderQueued() {
740
771
  return this.rerenderQueued;
741
- };
772
+ }
742
773
  /**
743
774
  * Re-renders the entire image.
744
775
  *
745
776
  * @see {@link Editor.queueRerender}
746
777
  */
747
- Editor.prototype.rerender = function (showImageBounds) {
748
- if (showImageBounds === void 0) { showImageBounds = true; }
778
+ rerender(showImageBounds = true) {
749
779
  this.display.startRerender();
750
780
  // Don't render if the display has zero size.
751
781
  if (this.display.width === 0 || this.display.height === 0) {
752
782
  return;
753
783
  }
754
- // Draw a rectangle around the region that will be visible on save
755
- var renderer = this.display.getDryInkRenderer();
784
+ const renderer = this.display.getDryInkRenderer();
756
785
  this.image.renderWithCache(renderer, this.display.getCache(), this.viewport);
757
786
  if (showImageBounds) {
758
- var exportRectFill = { fill: Color4_1.default.fromHex('#44444455') };
759
- var exportRectStrokeWidth = 5 * this.viewport.getSizeOfPixelOnCanvas();
787
+ // Draw a rectangle around the region that will be visible on save
788
+ const exportRectFill = { fill: math_1.Color4.fromHex('#44444455') };
789
+ const exportRectStrokeWidth = 5 * this.viewport.getSizeOfPixelOnCanvas();
760
790
  renderer.drawRect(this.getImportExportRect(), exportRectStrokeWidth, exportRectFill);
761
791
  }
762
792
  this.rerenderQueued = false;
763
- this.nextRerenderListeners.forEach(function (listener) { return listener(); });
793
+ this.nextRerenderListeners.forEach(listener => listener());
764
794
  this.nextRerenderListeners = [];
765
- };
795
+ }
766
796
  /**
767
797
  * Draws the given path onto the wet ink renderer. The given path will
768
798
  * be displayed on top of the main image.
769
799
  *
770
800
  * @see {@link Display.getWetInkRenderer} {@link Display.flatten}
771
801
  */
772
- Editor.prototype.drawWetInk = function () {
773
- var path = [];
774
- for (var _i = 0; _i < arguments.length; _i++) {
775
- path[_i] = arguments[_i];
776
- }
777
- for (var _a = 0, path_1 = path; _a < path_1.length; _a++) {
778
- var part = path_1[_a];
802
+ drawWetInk(...path) {
803
+ for (const part of path) {
779
804
  this.display.getWetInkRenderer().drawPath(part);
780
805
  }
781
- };
806
+ }
782
807
  /**
783
808
  * Clears the wet ink display.
784
809
  *
785
810
  * @see {@link Display.getWetInkRenderer}
786
811
  */
787
- Editor.prototype.clearWetInk = function () {
812
+ clearWetInk() {
788
813
  this.display.getWetInkRenderer().clear();
789
- };
814
+ }
790
815
  /**
791
816
  * Focuses the region used for text input/key commands.
792
817
  */
793
- Editor.prototype.focus = function () {
818
+ focus() {
794
819
  this.renderingRegion.focus();
795
- };
820
+ }
796
821
  /**
797
822
  * Creates an element that will be positioned on top of the dry/wet ink
798
823
  * renderers.
@@ -800,31 +825,42 @@ var Editor = /** @class */ (function () {
800
825
  * This is useful for displaying content on top of the rendered content
801
826
  * (e.g. a selection box).
802
827
  */
803
- Editor.prototype.createHTMLOverlay = function (overlay) {
828
+ createHTMLOverlay(overlay) {
804
829
  overlay.classList.add('overlay');
805
830
  this.container.appendChild(overlay);
806
831
  return {
807
- remove: function () { return overlay.remove(); },
832
+ remove: () => overlay.remove(),
808
833
  };
809
- };
810
- Editor.prototype.addStyleSheet = function (content) {
811
- var styleSheet = document.createElement('style');
834
+ }
835
+ addStyleSheet(content) {
836
+ const styleSheet = document.createElement('style');
812
837
  styleSheet.innerText = content;
813
838
  this.container.appendChild(styleSheet);
814
839
  return styleSheet;
815
- };
816
- // Dispatch a keyboard event to the currently selected tool.
817
- // Intended for unit testing
818
- Editor.prototype.sendKeyboardEvent = function (eventType, key, ctrlKey, altKey) {
819
- if (ctrlKey === void 0) { ctrlKey = false; }
820
- if (altKey === void 0) { altKey = false; }
840
+ }
841
+ /**
842
+ * Dispatch a keyboard event to the currently selected tool.
843
+ * Intended for unit testing.
844
+ *
845
+ * If `shiftKey` is undefined, it is guessed from `key`.
846
+ *
847
+ * At present, the **key code** dispatched is guessed from the given key and,
848
+ * while this works for ASCII alphanumeric characters, this does not work for
849
+ * most non-alphanumeric keys.
850
+ *
851
+ * Because guessing the key code from `key` is problematic, **only use this for testing**.
852
+ */
853
+ sendKeyboardEvent(eventType, key, ctrlKey = false, altKey = false, shiftKey = undefined) {
854
+ shiftKey ??= key.toUpperCase() === key && key.toLowerCase() !== key;
821
855
  this.toolController.dispatchInputEvent({
822
856
  kind: eventType,
823
- key: key,
824
- ctrlKey: ctrlKey,
825
- altKey: altKey,
857
+ key,
858
+ code: (0, guessKeyCodeFromKey_1.default)(key),
859
+ ctrlKey,
860
+ altKey,
861
+ shiftKey,
826
862
  });
827
- };
863
+ }
828
864
  /**
829
865
  * Dispatch a pen event to the currently selected tool.
830
866
  * Intended primarially for unit tests.
@@ -832,227 +868,220 @@ var Editor = /** @class */ (function () {
832
868
  * @deprecated
833
869
  * @see {@link sendPenEvent} {@link sendTouchEvent}
834
870
  */
835
- Editor.prototype.sendPenEvent = function (eventType, point,
871
+ sendPenEvent(eventType, point,
836
872
  // @deprecated
837
873
  allPointers) {
838
874
  (0, sendPenEvent_1.default)(this, eventType, point, allPointers);
839
- };
840
- Editor.prototype.addAndCenterComponents = function (components, selectComponents) {
841
- if (selectComponents === void 0) { selectComponents = true; }
842
- return __awaiter(this, void 0, void 0, function () {
843
- var bbox, _i, components_1, component, visibleRect, scaleRatioX, scaleRatioY, scaleRatio, transfm, commands, _a, components_2, component, applyChunkSize, _b, _c, selectionTool;
844
- return __generator(this, function (_d) {
845
- switch (_d.label) {
846
- case 0:
847
- bbox = null;
848
- for (_i = 0, components_1 = components; _i < components_1.length; _i++) {
849
- component = components_1[_i];
850
- if (bbox) {
851
- bbox = bbox.union(component.getBBox());
852
- }
853
- else {
854
- bbox = component.getBBox();
855
- }
856
- }
857
- if (!bbox) {
858
- return [2 /*return*/];
859
- }
860
- visibleRect = this.viewport.visibleRect;
861
- scaleRatioX = visibleRect.width / bbox.width;
862
- scaleRatioY = visibleRect.height / bbox.height;
863
- scaleRatio = scaleRatioX;
864
- if (bbox.width * scaleRatio > visibleRect.width || bbox.height * scaleRatio > visibleRect.height) {
865
- scaleRatio = scaleRatioY;
866
- }
867
- scaleRatio *= 2 / 3;
868
- scaleRatio = Viewport_1.default.roundScaleRatio(scaleRatio);
869
- transfm = Mat33_1.default.translation(visibleRect.center.minus(bbox.center)).rightMul(Mat33_1.default.scaling2D(scaleRatio, bbox.center));
870
- commands = [];
871
- for (_a = 0, components_2 = components; _a < components_2.length; _a++) {
872
- component = components_2[_a];
873
- // To allow deserialization, we need to add first, then transform.
874
- commands.push(EditorImage_1.default.addElement(component));
875
- commands.push(component.transformBy(transfm));
876
- }
877
- applyChunkSize = 100;
878
- return [4 /*yield*/, this.dispatch((0, uniteCommands_1.default)(commands, applyChunkSize), true)];
879
- case 1:
880
- _d.sent();
881
- if (selectComponents) {
882
- for (_b = 0, _c = this.toolController.getMatchingTools(SelectionTool_1.default); _b < _c.length; _b++) {
883
- selectionTool = _c[_b];
884
- selectionTool.setEnabled(true);
885
- selectionTool.setSelection(components);
886
- }
887
- }
888
- return [2 /*return*/];
889
- }
890
- });
891
- });
892
- };
875
+ }
876
+ async addAndCenterComponents(components, selectComponents = true) {
877
+ let bbox = null;
878
+ for (const component of components) {
879
+ if (bbox) {
880
+ bbox = bbox.union(component.getBBox());
881
+ }
882
+ else {
883
+ bbox = component.getBBox();
884
+ }
885
+ }
886
+ if (!bbox) {
887
+ return;
888
+ }
889
+ // Find a transform that scales/moves bbox onto the screen.
890
+ const visibleRect = this.viewport.visibleRect;
891
+ const scaleRatioX = visibleRect.width / bbox.width;
892
+ const scaleRatioY = visibleRect.height / bbox.height;
893
+ let scaleRatio = scaleRatioX;
894
+ if (bbox.width * scaleRatio > visibleRect.width || bbox.height * scaleRatio > visibleRect.height) {
895
+ scaleRatio = scaleRatioY;
896
+ }
897
+ scaleRatio *= 2 / 3;
898
+ scaleRatio = Viewport_1.default.roundScaleRatio(scaleRatio);
899
+ const transfm = math_1.Mat33.translation(visibleRect.center.minus(bbox.center)).rightMul(math_1.Mat33.scaling2D(scaleRatio, bbox.center));
900
+ const commands = [];
901
+ for (const component of components) {
902
+ // To allow deserialization, we need to add first, then transform.
903
+ commands.push(EditorImage_1.default.addElement(component));
904
+ commands.push(component.transformBy(transfm));
905
+ }
906
+ const applyChunkSize = 100;
907
+ await this.dispatch((0, uniteCommands_1.default)(commands, applyChunkSize), true);
908
+ if (selectComponents) {
909
+ for (const selectionTool of this.toolController.getMatchingTools(SelectionTool_1.default)) {
910
+ selectionTool.setEnabled(true);
911
+ selectionTool.setSelection(components);
912
+ }
913
+ }
914
+ }
893
915
  // Get a data URL (e.g. as produced by `HTMLCanvasElement::toDataURL`).
894
916
  // If `format` is not `image/png`, a PNG image URL may still be returned (as in the
895
917
  // case of `HTMLCanvasElement::toDataURL`).
896
918
  //
897
919
  // The export resolution is the same as the size of the drawing canvas.
898
- Editor.prototype.toDataURL = function (format, outputSize) {
899
- if (format === void 0) { format = 'image/png'; }
900
- var canvas = document.createElement('canvas');
901
- var importExportViewport = this.image.getImportExportViewport();
902
- var exportRectSize = importExportViewport.getScreenRectSize();
903
- var resolution = outputSize !== null && outputSize !== void 0 ? outputSize : exportRectSize;
920
+ toDataURL(format = 'image/png', outputSize) {
921
+ const canvas = document.createElement('canvas');
922
+ const importExportViewport = this.image.getImportExportViewport();
923
+ const exportRectSize = importExportViewport.getScreenRectSize();
924
+ const resolution = outputSize ?? exportRectSize;
904
925
  canvas.width = resolution.x;
905
926
  canvas.height = resolution.y;
906
- var ctx = canvas.getContext('2d');
927
+ const ctx = canvas.getContext('2d');
907
928
  // Scale to ensure that the entire output is visible.
908
- var scaleFactor = Math.min(resolution.x / exportRectSize.x, resolution.y / exportRectSize.y);
929
+ const scaleFactor = Math.min(resolution.x / exportRectSize.x, resolution.y / exportRectSize.y);
909
930
  ctx.scale(scaleFactor, scaleFactor);
910
- var renderer = new CanvasRenderer_1.default(ctx, importExportViewport);
931
+ const renderer = new CanvasRenderer_1.default(ctx, importExportViewport);
911
932
  this.image.renderAll(renderer);
912
- var dataURL = canvas.toDataURL(format);
933
+ const dataURL = canvas.toDataURL(format);
913
934
  return dataURL;
914
- };
915
- Editor.prototype.toSVG = function () {
916
- var importExportViewport = this.image.getImportExportViewport().getTemporaryClone();
917
- var sanitize = false;
918
- var _a = SVGRenderer_1.default.fromViewport(importExportViewport, sanitize), result = _a.element, renderer = _a.renderer;
919
- var origTransform = importExportViewport.canvasToScreenTransform;
935
+ }
936
+ toSVG() {
937
+ const importExportViewport = this.image.getImportExportViewport().getTemporaryClone();
938
+ const sanitize = false;
939
+ const { element: result, renderer } = SVGRenderer_1.default.fromViewport(importExportViewport, sanitize);
940
+ const origTransform = importExportViewport.canvasToScreenTransform;
920
941
  // Render with (0,0) at (0,0) — we'll handle translation with
921
942
  // the viewBox property.
922
- importExportViewport.resetTransform(Mat33_1.default.identity);
943
+ importExportViewport.resetTransform(math_1.Mat33.identity);
923
944
  this.image.renderAll(renderer);
924
945
  importExportViewport.resetTransform(origTransform);
925
946
  // Just show the main region
926
- var rect = importExportViewport.visibleRect;
927
- result.setAttribute('viewBox', [rect.x, rect.y, rect.w, rect.h].map(function (part) { return (0, rounding_1.toRoundedString)(part); }).join(' '));
928
- result.setAttribute('width', (0, rounding_1.toRoundedString)(rect.w));
929
- result.setAttribute('height', (0, rounding_1.toRoundedString)(rect.h));
947
+ const rect = importExportViewport.visibleRect;
948
+ result.setAttribute('viewBox', [rect.x, rect.y, rect.w, rect.h].map(part => (0, math_1.toRoundedString)(part)).join(' '));
949
+ result.setAttribute('width', (0, math_1.toRoundedString)(rect.w));
950
+ result.setAttribute('height', (0, math_1.toRoundedString)(rect.h));
930
951
  return result;
931
- };
952
+ }
932
953
  /**
933
954
  * Load editor data from an `ImageLoader` (e.g. an {@link SVGLoader}).
934
955
  *
935
956
  * @see loadFromSVG
936
957
  */
937
- Editor.prototype.loadFrom = function (loader) {
938
- return __awaiter(this, void 0, void 0, function () {
939
- var originalBackgrounds, eraseBackgroundCommand;
940
- var _this = this;
941
- return __generator(this, function (_a) {
942
- switch (_a.label) {
943
- case 0:
944
- this.showLoadingWarning(0);
945
- this.display.setDraftMode(true);
946
- originalBackgrounds = this.image.getBackgroundComponents();
947
- eraseBackgroundCommand = new Erase_1.default(originalBackgrounds);
948
- return [4 /*yield*/, loader.start(function (component) { return __awaiter(_this, void 0, void 0, function () {
949
- return __generator(this, function (_a) {
950
- switch (_a.label) {
951
- case 0: return [4 /*yield*/, this.dispatchNoAnnounce(EditorImage_1.default.addElement(component))];
952
- case 1:
953
- _a.sent();
954
- return [2 /*return*/];
955
- }
956
- });
957
- }); }, function (countProcessed, totalToProcess) {
958
- if (countProcessed % 500 === 0) {
959
- _this.showLoadingWarning(countProcessed / totalToProcess);
960
- _this.rerender();
961
- return (0, untilNextAnimationFrame_1.default)();
962
- }
963
- return null;
964
- }, function (importExportRect) {
965
- _this.dispatchNoAnnounce(_this.setImportExportRect(importExportRect), false);
966
- _this.dispatchNoAnnounce(_this.viewport.zoomTo(importExportRect), false);
967
- })];
968
- case 1:
969
- _a.sent();
970
- if (!(this.image.getBackgroundComponents().length !== originalBackgrounds.length)) return [3 /*break*/, 3];
971
- return [4 /*yield*/, this.dispatchNoAnnounce(eraseBackgroundCommand)];
972
- case 2:
973
- _a.sent();
974
- _a.label = 3;
975
- case 3:
976
- this.hideLoadingWarning();
977
- this.display.setDraftMode(false);
978
- this.queueRerender();
979
- return [2 /*return*/];
980
- }
981
- });
958
+ async loadFrom(loader) {
959
+ this.showLoadingWarning(0);
960
+ this.display.setDraftMode(true);
961
+ const originalBackgrounds = this.image.getBackgroundComponents();
962
+ const eraseBackgroundCommand = new Erase_1.default(originalBackgrounds);
963
+ await loader.start(async (component) => {
964
+ await this.dispatchNoAnnounce(EditorImage_1.default.addElement(component));
965
+ }, (countProcessed, totalToProcess) => {
966
+ if (countProcessed % 500 === 0) {
967
+ this.showLoadingWarning(countProcessed / totalToProcess);
968
+ this.rerender();
969
+ return (0, untilNextAnimationFrame_1.default)();
970
+ }
971
+ return null;
972
+ }, (importExportRect) => {
973
+ this.dispatchNoAnnounce(this.setImportExportRect(importExportRect), false);
974
+ this.dispatchNoAnnounce(this.viewport.zoomTo(importExportRect), false);
982
975
  });
983
- };
984
- Editor.prototype.getTopmostBackgroundComponent = function () {
985
- var background = null;
976
+ // Ensure that we don't have multiple overlapping BackgroundComponents. Remove
977
+ // old BackgroundComponents.
978
+ // Overlapping BackgroundComponents may cause changing the background color to
979
+ // not work properly.
980
+ if (this.image.getBackgroundComponents().length !== originalBackgrounds.length) {
981
+ await this.dispatchNoAnnounce(eraseBackgroundCommand);
982
+ }
983
+ this.hideLoadingWarning();
984
+ this.display.setDraftMode(false);
985
+ this.queueRerender();
986
+ }
987
+ getTopmostBackgroundComponent() {
988
+ let background = null;
986
989
  // Find a background component, if one exists.
987
990
  // Use the last (topmost) background component if there are multiple.
988
- for (var _i = 0, _a = this.image.getBackgroundComponents(); _i < _a.length; _i++) {
989
- var component = _a[_i];
991
+ for (const component of this.image.getBackgroundComponents()) {
990
992
  if (component instanceof BackgroundComponent_1.default) {
991
993
  background = component;
992
994
  }
993
995
  }
994
996
  return background;
995
- };
997
+ }
996
998
  /**
997
999
  * Set the background color of the image.
998
1000
  */
999
- Editor.prototype.setBackgroundColor = function (color) {
1000
- var background = this.getTopmostBackgroundComponent();
1001
+ setBackgroundColor(color) {
1002
+ let background = this.getTopmostBackgroundComponent();
1001
1003
  if (!background) {
1002
- var backgroundType = color.eq(Color4_1.default.transparent) ? BackgroundComponent_1.BackgroundType.None : BackgroundComponent_1.BackgroundType.SolidColor;
1004
+ const backgroundType = color.eq(math_1.Color4.transparent) ? BackgroundComponent_1.BackgroundType.None : BackgroundComponent_1.BackgroundType.SolidColor;
1003
1005
  background = new BackgroundComponent_1.default(backgroundType, color);
1004
1006
  return this.image.addElement(background);
1005
1007
  }
1006
1008
  else {
1007
- return background.updateStyle({ color: color });
1009
+ return background.updateStyle({ color });
1008
1010
  }
1009
- };
1011
+ }
1010
1012
  /**
1011
1013
  * @returns the average of the colors of all background components. Use this to get the current background
1012
1014
  * color.
1013
1015
  */
1014
- Editor.prototype.estimateBackgroundColor = function () {
1015
- var _a;
1016
- var backgroundColors = [];
1017
- for (var _i = 0, _b = this.image.getBackgroundComponents(); _i < _b.length; _i++) {
1018
- var component = _b[_i];
1016
+ estimateBackgroundColor() {
1017
+ const backgroundColors = [];
1018
+ for (const component of this.image.getBackgroundComponents()) {
1019
1019
  if (component instanceof BackgroundComponent_1.default) {
1020
- backgroundColors.push((_a = component.getStyle().color) !== null && _a !== void 0 ? _a : Color4_1.default.transparent);
1020
+ backgroundColors.push(component.getStyle().color ?? math_1.Color4.transparent);
1021
1021
  }
1022
1022
  }
1023
- return Color4_1.default.average(backgroundColors);
1024
- };
1023
+ return math_1.Color4.average(backgroundColors);
1024
+ }
1025
1025
  // Returns the size of the visible region of the output SVG
1026
- Editor.prototype.getImportExportRect = function () {
1026
+ getImportExportRect() {
1027
1027
  return this.image.getImportExportViewport().visibleRect;
1028
- };
1028
+ }
1029
1029
  // Resize the output SVG to match `imageRect`.
1030
- Editor.prototype.setImportExportRect = function (imageRect) {
1030
+ setImportExportRect(imageRect) {
1031
1031
  return this.image.setImportExportRect(imageRect);
1032
- };
1032
+ }
1033
1033
  /**
1034
- * Alias for loadFrom(SVGLoader.fromString).
1034
+ * Alias for `loadFrom(SVGLoader.fromString)`.
1035
1035
  *
1036
1036
  * This is particularly useful when accessing a bundled version of the editor,
1037
1037
  * where `SVGLoader.fromString` is unavailable.
1038
1038
  */
1039
- Editor.prototype.loadFromSVG = function (svgData, sanitize) {
1040
- if (sanitize === void 0) { sanitize = false; }
1041
- return __awaiter(this, void 0, void 0, function () {
1042
- var loader;
1043
- return __generator(this, function (_a) {
1044
- switch (_a.label) {
1045
- case 0:
1046
- loader = SVGLoader_1.default.fromString(svgData, sanitize);
1047
- return [4 /*yield*/, this.loadFrom(loader)];
1048
- case 1:
1049
- _a.sent();
1050
- return [2 /*return*/];
1051
- }
1052
- });
1039
+ async loadFromSVG(svgData, sanitize = false) {
1040
+ const loader = SVGLoader_1.default.fromString(svgData, sanitize);
1041
+ await this.loadFrom(loader);
1042
+ }
1043
+ /**
1044
+ * Shows an information dialog with legal notices.
1045
+ */
1046
+ showAboutDialog() {
1047
+ const iconLicenseText = this.icons.licenseInfo();
1048
+ const notices = [];
1049
+ notices.push({
1050
+ heading: 'js-draw',
1051
+ text: [
1052
+ `v${version_1.default.number}`,
1053
+ '',
1054
+ 'Image debug information (from when this dialog was opened):',
1055
+ ` ${this.viewport.getScaleFactor()}x zoom, ${180 / Math.PI * this.viewport.getRotationAngle()} rotation`,
1056
+ ` ${this.image.estimateNumElements()} components`,
1057
+ ` ${this.getImportExportRect().w}x${this.getImportExportRect().h} size`,
1058
+ ].join('\n'),
1059
+ });
1060
+ notices.push({
1061
+ heading: 'Libraries',
1062
+ text: [
1063
+ 'js-draw uses several libraries at runtime. Particularly noteworthy are:',
1064
+ ' - The Coloris color picker: https://github.com/mdbassit/Coloris',
1065
+ ' - The bezier.js Bézier curve library: https://github.com/Pomax/bezierjs'
1066
+ ].join('\n'),
1067
+ minimized: true,
1053
1068
  });
1054
- };
1055
- return Editor;
1056
- }());
1069
+ if (iconLicenseText) {
1070
+ notices.push({
1071
+ heading: 'Icon Pack',
1072
+ text: iconLicenseText,
1073
+ minimized: true,
1074
+ });
1075
+ }
1076
+ notices.push(...this.settings.notices);
1077
+ this.closeAboutDialog?.();
1078
+ this.closeAboutDialog = (0, makeAboutDialog_1.default)(this, notices).close;
1079
+ }
1080
+ /** Removes and destroys the editor */
1081
+ remove() {
1082
+ this.container.remove();
1083
+ // TODO: Is additional cleanup necessary here?
1084
+ }
1085
+ }
1057
1086
  exports.Editor = Editor;
1058
1087
  exports.default = Editor;