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