js-draw 1.21.3 → 1.23.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (331) hide show
  1. package/README.md +104 -76
  2. package/build-config.json +2 -2
  3. package/dist/Editor.css +29 -16
  4. package/dist/bundle.js +2 -2
  5. package/dist/bundledStyles.js +1 -1
  6. package/dist/cjs/Editor.d.ts +1 -3
  7. package/dist/cjs/Editor.js +38 -26
  8. package/dist/cjs/EventDispatcher.js +1 -1
  9. package/dist/cjs/Pointer.js +3 -3
  10. package/dist/cjs/SVGLoader/SVGLoader.js +15 -6
  11. package/dist/cjs/UndoRedoHistory.js +1 -1
  12. package/dist/cjs/Viewport.d.ts +1 -1
  13. package/dist/cjs/Viewport.js +5 -3
  14. package/dist/cjs/commands/Command.js +7 -5
  15. package/dist/cjs/commands/Duplicate.js +2 -2
  16. package/dist/cjs/commands/Erase.js +3 -4
  17. package/dist/cjs/commands/invertCommand.js +4 -4
  18. package/dist/cjs/commands/lib.d.ts +1 -1
  19. package/dist/cjs/commands/uniteCommands.js +4 -4
  20. package/dist/cjs/components/AbstractComponent.d.ts +2 -2
  21. package/dist/cjs/components/AbstractComponent.js +4 -4
  22. package/dist/cjs/components/BackgroundComponent.js +8 -6
  23. package/dist/cjs/components/ImageComponent.js +12 -5
  24. package/dist/cjs/components/RestylableComponent.js +1 -1
  25. package/dist/cjs/components/SVGGlobalAttributesObject.js +1 -2
  26. package/dist/cjs/components/Stroke.js +37 -24
  27. package/dist/cjs/components/TextComponent.js +13 -10
  28. package/dist/cjs/components/UnknownSVGObject.js +2 -3
  29. package/dist/cjs/components/builders/ArrowBuilder.d.ts +6 -0
  30. package/dist/cjs/components/builders/ArrowBuilder.js +9 -3
  31. package/dist/cjs/components/builders/CircleBuilder.d.ts +6 -0
  32. package/dist/cjs/components/builders/CircleBuilder.js +11 -4
  33. package/dist/cjs/components/builders/FreehandLineBuilder.d.ts +6 -0
  34. package/dist/cjs/components/builders/FreehandLineBuilder.js +10 -4
  35. package/dist/cjs/components/builders/LineBuilder.d.ts +6 -0
  36. package/dist/cjs/components/builders/LineBuilder.js +8 -4
  37. package/dist/cjs/components/builders/PolylineBuilder.d.ts +4 -1
  38. package/dist/cjs/components/builders/PolylineBuilder.js +9 -5
  39. package/dist/cjs/components/builders/PressureSensitiveFreehandLineBuilder.js +16 -10
  40. package/dist/cjs/components/builders/RectangleBuilder.d.ts +12 -0
  41. package/dist/cjs/components/builders/RectangleBuilder.js +17 -3
  42. package/dist/cjs/components/builders/autocorrect/makeShapeFitAutocorrect.js +5 -8
  43. package/dist/cjs/components/builders/autocorrect/makeSnapToGridAutocorrect.js +1 -1
  44. package/dist/cjs/components/builders/lib.d.ts +7 -0
  45. package/dist/cjs/components/builders/lib.js +18 -0
  46. package/dist/cjs/components/lib.d.ts +1 -4
  47. package/dist/cjs/components/lib.js +2 -9
  48. package/dist/cjs/components/util/StrokeSmoother.js +5 -6
  49. package/dist/cjs/dialogs/makeAboutDialog.js +1 -1
  50. package/dist/cjs/dialogs/makeMessageDialog.js +2 -2
  51. package/dist/cjs/image/EditorImage.d.ts +30 -7
  52. package/dist/cjs/image/EditorImage.js +43 -22
  53. package/dist/cjs/image/export/editorImageToSVG.js +1 -1
  54. package/dist/cjs/inputEvents.js +3 -3
  55. package/dist/cjs/lib.d.ts +2 -2
  56. package/dist/cjs/localizations/de.js +2 -2
  57. package/dist/cjs/localizations/es.js +7 -3
  58. package/dist/cjs/rendering/Display.js +7 -3
  59. package/dist/cjs/rendering/RenderablePathSpec.js +26 -11
  60. package/dist/cjs/rendering/RenderingStyle.js +22 -15
  61. package/dist/cjs/rendering/TextRenderingStyle.js +1 -1
  62. package/dist/cjs/rendering/caching/CacheRecord.js +1 -1
  63. package/dist/cjs/rendering/caching/CacheRecordManager.js +1 -1
  64. package/dist/cjs/rendering/caching/RenderingCache.js +1 -1
  65. package/dist/cjs/rendering/caching/RenderingCacheNode.js +26 -15
  66. package/dist/cjs/rendering/caching/testUtils.js +2 -2
  67. package/dist/cjs/rendering/renderers/AbstractRenderer.js +3 -1
  68. package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +2 -25
  69. package/dist/cjs/rendering/renderers/CanvasRenderer.js +6 -28
  70. package/dist/cjs/rendering/renderers/DummyRenderer.js +1 -1
  71. package/dist/cjs/rendering/renderers/SVGRenderer.js +39 -21
  72. package/dist/cjs/rendering/renderers/TextOnlyRenderer.js +13 -15
  73. package/dist/cjs/shortcuts/KeyBinding.js +6 -12
  74. package/dist/cjs/shortcuts/KeyboardShortcutManager.js +2 -2
  75. package/dist/cjs/testing/createEditor.js +6 -1
  76. package/dist/cjs/testing/findNodeWithText.d.ts +4 -1
  77. package/dist/cjs/testing/findNodeWithText.js +12 -3
  78. package/dist/cjs/testing/getUniquePointerId.js +1 -1
  79. package/dist/cjs/testing/sendHtmlSwipe.js +7 -3
  80. package/dist/cjs/testing/sendPenEvent.js +1 -3
  81. package/dist/cjs/testing/sendTouchEvent.js +1 -4
  82. package/dist/cjs/testing/startPinchGesture.js +3 -1
  83. package/dist/cjs/toolbar/AbstractToolbar.d.ts +19 -0
  84. package/dist/cjs/toolbar/AbstractToolbar.js +26 -11
  85. package/dist/cjs/toolbar/EdgeToolbar.js +11 -15
  86. package/dist/cjs/toolbar/IconProvider.d.ts +5 -1
  87. package/dist/cjs/toolbar/IconProvider.js +117 -149
  88. package/dist/cjs/toolbar/localization.js +5 -5
  89. package/dist/cjs/toolbar/utils/HelpDisplay.js +8 -6
  90. package/dist/cjs/toolbar/utils/makeDraggable.js +4 -7
  91. package/dist/cjs/toolbar/widgets/BaseToolWidget.js +3 -2
  92. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +1 -1
  93. package/dist/cjs/toolbar/widgets/BaseWidget.js +8 -8
  94. package/dist/cjs/toolbar/widgets/DocumentPropertiesWidget.js +2 -2
  95. package/dist/cjs/toolbar/widgets/EraserToolWidget.js +5 -3
  96. package/dist/cjs/toolbar/widgets/HandToolWidget.js +8 -6
  97. package/dist/cjs/toolbar/widgets/InsertImageWidget/InsertImageWidget.js +9 -10
  98. package/dist/cjs/toolbar/widgets/PenToolWidget.js +22 -13
  99. package/dist/cjs/toolbar/widgets/SelectionToolWidget.js +2 -2
  100. package/dist/cjs/toolbar/widgets/TextToolWidget.js +5 -5
  101. package/dist/cjs/toolbar/widgets/components/makeFileInput.js +7 -7
  102. package/dist/cjs/toolbar/widgets/components/makeGridSelector.js +5 -5
  103. package/dist/cjs/toolbar/widgets/components/makeSnappedList.js +9 -5
  104. package/dist/cjs/toolbar/widgets/keybindings.js +2 -2
  105. package/dist/cjs/toolbar/widgets/layout/DropdownLayoutManager.js +6 -6
  106. package/dist/cjs/tools/BaseTool.js +5 -3
  107. package/dist/cjs/tools/Eraser.js +25 -20
  108. package/dist/cjs/tools/FindTool.js +2 -2
  109. package/dist/cjs/tools/InputFilter/ContextMenuRecognizer.js +1 -3
  110. package/dist/cjs/tools/InputFilter/InputMapper.js +1 -1
  111. package/dist/cjs/tools/InputFilter/InputPipeline.js +1 -1
  112. package/dist/cjs/tools/InputFilter/InputStabilizer.js +12 -5
  113. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +7 -4
  114. package/dist/cjs/tools/PanZoom.d.ts +1 -1
  115. package/dist/cjs/tools/PanZoom.js +18 -13
  116. package/dist/cjs/tools/PasteHandler.js +8 -2
  117. package/dist/cjs/tools/Pen.d.ts +13 -0
  118. package/dist/cjs/tools/Pen.js +30 -9
  119. package/dist/cjs/tools/ScrollbarTool.js +8 -7
  120. package/dist/cjs/tools/SelectionTool/Selection.js +16 -12
  121. package/dist/cjs/tools/SelectionTool/SelectionHandle.js +5 -2
  122. package/dist/cjs/tools/SelectionTool/SelectionMenuShortcut.js +3 -1
  123. package/dist/cjs/tools/SelectionTool/SelectionTool.js +25 -16
  124. package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.js +1 -1
  125. package/dist/cjs/tools/SelectionTool/TransformMode.js +6 -7
  126. package/dist/cjs/tools/SelectionTool/util/makeClipboardErrorHandlers.js +23 -2
  127. package/dist/cjs/tools/SelectionTool/util/showSelectionContextMenu.js +29 -20
  128. package/dist/cjs/tools/SoundUITool.js +5 -3
  129. package/dist/cjs/tools/TextTool.js +8 -6
  130. package/dist/cjs/tools/ToolController.js +16 -10
  131. package/dist/cjs/tools/lib.d.ts +1 -0
  132. package/dist/cjs/tools/lib.js +3 -1
  133. package/dist/cjs/tools/localization.d.ts +2 -0
  134. package/dist/cjs/tools/localization.js +3 -1
  135. package/dist/cjs/tools/util/StationaryPenDetector.js +3 -3
  136. package/dist/cjs/tools/util/createMenuOverlay.js +2 -2
  137. package/dist/cjs/util/ClipboardHandler.d.ts +1 -1
  138. package/dist/cjs/util/ClipboardHandler.js +19 -18
  139. package/dist/cjs/util/ReactiveValue.js +16 -12
  140. package/dist/cjs/util/adjustEditorThemeForContrast.js +6 -2
  141. package/dist/cjs/util/cloneElementWithStyles.js +1 -1
  142. package/dist/cjs/util/createElement.d.ts +62 -0
  143. package/dist/cjs/util/createElement.js +53 -0
  144. package/dist/cjs/util/guessKeyCodeFromKey.js +1 -1
  145. package/dist/cjs/util/listenForKeyboardEventsFrom.js +8 -6
  146. package/dist/cjs/util/waitForAll.js +3 -3
  147. package/dist/cjs/util/waitForImageLoaded.js +3 -3
  148. package/dist/cjs/util/waitForTimeout.js +1 -1
  149. package/dist/cjs/version.js +1 -1
  150. package/dist/mjs/Editor.d.ts +1 -3
  151. package/dist/mjs/Editor.mjs +39 -27
  152. package/dist/mjs/EventDispatcher.mjs +1 -1
  153. package/dist/mjs/Pointer.mjs +3 -3
  154. package/dist/mjs/SVGLoader/SVGLoader.mjs +16 -7
  155. package/dist/mjs/UndoRedoHistory.mjs +1 -1
  156. package/dist/mjs/Viewport.d.ts +1 -1
  157. package/dist/mjs/Viewport.mjs +5 -3
  158. package/dist/mjs/commands/Command.mjs +7 -5
  159. package/dist/mjs/commands/Duplicate.mjs +2 -2
  160. package/dist/mjs/commands/Erase.mjs +3 -4
  161. package/dist/mjs/commands/invertCommand.mjs +4 -4
  162. package/dist/mjs/commands/lib.d.ts +1 -1
  163. package/dist/mjs/commands/lib.mjs +1 -1
  164. package/dist/mjs/commands/uniteCommands.mjs +4 -4
  165. package/dist/mjs/components/AbstractComponent.d.ts +2 -2
  166. package/dist/mjs/components/AbstractComponent.mjs +4 -4
  167. package/dist/mjs/components/BackgroundComponent.mjs +10 -8
  168. package/dist/mjs/components/ImageComponent.mjs +12 -5
  169. package/dist/mjs/components/RestylableComponent.mjs +2 -2
  170. package/dist/mjs/components/SVGGlobalAttributesObject.mjs +1 -2
  171. package/dist/mjs/components/Stroke.mjs +40 -27
  172. package/dist/mjs/components/TextComponent.mjs +15 -12
  173. package/dist/mjs/components/UnknownSVGObject.mjs +2 -3
  174. package/dist/mjs/components/builders/ArrowBuilder.d.ts +6 -0
  175. package/dist/mjs/components/builders/ArrowBuilder.mjs +9 -3
  176. package/dist/mjs/components/builders/CircleBuilder.d.ts +6 -0
  177. package/dist/mjs/components/builders/CircleBuilder.mjs +11 -4
  178. package/dist/mjs/components/builders/FreehandLineBuilder.d.ts +6 -0
  179. package/dist/mjs/components/builders/FreehandLineBuilder.mjs +10 -4
  180. package/dist/mjs/components/builders/LineBuilder.d.ts +6 -0
  181. package/dist/mjs/components/builders/LineBuilder.mjs +8 -4
  182. package/dist/mjs/components/builders/PolylineBuilder.d.ts +4 -1
  183. package/dist/mjs/components/builders/PolylineBuilder.mjs +10 -6
  184. package/dist/mjs/components/builders/PressureSensitiveFreehandLineBuilder.mjs +17 -11
  185. package/dist/mjs/components/builders/RectangleBuilder.d.ts +12 -0
  186. package/dist/mjs/components/builders/RectangleBuilder.mjs +17 -3
  187. package/dist/mjs/components/builders/autocorrect/makeShapeFitAutocorrect.mjs +5 -8
  188. package/dist/mjs/components/builders/autocorrect/makeSnapToGridAutocorrect.mjs +1 -1
  189. package/dist/mjs/components/builders/lib.d.ts +7 -0
  190. package/dist/mjs/components/builders/lib.mjs +7 -0
  191. package/dist/mjs/components/lib.d.ts +1 -4
  192. package/dist/mjs/components/lib.mjs +2 -5
  193. package/dist/mjs/components/util/StrokeSmoother.mjs +5 -6
  194. package/dist/mjs/dialogs/makeAboutDialog.mjs +1 -1
  195. package/dist/mjs/dialogs/makeMessageDialog.mjs +2 -2
  196. package/dist/mjs/image/EditorImage.d.ts +30 -7
  197. package/dist/mjs/image/EditorImage.mjs +43 -22
  198. package/dist/mjs/image/export/editorImageToSVG.mjs +1 -1
  199. package/dist/mjs/inputEvents.mjs +3 -3
  200. package/dist/mjs/lib.d.ts +2 -2
  201. package/dist/mjs/lib.mjs +2 -2
  202. package/dist/mjs/localization.mjs +2 -2
  203. package/dist/mjs/localizations/de.mjs +2 -2
  204. package/dist/mjs/localizations/es.mjs +7 -3
  205. package/dist/mjs/rendering/Display.mjs +7 -3
  206. package/dist/mjs/rendering/RenderablePathSpec.mjs +26 -11
  207. package/dist/mjs/rendering/RenderingStyle.mjs +22 -15
  208. package/dist/mjs/rendering/TextRenderingStyle.mjs +1 -1
  209. package/dist/mjs/rendering/caching/CacheRecord.mjs +1 -1
  210. package/dist/mjs/rendering/caching/CacheRecordManager.mjs +1 -1
  211. package/dist/mjs/rendering/caching/RenderingCache.mjs +1 -1
  212. package/dist/mjs/rendering/caching/RenderingCacheNode.mjs +26 -15
  213. package/dist/mjs/rendering/caching/testUtils.mjs +2 -2
  214. package/dist/mjs/rendering/renderers/AbstractRenderer.mjs +3 -1
  215. package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +2 -25
  216. package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +6 -28
  217. package/dist/mjs/rendering/renderers/DummyRenderer.mjs +1 -1
  218. package/dist/mjs/rendering/renderers/SVGRenderer.mjs +40 -22
  219. package/dist/mjs/rendering/renderers/TextOnlyRenderer.mjs +13 -15
  220. package/dist/mjs/shortcuts/KeyBinding.mjs +6 -12
  221. package/dist/mjs/shortcuts/KeyboardShortcutManager.mjs +2 -2
  222. package/dist/mjs/testing/createEditor.mjs +6 -1
  223. package/dist/mjs/testing/findNodeWithText.d.ts +4 -1
  224. package/dist/mjs/testing/findNodeWithText.mjs +12 -3
  225. package/dist/mjs/testing/getUniquePointerId.mjs +1 -1
  226. package/dist/mjs/testing/sendHtmlSwipe.mjs +7 -3
  227. package/dist/mjs/testing/sendPenEvent.mjs +1 -3
  228. package/dist/mjs/testing/sendTouchEvent.mjs +1 -4
  229. package/dist/mjs/testing/startPinchGesture.mjs +3 -1
  230. package/dist/mjs/toolbar/AbstractToolbar.d.ts +19 -0
  231. package/dist/mjs/toolbar/AbstractToolbar.mjs +26 -11
  232. package/dist/mjs/toolbar/EdgeToolbar.mjs +11 -15
  233. package/dist/mjs/toolbar/IconProvider.d.ts +5 -1
  234. package/dist/mjs/toolbar/IconProvider.mjs +117 -149
  235. package/dist/mjs/toolbar/localization.mjs +5 -5
  236. package/dist/mjs/toolbar/utils/HelpDisplay.mjs +8 -6
  237. package/dist/mjs/toolbar/utils/makeDraggable.mjs +4 -7
  238. package/dist/mjs/toolbar/widgets/BaseToolWidget.mjs +3 -2
  239. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +1 -1
  240. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +9 -9
  241. package/dist/mjs/toolbar/widgets/DocumentPropertiesWidget.mjs +2 -2
  242. package/dist/mjs/toolbar/widgets/EraserToolWidget.mjs +5 -3
  243. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +8 -6
  244. package/dist/mjs/toolbar/widgets/InsertImageWidget/InsertImageWidget.mjs +9 -10
  245. package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +23 -14
  246. package/dist/mjs/toolbar/widgets/SelectionToolWidget.mjs +2 -2
  247. package/dist/mjs/toolbar/widgets/TextToolWidget.mjs +5 -5
  248. package/dist/mjs/toolbar/widgets/components/makeFileInput.mjs +7 -7
  249. package/dist/mjs/toolbar/widgets/components/makeGridSelector.mjs +5 -5
  250. package/dist/mjs/toolbar/widgets/components/makeSnappedList.mjs +9 -5
  251. package/dist/mjs/toolbar/widgets/keybindings.mjs +2 -2
  252. package/dist/mjs/toolbar/widgets/layout/DropdownLayoutManager.mjs +6 -6
  253. package/dist/mjs/tools/BaseTool.mjs +6 -4
  254. package/dist/mjs/tools/Eraser.mjs +25 -20
  255. package/dist/mjs/tools/FindTool.mjs +2 -2
  256. package/dist/mjs/tools/InputFilter/ContextMenuRecognizer.mjs +2 -4
  257. package/dist/mjs/tools/InputFilter/InputMapper.mjs +1 -1
  258. package/dist/mjs/tools/InputFilter/InputPipeline.mjs +1 -1
  259. package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +13 -6
  260. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +7 -4
  261. package/dist/mjs/tools/PanZoom.d.ts +1 -1
  262. package/dist/mjs/tools/PanZoom.mjs +19 -14
  263. package/dist/mjs/tools/PasteHandler.mjs +8 -2
  264. package/dist/mjs/tools/Pen.d.ts +13 -0
  265. package/dist/mjs/tools/Pen.mjs +31 -10
  266. package/dist/mjs/tools/ScrollbarTool.mjs +8 -7
  267. package/dist/mjs/tools/SelectionTool/Selection.mjs +16 -12
  268. package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +5 -2
  269. package/dist/mjs/tools/SelectionTool/SelectionMenuShortcut.mjs +3 -1
  270. package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +26 -17
  271. package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.mjs +1 -1
  272. package/dist/mjs/tools/SelectionTool/TransformMode.mjs +6 -7
  273. package/dist/mjs/tools/SelectionTool/util/makeClipboardErrorHandlers.mjs +23 -2
  274. package/dist/mjs/tools/SelectionTool/util/showSelectionContextMenu.mjs +29 -20
  275. package/dist/mjs/tools/SoundUITool.mjs +5 -3
  276. package/dist/mjs/tools/TextTool.mjs +8 -6
  277. package/dist/mjs/tools/ToolController.mjs +16 -10
  278. package/dist/mjs/tools/lib.d.ts +1 -0
  279. package/dist/mjs/tools/lib.mjs +1 -0
  280. package/dist/mjs/tools/localization.d.ts +2 -0
  281. package/dist/mjs/tools/localization.mjs +3 -1
  282. package/dist/mjs/tools/util/StationaryPenDetector.mjs +3 -3
  283. package/dist/mjs/tools/util/createMenuOverlay.mjs +2 -2
  284. package/dist/mjs/util/ClipboardHandler.d.ts +1 -1
  285. package/dist/mjs/util/ClipboardHandler.mjs +19 -18
  286. package/dist/mjs/util/ReactiveValue.mjs +16 -12
  287. package/dist/mjs/util/adjustEditorThemeForContrast.mjs +6 -2
  288. package/dist/mjs/util/cloneElementWithStyles.mjs +1 -1
  289. package/dist/mjs/util/createElement.d.ts +62 -0
  290. package/dist/mjs/util/createElement.mjs +47 -0
  291. package/dist/mjs/util/guessKeyCodeFromKey.mjs +1 -1
  292. package/dist/mjs/util/listenForKeyboardEventsFrom.mjs +8 -6
  293. package/dist/mjs/util/waitForAll.mjs +3 -3
  294. package/dist/mjs/util/waitForImageLoaded.mjs +3 -3
  295. package/dist/mjs/util/waitForTimeout.mjs +1 -1
  296. package/dist/mjs/version.mjs +1 -1
  297. package/package.json +88 -88
  298. package/src/Coloris.css +6 -6
  299. package/src/Editor.scss +7 -5
  300. package/src/dialogs/dialogs.scss +3 -4
  301. package/src/dialogs/makeAboutDialog.scss +2 -2
  302. package/src/dialogs/makeMessageDialog.scss +11 -7
  303. package/src/styles.js +1 -1
  304. package/src/toolbar/AbstractToolbar.scss +20 -12
  305. package/src/toolbar/DropdownToolbar.scss +5 -4
  306. package/src/toolbar/EdgeToolbar.scss +65 -31
  307. package/src/toolbar/toolbar.scss +5 -5
  308. package/src/toolbar/utils/HelpDisplay.scss +48 -25
  309. package/src/toolbar/utils/labelVisibleOnHover.scss +39 -16
  310. package/src/toolbar/widgets/DocumentPropertiesWidget.scss +0 -1
  311. package/src/toolbar/widgets/HandToolWidget.scss +0 -1
  312. package/src/toolbar/widgets/InsertImageWidget/InsertImageWidget.scss +2 -3
  313. package/src/toolbar/widgets/OverflowWidget.css +1 -2
  314. package/src/toolbar/widgets/PenToolWidget.scss +0 -2
  315. package/src/toolbar/widgets/SelectionToolWidget.scss +1 -2
  316. package/src/toolbar/widgets/components/components.scss +6 -6
  317. package/src/toolbar/widgets/components/makeColorInput.scss +0 -2
  318. package/src/toolbar/widgets/components/makeFileInput.scss +5 -7
  319. package/src/toolbar/widgets/components/makeGridSelector.scss +6 -9
  320. package/src/toolbar/widgets/components/makeSnappedList.scss +3 -4
  321. package/src/toolbar/widgets/components/makeThicknessSlider.scss +1 -2
  322. package/src/toolbar/widgets/widgets.scss +7 -7
  323. package/src/tools/FindTool.css +1 -2
  324. package/src/tools/ScrollbarTool.scss +9 -5
  325. package/src/tools/SelectionTool/SelectionTool.scss +15 -7
  326. package/src/tools/SelectionTool/util/makeClipboardErrorHandlers.scss +1 -2
  327. package/src/tools/SoundUITool.scss +4 -4
  328. package/src/tools/tools.scss +5 -6
  329. package/src/tools/util/createMenuOverlay.scss +10 -4
  330. package/tsconfig.json +1 -3
  331. package/typedoc.json +1 -1
@@ -10,31 +10,8 @@ const RenderablePathSpec_1 = require("../RenderablePathSpec");
10
10
  /**
11
11
  * Renders onto a `CanvasRenderingContext2D`.
12
12
  *
13
- * @example
14
- * ```ts,runnable
15
- * import {Editor,CanvasRenderer} from 'js-draw';
16
- *
17
- * // Create an editor and load initial data -- don't add to the body (hidden editor).
18
- * const editor = new Editor(document.createElement('div'));
19
- * await editor.loadFromSVG('<svg><path d="m0,0 l100,5 l-50,60 l30,20 z" fill="green"/></svg>');
20
- * ---visible---
21
- * // Given some editor.
22
- * // Set up the canvas to be drawn onto.
23
- * const canvas = document.createElement('canvas');
24
- * const ctx = canvas.getContext('2d');
25
- *
26
- * // Ensure that the canvas can fit the entire rendering
27
- * const viewport = editor.image.getImportExportViewport();
28
- * canvas.width = viewport.getScreenRectSize().x;
29
- * canvas.height = viewport.getScreenRectSize().y;
30
- *
31
- * // Render editor.image onto the renderer
32
- * const renderer = new CanvasRenderer(ctx, viewport);
33
- * editor.image.render(renderer, viewport);
34
- *
35
- * // Add the rendered canvas to the document.
36
- * document.body.appendChild(canvas);
37
- * ```
13
+ * **Example**:
14
+ * [[include:doc-pages/inline-examples/canvas-renderer.md]]
38
15
  */
39
16
  class CanvasRenderer extends AbstractRenderer_1.default {
40
17
  /**
@@ -136,8 +113,8 @@ class CanvasRenderer extends AbstractRenderer_1.default {
136
113
  // Approximate the curve if small enough.
137
114
  const delta1 = p2.minus(p1);
138
115
  const delta2 = p3.minus(p2);
139
- if (delta1.magnitudeSquared() < this.minSquareCurveApproxDist
140
- && delta2.magnitudeSquared() < this.minSquareCurveApproxDist) {
116
+ if (delta1.magnitudeSquared() < this.minSquareCurveApproxDist &&
117
+ delta2.magnitudeSquared() < this.minSquareCurveApproxDist) {
141
118
  this.ctx.lineTo(p3.x, p3.y);
142
119
  }
143
120
  else {
@@ -230,7 +207,8 @@ class CanvasRenderer extends AbstractRenderer_1.default {
230
207
  }
231
208
  }
232
209
  // If exiting an object with a too-small-to-draw bounding box,
233
- if (this.ignoreObjectsAboveLevel !== null && this.getNestingLevel() <= this.ignoreObjectsAboveLevel) {
210
+ if (this.ignoreObjectsAboveLevel !== null &&
211
+ this.getNestingLevel() <= this.ignoreObjectsAboveLevel) {
234
212
  this.ignoreObjectsAboveLevel = null;
235
213
  this.ignoringObject = false;
236
214
  }
@@ -104,7 +104,7 @@ class DummyRenderer extends AbstractRenderer_1.default {
104
104
  this.renderedPathCount += other.renderedPathCount;
105
105
  this.lastFillStyle = other.lastFillStyle;
106
106
  this.lastPoint = other.lastPoint;
107
- this.pointBuffer.push(...other.pointBuffer.map(point => {
107
+ this.pointBuffer.push(...other.pointBuffer.map((point) => {
108
108
  return transform.transformVec2(point);
109
109
  }));
110
110
  }
@@ -49,7 +49,7 @@ class SVGRenderer extends AbstractRenderer_1.default {
49
49
  if (!this.elem.querySelector(`#${exports.renderedStylesheetId}`)) {
50
50
  // Default to rounded strokes.
51
51
  const styleSheet = document.createElementNS('http://www.w3.org/2000/svg', 'style');
52
- styleSheet.innerHTML = `
52
+ styleSheet.appendChild(document.createTextNode(`
53
53
  path {
54
54
  stroke-linecap: round;
55
55
  stroke-linejoin: round;
@@ -58,7 +58,7 @@ class SVGRenderer extends AbstractRenderer_1.default {
58
58
  text {
59
59
  white-space: pre;
60
60
  }
61
- `.replace(/\s+/g, '');
61
+ `.replace(/\s+/g, '')));
62
62
  styleSheet.setAttribute('id', exports.renderedStylesheetId);
63
63
  this.elem.appendChild(styleSheet);
64
64
  }
@@ -126,7 +126,9 @@ class SVGRenderer extends AbstractRenderer_1.default {
126
126
  const style = pathSpec.style;
127
127
  const path = (0, RenderablePathSpec_1.pathFromRenderable)(pathSpec).transformedBy(this.getCanvasToScreenTransform());
128
128
  // Try to extend the previous path, if possible
129
- if (this.lastPathString.length === 0 || !this.lastPathStyle || !(0, RenderingStyle_1.stylesEqual)(this.lastPathStyle, style)) {
129
+ if (this.lastPathString.length === 0 ||
130
+ !this.lastPathStyle ||
131
+ !(0, RenderingStyle_1.stylesEqual)(this.lastPathStyle, style)) {
130
132
  this.addPathToSVG();
131
133
  this.lastPathStyle = style;
132
134
  this.lastPathString = [];
@@ -136,7 +138,9 @@ class SVGRenderer extends AbstractRenderer_1.default {
136
138
  // Apply [elemTransform] to [elem]. Uses both a `matrix` and `.x`, `.y` properties if `setXY` is true.
137
139
  // Otherwise, just uses a `matrix`.
138
140
  transformFrom(elemTransform, elem, inCanvasSpace = false) {
139
- const transform = !inCanvasSpace ? this.getCanvasToScreenTransform().rightMul(elemTransform) : elemTransform;
141
+ const transform = !inCanvasSpace
142
+ ? this.getCanvasToScreenTransform().rightMul(elemTransform)
143
+ : elemTransform;
140
144
  if (!transform.eq(math_1.Mat33.identity)) {
141
145
  const matrixString = transform.toCSSMatrix();
142
146
  elem.style.transform = matrixString;
@@ -261,15 +265,15 @@ class SVGRenderer extends AbstractRenderer_1.default {
261
265
  containerIDList = containerIDData[0];
262
266
  }
263
267
  }
264
- if (containerIDList.length > 0
268
+ if (containerIDList.length > 0 &&
265
269
  // containerIDList must share a prefix with the last ID list
266
270
  // otherwise, the z order of elements may have been changed from
267
271
  // the original image.
268
272
  // In the case that the z order has been changed, keep the current
269
273
  // element as a child of the root to preserve z order.
270
- && (0, listPrefixMatch_1.default)(this.lastContainerIDList, containerIDList)
274
+ (0, listPrefixMatch_1.default)(this.lastContainerIDList, containerIDList) &&
271
275
  // The component can add at most one more parent than the previous item.
272
- && this.lastContainerIDList.length >= containerIDList.length - 1) {
276
+ this.lastContainerIDList.length >= containerIDList.length - 1) {
273
277
  // Select the last
274
278
  const containerID = containerIDList[containerIDList.length - 1];
275
279
  const containerCandidates = this.elem.querySelectorAll(`g#${containerID}`);
@@ -278,7 +282,8 @@ class SVGRenderer extends AbstractRenderer_1.default {
278
282
  // If this is the first time we're entering the group, the
279
283
  // group should be empty.
280
284
  // Otherwise, this may be a case that would break z-ordering.
281
- if (container.children.length === 0 || this.lastContainerIDList.length >= containerIDList.length) {
285
+ if (container.children.length === 0 ||
286
+ this.lastContainerIDList.length >= containerIDList.length) {
282
287
  // Move all objectElems to the found container
283
288
  for (const elem of this.objectElems) {
284
289
  elem.remove();
@@ -312,15 +317,29 @@ class SVGRenderer extends AbstractRenderer_1.default {
312
317
  }
313
318
  }
314
319
  // Not implemented -- use drawPath instead.
315
- unimplementedMessage() { throw new Error('Not implemenented!'); }
316
- beginPath(_startPoint) { this.unimplementedMessage(); }
317
- endPath(_style) { this.unimplementedMessage(); }
318
- lineTo(_point) { this.unimplementedMessage(); }
319
- moveTo(_point) { this.unimplementedMessage(); }
320
- traceCubicBezierCurve(_controlPoint1, _controlPoint2, _endPoint) { this.unimplementedMessage(); }
321
- traceQuadraticBezierCurve(_controlPoint, _endPoint) { this.unimplementedMessage(); }
320
+ unimplementedMessage() {
321
+ throw new Error('Not implemenented!');
322
+ }
323
+ beginPath(_startPoint) {
324
+ this.unimplementedMessage();
325
+ }
326
+ endPath(_style) {
327
+ this.unimplementedMessage();
328
+ }
329
+ lineTo(_point) {
330
+ this.unimplementedMessage();
331
+ }
332
+ moveTo(_point) {
333
+ this.unimplementedMessage();
334
+ }
335
+ traceCubicBezierCurve(_controlPoint1, _controlPoint2, _endPoint) {
336
+ this.unimplementedMessage();
337
+ }
338
+ traceQuadraticBezierCurve(_controlPoint, _endPoint) {
339
+ this.unimplementedMessage();
340
+ }
322
341
  drawPoints(...points) {
323
- points.map(point => {
342
+ points.map((point) => {
324
343
  const elem = document.createElementNS(svgNameSpace, 'circle');
325
344
  elem.setAttribute('cx', `${point.x}`);
326
345
  elem.setAttribute('cy', `${point.y}`);
@@ -334,7 +353,8 @@ class SVGRenderer extends AbstractRenderer_1.default {
334
353
  return;
335
354
  }
336
355
  // Don't add multiple copies of the default stylesheet.
337
- if (elem.tagName.toLowerCase() === 'style' && elem.getAttribute('id') === exports.renderedStylesheetId) {
356
+ if (elem.tagName.toLowerCase() === 'style' &&
357
+ elem.getAttribute('id') === exports.renderedStylesheetId) {
338
358
  return;
339
359
  }
340
360
  const elemToDraw = elem.cloneNode(true);
@@ -369,9 +389,7 @@ class SVGRenderer extends AbstractRenderer_1.default {
369
389
  let viewBoxComponents;
370
390
  if (useViewBoxForPositioning) {
371
391
  const exportRect = viewport.visibleRect;
372
- viewBoxComponents = [
373
- exportRect.x, exportRect.y, exportRect.w, exportRect.h,
374
- ];
392
+ viewBoxComponents = [exportRect.x, exportRect.y, exportRect.w, exportRect.h];
375
393
  // Replace the viewport with a copy that has a modified transform.
376
394
  // (Avoids modifying the original viewport).
377
395
  viewport = viewport.getTemporaryClone();
@@ -383,7 +401,7 @@ class SVGRenderer extends AbstractRenderer_1.default {
383
401
  viewBoxComponents = [0, 0, screenRectSize.x, screenRectSize.y];
384
402
  }
385
403
  // rect.x -> size of rect in x direction, rect.y -> size of rect in y direction.
386
- result.setAttribute('viewBox', viewBoxComponents.map(part => (0, math_1.toRoundedString)(part)).join(' '));
404
+ result.setAttribute('viewBox', viewBoxComponents.map((part) => (0, math_1.toRoundedString)(part)).join(' '));
387
405
  result.setAttribute('width', (0, math_1.toRoundedString)(screenRectSize.x));
388
406
  result.setAttribute('height', (0, math_1.toRoundedString)(screenRectSize.y));
389
407
  // Ensure the image can be identified as an SVG if downloaded.
@@ -29,36 +29,34 @@ class TextOnlyRenderer extends AbstractRenderer_1.default {
29
29
  return [
30
30
  this.localizationTable.pathNodeCount(this.pathCount),
31
31
  ...(this.textNodeCount > 0 ? [this.localizationTable.textNodeCount(this.textNodeCount)] : []),
32
- ...(this.imageNodeCount > 0 ? [this.localizationTable.imageNodeCount(this.imageNodeCount)] : []),
33
- ...this.descriptionBuilder
32
+ ...(this.imageNodeCount > 0
33
+ ? [this.localizationTable.imageNodeCount(this.imageNodeCount)]
34
+ : []),
35
+ ...this.descriptionBuilder,
34
36
  ].join('\n');
35
37
  }
36
- beginPath(_startPoint) {
37
- }
38
+ beginPath(_startPoint) { }
38
39
  endPath(_style) {
39
40
  this.pathCount++;
40
41
  }
41
- lineTo(_point) {
42
- }
43
- moveTo(_point) {
44
- }
45
- traceCubicBezierCurve(_p1, _p2, _p3) {
46
- }
47
- traceQuadraticBezierCurve(_controlPoint, _endPoint) {
48
- }
42
+ lineTo(_point) { }
43
+ moveTo(_point) { }
44
+ traceCubicBezierCurve(_p1, _p2, _p3) { }
45
+ traceQuadraticBezierCurve(_controlPoint, _endPoint) { }
49
46
  drawText(text, _transform, _style) {
50
47
  this.descriptionBuilder.push(this.localizationTable.textNode(text));
51
48
  this.textNodeCount++;
52
49
  }
53
50
  drawImage(image) {
54
- const label = image.label ? this.localizationTable.imageNode(image.label) : this.localizationTable.unlabeledImageNode;
51
+ const label = image.label
52
+ ? this.localizationTable.imageNode(image.label)
53
+ : this.localizationTable.unlabeledImageNode;
55
54
  this.descriptionBuilder.push(label);
56
55
  this.imageNodeCount++;
57
56
  }
58
57
  isTooSmallToRender(rect) {
59
58
  return rect.maxDimension < 15 / this.getSizeOfCanvasPixelOnScreen();
60
59
  }
61
- drawPoints(..._points) {
62
- }
60
+ drawPoints(..._points) { }
63
61
  }
64
62
  exports.default = TextOnlyRenderer;
@@ -1,14 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const isUppercaseLetter = (text) => {
4
- return text.toUpperCase() === text
5
- && text.toLowerCase() !== text
6
- && text.length === 1;
4
+ return text.toUpperCase() === text && text.toLowerCase() !== text && text.length === 1;
7
5
  };
8
6
  const isLowercaseLetter = (text) => {
9
- return text.toLowerCase() === text
10
- && text.toUpperCase() !== text
11
- && text.length === 1;
7
+ return text.toLowerCase() === text && text.toUpperCase() !== text && text.length === 1;
12
8
  };
13
9
  /** Represents a key combination that can trigger a keyboard shortcut. */
14
10
  class KeyBinding {
@@ -51,12 +47,10 @@ class KeyBinding {
51
47
  const shortcutControlOrMeta = this.controlOrMeta;
52
48
  // Match ctrl/meta if the shortcut doesn't have controlOrMeta specified
53
49
  // (controlOrMeta should match either).
54
- const ctrlAndMetaMatches = ctrlKey === this.ctrlKey
55
- && metaKey === this.metaKey
56
- && !shortcutControlOrMeta;
57
- const matches = (ctrlAndMetaMatches || (shortcutControlOrMeta && keyEventHasCtrlOrMeta))
58
- && altKey === this.altKey
59
- && (shiftKey === this.shiftKey || this.shiftKey === undefined);
50
+ const ctrlAndMetaMatches = ctrlKey === this.ctrlKey && metaKey === this.metaKey && !shortcutControlOrMeta;
51
+ const matches = (ctrlAndMetaMatches || (shortcutControlOrMeta && keyEventHasCtrlOrMeta)) &&
52
+ altKey === this.altKey &&
53
+ (shiftKey === this.shiftKey || this.shiftKey === undefined);
60
54
  return matches;
61
55
  }
62
56
  /**
@@ -82,8 +82,8 @@ class KeyboardShortcutManager {
82
82
  return false;
83
83
  }
84
84
  // Convert the strings to shortcut maps.
85
- const shortcutsAsShortcuts = shortcuts.map(shortcut => {
86
- if (typeof (shortcut) === 'string') {
85
+ const shortcutsAsShortcuts = shortcuts.map((shortcut) => {
86
+ if (typeof shortcut === 'string') {
87
87
  return KeyBinding_1.default.fromString(shortcut);
88
88
  }
89
89
  return shortcut;
@@ -5,10 +5,15 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  const Display_1 = require("../rendering/Display");
7
7
  const Editor_1 = __importDefault(require("../Editor"));
8
+ const getLocalizationTable_1 = __importDefault(require("../localizations/getLocalizationTable"));
8
9
  /** Creates an editor. Should only be used in test files. */
9
10
  exports.default = (settings) => {
10
11
  if (jest === undefined) {
11
12
  throw new Error('Files in the testing/ folder should only be used in tests!');
12
13
  }
13
- return new Editor_1.default(document.body, { renderingMode: Display_1.RenderingMode.DummyRenderer, ...settings });
14
+ return new Editor_1.default(document.body, {
15
+ renderingMode: Display_1.RenderingMode.DummyRenderer,
16
+ localization: (0, getLocalizationTable_1.default)(['en']),
17
+ ...settings,
18
+ });
14
19
  };
@@ -1,3 +1,6 @@
1
+ interface Options {
2
+ tag?: string;
3
+ }
1
4
  /** Returns the first node or element with `textContent` matching `expectedText`. */
2
- declare const findNodeWithText: (expectedText: string, parent: Node) => Node | null;
5
+ declare const findNodeWithText: (expectedText: string, parent: Node, options?: Options) => Node | null;
3
6
  export default findNodeWithText;
@@ -1,12 +1,21 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  /** Returns the first node or element with `textContent` matching `expectedText`. */
4
- const findNodeWithText = (expectedText, parent) => {
4
+ const findNodeWithText = (expectedText, parent, options = {}) => {
5
+ const { tag } = options;
5
6
  if (parent.textContent === expectedText) {
6
- return parent;
7
+ const matchesTag = (() => {
8
+ // No tag check necessary?
9
+ if (!tag)
10
+ return true;
11
+ return parent instanceof Element && tag.toUpperCase() === parent.tagName;
12
+ })();
13
+ if (matchesTag) {
14
+ return parent;
15
+ }
7
16
  }
8
17
  for (const child of parent.childNodes) {
9
- const results = findNodeWithText(expectedText, child);
18
+ const results = findNodeWithText(expectedText, child, options);
10
19
  if (results) {
11
20
  return results;
12
21
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  /** Returns the smallest ID not used by the pointers in the given list. */
4
4
  const getUniquePointerId = (pointers) => {
5
5
  let ptrId = 0;
6
- const pointerIds = pointers.map(ptr => ptr.id);
6
+ const pointerIds = pointers.map((ptr) => ptr.id);
7
7
  pointerIds.sort();
8
8
  for (const pointerId of pointerIds) {
9
9
  if (ptrId === pointerId) {
@@ -2,13 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  /** Swipes `element` using HTML pointer events. */
4
4
  const sendHtmlSwipe = async (element, start, end, timeMs = 300) => {
5
- element.dispatchEvent(new PointerEvent('pointerdown', { isPrimary: true, clientX: start.x, clientY: start.y, }));
5
+ element.dispatchEvent(new PointerEvent('pointerdown', { isPrimary: true, clientX: start.x, clientY: start.y }));
6
6
  const step = 0.1;
7
7
  for (let i = 0; i < 1; i += step) {
8
8
  await jest.advanceTimersByTimeAsync(timeMs * step);
9
9
  const currentPoint = start.lerp(end, i);
10
- element.dispatchEvent(new PointerEvent('pointermove', { isPrimary: true, clientX: currentPoint.x, clientY: currentPoint.y, }));
10
+ element.dispatchEvent(new PointerEvent('pointermove', {
11
+ isPrimary: true,
12
+ clientX: currentPoint.x,
13
+ clientY: currentPoint.y,
14
+ }));
11
15
  }
12
- element.dispatchEvent(new PointerEvent('pointerup', { isPrimary: true, clientX: end.x, clientY: end.y, }));
16
+ element.dispatchEvent(new PointerEvent('pointerup', { isPrimary: true, clientX: end.x, clientY: end.y }));
13
17
  };
14
18
  exports.default = sendHtmlSwipe;
@@ -40,9 +40,7 @@ const sendPenEvent = (editor, eventType, point, allPointers, deviceType = Pointe
40
40
  const mainPointer = Pointer_1.default.ofCanvasPoint(point, eventType !== inputEvents_1.InputEvtType.PointerUpEvt, editor.viewport, id, deviceType);
41
41
  editor.toolController.dispatchInputEvent({
42
42
  kind: eventType,
43
- allPointers: allPointers ?? [
44
- mainPointer,
45
- ],
43
+ allPointers: allPointers ?? [mainPointer],
46
44
  current: mainPointer,
47
45
  });
48
46
  return mainPointer;
@@ -73,10 +73,7 @@ const sendTouchEvent = (editor, eventType, screenPos, allOtherPointers) => {
73
73
  const mainPointer = Pointer_1.default.ofCanvasPoint(canvasPos, eventType !== inputEvents_1.InputEvtType.PointerUpEvt, editor.viewport, ptrId, Pointer_1.PointerDevice.Touch);
74
74
  editor.toolController.dispatchInputEvent({
75
75
  kind: eventType,
76
- allPointers: [
77
- ...(allOtherPointers ?? []),
78
- mainPointer,
79
- ],
76
+ allPointers: [...(allOtherPointers ?? []), mainPointer],
80
77
  current: mainPointer,
81
78
  });
82
79
  return mainPointer;
@@ -22,7 +22,9 @@ const startPinchGesture = (editor, center, initialDistance, initialRotation) =>
22
22
  };
23
23
  let [touchPoint1, touchPoint2] = computeTouchPoints(center, initialDistance, initialRotation);
24
24
  let firstPointer = (0, sendTouchEvent_1.default)(editor, inputEvents_1.InputEvtType.PointerDownEvt, touchPoint1);
25
- let secondPointer = (0, sendTouchEvent_1.default)(editor, inputEvents_1.InputEvtType.PointerDownEvt, touchPoint2, [firstPointer]);
25
+ let secondPointer = (0, sendTouchEvent_1.default)(editor, inputEvents_1.InputEvtType.PointerDownEvt, touchPoint2, [
26
+ firstPointer,
27
+ ]);
26
28
  return {
27
29
  update(center, distance, rotation) {
28
30
  const eventType = inputEvents_1.InputEvtType.PointerMoveEvt;
@@ -110,6 +110,25 @@ export default abstract class AbstractToolbar {
110
110
  * as being the value of `mustBeToplevel`.
111
111
  *
112
112
  * @return The added button.
113
+ *
114
+ * **Example**:
115
+ * ```ts,runnable
116
+ * import { Editor } from 'js-draw';
117
+ * const editor = new Editor(document.body);
118
+ * const toolbar = editor.addToolbar();
119
+ *
120
+ * function makeTrashIcon() {
121
+ * const container = document.createElement('div');
122
+ * container.textContent = '🗑️';
123
+ * return container;
124
+ * }
125
+ *
126
+ * toolbar.addActionButton({
127
+ * icon: makeTrashIcon(), // can be any Element not in the DOM
128
+ * label: 'Delete all',
129
+ * }, () => {
130
+ * alert('to-do!');
131
+ * });
113
132
  */
114
133
  addActionButton(title: string | ActionButtonIcon, command: () => void, options?: ToolbarActionButtonOptions | boolean): BaseWidget;
115
134
  /**
@@ -138,7 +138,7 @@ class AbstractToolbar {
138
138
  initColoris();
139
139
  }
140
140
  };
141
- __classPrivateFieldGet(this, _AbstractToolbar_listeners, "f").push(this.editor.notifier.on(types_1.EditorEventType.ColorPickerToggled, event => {
141
+ __classPrivateFieldGet(this, _AbstractToolbar_listeners, "f").push(this.editor.notifier.on(types_1.EditorEventType.ColorPickerToggled, (event) => {
142
142
  if (event.kind !== types_1.EditorEventType.ColorPickerToggled) {
143
143
  return;
144
144
  }
@@ -149,7 +149,7 @@ class AbstractToolbar {
149
149
  }
150
150
  }));
151
151
  // Add newly-selected colors to the swatch.
152
- __classPrivateFieldGet(this, _AbstractToolbar_listeners, "f").push(this.editor.notifier.on(types_1.EditorEventType.ColorPickerColorSelected, event => {
152
+ __classPrivateFieldGet(this, _AbstractToolbar_listeners, "f").push(this.editor.notifier.on(types_1.EditorEventType.ColorPickerColorSelected, (event) => {
153
153
  if (event.kind === types_1.EditorEventType.ColorPickerColorSelected) {
154
154
  addColorToSwatch(event.color.toHexString());
155
155
  }
@@ -193,7 +193,7 @@ class AbstractToolbar {
193
193
  const id = widget.getUniqueIdIn(__classPrivateFieldGet(this, _AbstractToolbar_widgetsById, "f"));
194
194
  this.removeWidgetInternal(widget);
195
195
  delete __classPrivateFieldGet(this, _AbstractToolbar_widgetsById, "f")[id];
196
- __classPrivateFieldSet(this, _AbstractToolbar_widgetList, __classPrivateFieldGet(this, _AbstractToolbar_widgetList, "f").filter(otherWidget => otherWidget !== widget), "f");
196
+ __classPrivateFieldSet(this, _AbstractToolbar_widgetList, __classPrivateFieldGet(this, _AbstractToolbar_widgetList, "f").filter((otherWidget) => otherWidget !== widget), "f");
197
197
  }
198
198
  /** Returns a snapshot of the state of widgets in the toolbar. */
199
199
  serializeState() {
@@ -269,6 +269,25 @@ class AbstractToolbar {
269
269
  * as being the value of `mustBeToplevel`.
270
270
  *
271
271
  * @return The added button.
272
+ *
273
+ * **Example**:
274
+ * ```ts,runnable
275
+ * import { Editor } from 'js-draw';
276
+ * const editor = new Editor(document.body);
277
+ * const toolbar = editor.addToolbar();
278
+ *
279
+ * function makeTrashIcon() {
280
+ * const container = document.createElement('div');
281
+ * container.textContent = '🗑️';
282
+ * return container;
283
+ * }
284
+ *
285
+ * toolbar.addActionButton({
286
+ * icon: makeTrashIcon(), // can be any Element not in the DOM
287
+ * label: 'Delete all',
288
+ * }, () => {
289
+ * alert('to-do!');
290
+ * });
272
291
  */
273
292
  addActionButton(title, command, options = true) {
274
293
  const widget = this.makeActionButton(title, command, options);
@@ -336,19 +355,15 @@ class AbstractToolbar {
336
355
  */
337
356
  addUndoRedoButtons(undoFirst = true) {
338
357
  const makeUndo = () => {
339
- return this.addTaggedActionButton([
340
- BaseWidget_1.ToolbarWidgetTag.Undo,
341
- ], {
358
+ return this.addTaggedActionButton([BaseWidget_1.ToolbarWidgetTag.Undo], {
342
359
  label: this.localizationTable.undo,
343
- icon: this.editor.icons.makeUndoIcon()
360
+ icon: this.editor.icons.makeUndoIcon(),
344
361
  }, () => {
345
362
  this.editor.history.undo();
346
363
  });
347
364
  };
348
365
  const makeRedo = () => {
349
- return this.addTaggedActionButton([
350
- BaseWidget_1.ToolbarWidgetTag.Redo,
351
- ], {
366
+ return this.addTaggedActionButton([BaseWidget_1.ToolbarWidgetTag.Redo], {
352
367
  label: this.localizationTable.redo,
353
368
  icon: this.editor.icons.makeRedoIcon(),
354
369
  }, () => {
@@ -367,7 +382,7 @@ class AbstractToolbar {
367
382
  }
368
383
  undoButton.setDisabled(true);
369
384
  redoButton.setDisabled(true);
370
- this.editor.notifier.on(types_1.EditorEventType.UndoRedoStackUpdated, event => {
385
+ this.editor.notifier.on(types_1.EditorEventType.UndoRedoStackUpdated, (event) => {
371
386
  if (event.kind !== types_1.EditorEventType.UndoRedoStackUpdated) {
372
387
  throw new Error('Wrong event type!');
373
388
  }
@@ -79,7 +79,7 @@ class EdgeToolbar extends AbstractToolbar_1.default {
79
79
  this.sidebarContainer.classList.add(`${constants_1.toolbarCSSPrefix}tool-properties`);
80
80
  this.sidebarContent = document.createElement('div');
81
81
  // Setup resizing/dragging
82
- this.sidebarY.onUpdateAndNow(y => {
82
+ this.sidebarY.onUpdateAndNow((y) => {
83
83
  const belowEdgeClassName = 'dropdown-below-edge';
84
84
  if (y > 0) {
85
85
  this.sidebarContainer.style.transform = `translate(0, ${y}px)`;
@@ -96,12 +96,12 @@ class EdgeToolbar extends AbstractToolbar_1.default {
96
96
  this.closeButton.classList.add('drag-elem');
97
97
  // The close button has default focus -- forward its events to the main editor so that keyboard
98
98
  // shortcuts still work.
99
- this.editor.handleKeyEventsFrom(this.closeButton, event => {
99
+ this.editor.handleKeyEventsFrom(this.closeButton, (event) => {
100
100
  // Don't send
101
101
  return event.code !== 'Space' && event.code !== 'Enter' && event.code !== 'Tab';
102
102
  });
103
103
  // Close the sidebar when pressing escape
104
- this.sidebarContainer.addEventListener('keyup', event => {
104
+ this.sidebarContainer.addEventListener('keyup', (event) => {
105
105
  if (!event.defaultPrevented && event.code === 'Escape') {
106
106
  this.sidebarVisible.set(false);
107
107
  event.preventDefault();
@@ -115,7 +115,7 @@ class EdgeToolbar extends AbstractToolbar_1.default {
115
115
  };
116
116
  this.sidebarTitle = ReactiveValue_1.MutableReactiveValue.fromInitialValue('');
117
117
  this.layoutManager = new EdgeToolbarLayoutManager_1.default(setSidebarContent, this.sidebarTitle, this.sidebarVisible, editor.announceForAccessibility.bind(editor), localizationTable);
118
- this.sidebarTitle.onUpdateAndNow(title => {
118
+ this.sidebarTitle.onUpdateAndNow((title) => {
119
119
  this.closeButton.setAttribute('aria-label', localizationTable.closeSidebar(title));
120
120
  });
121
121
  // Make things visible/keep hidden.
@@ -134,7 +134,7 @@ class EdgeToolbar extends AbstractToolbar_1.default {
134
134
  this.menuContainer.style.opacity = '0';
135
135
  }
136
136
  const prefersReduceMotion = window.matchMedia?.('(prefers-reduced-motion: reduce)') ?? '';
137
- this.sidebarVisible.onUpdate(visible => {
137
+ this.sidebarVisible.onUpdate((visible) => {
138
138
  const animationProperties = `${animationDuration}ms ease`;
139
139
  // We need to use different animations when reducing motion.
140
140
  const reduceMotion = prefersReduceMotion.matches ? '-reduce-motion' : '';
@@ -145,23 +145,19 @@ class EdgeToolbar extends AbstractToolbar_1.default {
145
145
  animationTimeout = null;
146
146
  }
147
147
  this.menuContainer.style.display = '';
148
- this.sidebarContainer.style.animation =
149
- `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-transition-in${reduceMotion}`;
150
- this.menuContainer.style.animation =
151
- `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-container-transition-in${reduceMotion}`;
148
+ this.sidebarContainer.style.animation = `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-transition-in${reduceMotion}`;
149
+ this.menuContainer.style.animation = `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-container-transition-in${reduceMotion}`;
152
150
  this.menuContainer.style.opacity = '1';
153
151
  // Focus the close button when first shown, but prevent scroll because the button
154
152
  // is likely at the bottom of the screen (and we want the full sidebar to remain
155
153
  // visible).
156
- this.closeButton.focus({ preventScroll: true, });
154
+ this.closeButton.focus({ preventScroll: true });
157
155
  }
158
156
  else {
159
157
  this.closeColorPickers();
160
158
  if (animationTimeout === null) {
161
- this.sidebarContainer.style.animation =
162
- `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-transition-out${reduceMotion}`;
163
- this.menuContainer.style.animation =
164
- `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-container-transition-out${reduceMotion}`;
159
+ this.sidebarContainer.style.animation = `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-transition-out${reduceMotion}`;
160
+ this.menuContainer.style.animation = `${animationProperties} ${constants_1.toolbarCSSPrefix}-edgemenu-container-transition-out${reduceMotion}`;
165
161
  // Manually set the container's opacity to prevent flickering when closing
166
162
  // the toolbar.
167
163
  this.menuContainer.style.opacity = '0';
@@ -204,7 +200,7 @@ class EdgeToolbar extends AbstractToolbar_1.default {
204
200
  break;
205
201
  }
206
202
  }
207
- const perButtonPadding = Math.round(extraPadding / numVisibleButtons * 10) / 10;
203
+ const perButtonPadding = Math.round((extraPadding / numVisibleButtons) * 10) / 10;
208
204
  this.toolbarToolRow.style.setProperty('--extra-left-right-padding', `${perButtonPadding}px`);
209
205
  };
210
206
  const actionRowBBox = this.toolbarActionRow.getBoundingClientRect();
@@ -80,9 +80,13 @@ export default class IconProvider {
80
80
  * @returns An object with both the definition of a checkerboard pattern and the syntax to
81
81
  * reference that pattern. The defs provided by this function should be wrapped within a
82
82
  * `<defs></defs>` element.
83
+ *
84
+ * **Note**: This function's return value includes both `patternDefElement` (which returns
85
+ * an Element) and a (deprecated) `patternDef` string. Avoid using the `patternDef` result.
83
86
  */
84
87
  protected makeCheckerboardPattern(): {
85
- patternDef: string;
88
+ patternDefElement: SVGElement;
89
+ readonly patternDef: string;
86
90
  patternRef: string;
87
91
  };
88
92
  /**