js-draw 1.20.3 → 1.21.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (245) hide show
  1. package/LICENSE +1 -1
  2. package/dist/Editor.css +136 -26
  3. package/dist/bundle.js +2 -2
  4. package/dist/bundledStyles.js +1 -1
  5. package/dist/cjs/Editor.d.ts +27 -6
  6. package/dist/cjs/Editor.js +30 -8
  7. package/dist/cjs/SVGLoader/SVGLoader.js +2 -2
  8. package/dist/cjs/Viewport.d.ts +2 -2
  9. package/dist/cjs/commands/Command.d.ts +5 -0
  10. package/dist/cjs/commands/Command.js +5 -0
  11. package/dist/cjs/commands/SerializableCommand.d.ts +7 -0
  12. package/dist/cjs/commands/SerializableCommand.js +9 -0
  13. package/dist/cjs/dialogs/makeAboutDialog.d.ts +1 -1
  14. package/dist/cjs/dialogs/makeAboutDialog.js +10 -25
  15. package/dist/cjs/dialogs/makeMessageDialog.d.ts +11 -0
  16. package/dist/cjs/dialogs/makeMessageDialog.js +56 -0
  17. package/dist/cjs/image/EditorImage.d.ts +15 -1
  18. package/dist/cjs/image/EditorImage.js +15 -5
  19. package/dist/cjs/inputEvents.d.ts +10 -2
  20. package/dist/cjs/inputEvents.js +1 -0
  21. package/dist/cjs/localizations/es.js +3 -0
  22. package/dist/cjs/rendering/Display.d.ts +1 -0
  23. package/dist/cjs/rendering/Display.js +1 -0
  24. package/dist/cjs/rendering/TextRenderingStyle.d.ts +7 -6
  25. package/dist/cjs/rendering/TextRenderingStyle.js +1 -0
  26. package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
  27. package/dist/cjs/rendering/renderers/CanvasRenderer.js +15 -2
  28. package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -1
  29. package/dist/cjs/testing/firstElementAncestorOfNode.d.ts +1 -1
  30. package/dist/cjs/testing/firstElementAncestorOfNode.js +1 -1
  31. package/dist/cjs/testing/sendPenEvent.d.ts +2 -2
  32. package/dist/cjs/testing/sendTouchEvent.d.ts +2 -2
  33. package/dist/cjs/toolbar/AbstractToolbar.d.ts +6 -1
  34. package/dist/cjs/toolbar/AbstractToolbar.js +6 -1
  35. package/dist/cjs/toolbar/IconProvider.d.ts +1 -1
  36. package/dist/cjs/toolbar/IconProvider.js +6 -1
  37. package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +8 -0
  38. package/dist/cjs/toolbar/widgets/BaseWidget.js +8 -0
  39. package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  40. package/dist/cjs/toolbar/widgets/HandToolWidget.js +1 -0
  41. package/dist/cjs/toolbar/widgets/InsertImageWidget/ImageWrapper.d.ts +1 -1
  42. package/dist/cjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
  43. package/dist/cjs/toolbar/widgets/PenToolWidget.js +5 -0
  44. package/dist/cjs/types.d.ts +5 -0
  45. package/dist/cjs/types.js +1 -0
  46. package/dist/cjs/util/ClipboardHandler.d.ts +9 -1
  47. package/dist/cjs/util/ClipboardHandler.js +82 -24
  48. package/dist/cjs/version.js +1 -1
  49. package/dist/mjs/Editor.d.ts +27 -6
  50. package/dist/mjs/Editor.mjs +31 -9
  51. package/dist/mjs/SVGLoader/SVGLoader.mjs +2 -2
  52. package/dist/mjs/Viewport.d.ts +2 -2
  53. package/dist/mjs/commands/Command.d.ts +5 -0
  54. package/dist/mjs/commands/Command.mjs +5 -0
  55. package/dist/mjs/commands/SerializableCommand.d.ts +7 -0
  56. package/dist/mjs/commands/SerializableCommand.mjs +9 -0
  57. package/dist/mjs/dialogs/makeAboutDialog.d.ts +1 -1
  58. package/dist/mjs/dialogs/makeAboutDialog.mjs +7 -25
  59. package/dist/mjs/dialogs/makeMessageDialog.d.ts +11 -0
  60. package/dist/mjs/dialogs/makeMessageDialog.mjs +51 -0
  61. package/dist/mjs/image/EditorImage.d.ts +15 -1
  62. package/dist/mjs/image/EditorImage.mjs +15 -5
  63. package/dist/mjs/inputEvents.d.ts +10 -2
  64. package/dist/mjs/inputEvents.mjs +1 -0
  65. package/dist/mjs/localizations/es.mjs +3 -0
  66. package/dist/mjs/rendering/Display.d.ts +1 -0
  67. package/dist/mjs/rendering/Display.mjs +1 -0
  68. package/dist/mjs/rendering/TextRenderingStyle.d.ts +7 -6
  69. package/dist/mjs/rendering/TextRenderingStyle.mjs +1 -0
  70. package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
  71. package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +15 -2
  72. package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -1
  73. package/dist/mjs/testing/firstElementAncestorOfNode.d.ts +1 -1
  74. package/dist/mjs/testing/firstElementAncestorOfNode.mjs +1 -1
  75. package/dist/mjs/testing/sendPenEvent.d.ts +2 -2
  76. package/dist/mjs/testing/sendTouchEvent.d.ts +2 -2
  77. package/dist/mjs/toolbar/AbstractToolbar.d.ts +6 -1
  78. package/dist/mjs/toolbar/AbstractToolbar.mjs +6 -1
  79. package/dist/mjs/toolbar/IconProvider.d.ts +1 -1
  80. package/dist/mjs/toolbar/IconProvider.mjs +6 -1
  81. package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +8 -0
  82. package/dist/mjs/toolbar/widgets/BaseWidget.mjs +8 -0
  83. package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
  84. package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +1 -0
  85. package/dist/mjs/toolbar/widgets/InsertImageWidget/ImageWrapper.d.ts +1 -1
  86. package/dist/mjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
  87. package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +5 -0
  88. package/dist/mjs/types.d.ts +5 -0
  89. package/dist/mjs/types.mjs +1 -0
  90. package/dist/mjs/util/ClipboardHandler.d.ts +9 -1
  91. package/dist/mjs/util/ClipboardHandler.mjs +82 -24
  92. package/dist/mjs/version.mjs +1 -1
  93. package/package.json +8 -9
  94. package/src/dialogs/dialogs.scss +9 -21
  95. package/src/dialogs/makeAboutDialog.scss +13 -33
  96. package/src/dialogs/makeMessageDialog.scss +46 -0
  97. package/dist/cjs/tools/BaseTool.d.ts +0 -60
  98. package/dist/cjs/tools/BaseTool.js +0 -174
  99. package/dist/cjs/tools/Eraser.d.ts +0 -56
  100. package/dist/cjs/tools/Eraser.js +0 -295
  101. package/dist/cjs/tools/Eraser.test.d.ts +0 -1
  102. package/dist/cjs/tools/FindTool.d.ts +0 -21
  103. package/dist/cjs/tools/FindTool.js +0 -137
  104. package/dist/cjs/tools/FindTool.test.d.ts +0 -1
  105. package/dist/cjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
  106. package/dist/cjs/tools/InputFilter/FunctionMapper.js +0 -21
  107. package/dist/cjs/tools/InputFilter/InputMapper.d.ts +0 -23
  108. package/dist/cjs/tools/InputFilter/InputMapper.js +0 -38
  109. package/dist/cjs/tools/InputFilter/InputPipeline.d.ts +0 -15
  110. package/dist/cjs/tools/InputFilter/InputPipeline.js +0 -54
  111. package/dist/cjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
  112. package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
  113. package/dist/cjs/tools/InputFilter/InputStabilizer.js +0 -181
  114. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
  115. package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +0 -84
  116. package/dist/cjs/tools/PanZoom.d.ts +0 -119
  117. package/dist/cjs/tools/PanZoom.js +0 -508
  118. package/dist/cjs/tools/PanZoom.test.d.ts +0 -1
  119. package/dist/cjs/tools/PasteHandler.d.ts +0 -23
  120. package/dist/cjs/tools/PasteHandler.js +0 -109
  121. package/dist/cjs/tools/Pen.d.ts +0 -53
  122. package/dist/cjs/tools/Pen.js +0 -318
  123. package/dist/cjs/tools/Pen.test.d.ts +0 -1
  124. package/dist/cjs/tools/PipetteTool.d.ts +0 -28
  125. package/dist/cjs/tools/PipetteTool.js +0 -69
  126. package/dist/cjs/tools/ScrollbarTool.d.ts +0 -18
  127. package/dist/cjs/tools/ScrollbarTool.js +0 -85
  128. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
  129. package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +0 -32
  130. package/dist/cjs/tools/SelectionTool/Selection.d.ts +0 -71
  131. package/dist/cjs/tools/SelectionTool/Selection.js +0 -620
  132. package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
  133. package/dist/cjs/tools/SelectionTool/SelectionHandle.js +0 -141
  134. package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
  135. package/dist/cjs/tools/SelectionTool/SelectionTool.js +0 -494
  136. package/dist/cjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
  137. package/dist/cjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
  138. package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
  139. package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.js +0 -83
  140. package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +0 -42
  141. package/dist/cjs/tools/SelectionTool/TransformMode.js +0 -155
  142. package/dist/cjs/tools/SelectionTool/types.d.ts +0 -28
  143. package/dist/cjs/tools/SelectionTool/types.js +0 -14
  144. package/dist/cjs/tools/SoundUITool.d.ts +0 -26
  145. package/dist/cjs/tools/SoundUITool.js +0 -171
  146. package/dist/cjs/tools/TextTool.d.ts +0 -36
  147. package/dist/cjs/tools/TextTool.js +0 -285
  148. package/dist/cjs/tools/TextTool.test.d.ts +0 -1
  149. package/dist/cjs/tools/ToolController.d.ts +0 -73
  150. package/dist/cjs/tools/ToolController.js +0 -304
  151. package/dist/cjs/tools/ToolController.test.d.ts +0 -1
  152. package/dist/cjs/tools/ToolEnabledGroup.d.ts +0 -6
  153. package/dist/cjs/tools/ToolEnabledGroup.js +0 -13
  154. package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +0 -16
  155. package/dist/cjs/tools/ToolSwitcherShortcut.js +0 -40
  156. package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +0 -12
  157. package/dist/cjs/tools/ToolbarShortcutHandler.js +0 -34
  158. package/dist/cjs/tools/UndoRedoShortcut.d.ts +0 -8
  159. package/dist/cjs/tools/UndoRedoShortcut.js +0 -27
  160. package/dist/cjs/tools/UndoRedoShortcut.test.d.ts +0 -1
  161. package/dist/cjs/tools/keybindings.d.ts +0 -18
  162. package/dist/cjs/tools/keybindings.js +0 -49
  163. package/dist/cjs/tools/lib.d.ts +0 -14
  164. package/dist/cjs/tools/lib.js +0 -36
  165. package/dist/cjs/tools/localization.d.ts +0 -34
  166. package/dist/cjs/tools/localization.js +0 -36
  167. package/dist/cjs/tools/util/StationaryPenDetector.d.ts +0 -22
  168. package/dist/cjs/tools/util/StationaryPenDetector.js +0 -95
  169. package/dist/mjs/tools/BaseTool.d.ts +0 -60
  170. package/dist/mjs/tools/BaseTool.mjs +0 -172
  171. package/dist/mjs/tools/Eraser.d.ts +0 -56
  172. package/dist/mjs/tools/Eraser.mjs +0 -288
  173. package/dist/mjs/tools/Eraser.test.d.ts +0 -1
  174. package/dist/mjs/tools/FindTool.d.ts +0 -21
  175. package/dist/mjs/tools/FindTool.mjs +0 -131
  176. package/dist/mjs/tools/FindTool.test.d.ts +0 -1
  177. package/dist/mjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
  178. package/dist/mjs/tools/InputFilter/FunctionMapper.mjs +0 -15
  179. package/dist/mjs/tools/InputFilter/InputMapper.d.ts +0 -23
  180. package/dist/mjs/tools/InputFilter/InputMapper.mjs +0 -36
  181. package/dist/mjs/tools/InputFilter/InputPipeline.d.ts +0 -15
  182. package/dist/mjs/tools/InputFilter/InputPipeline.mjs +0 -49
  183. package/dist/mjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
  184. package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
  185. package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +0 -175
  186. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
  187. package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +0 -78
  188. package/dist/mjs/tools/PanZoom.d.ts +0 -119
  189. package/dist/mjs/tools/PanZoom.mjs +0 -501
  190. package/dist/mjs/tools/PanZoom.test.d.ts +0 -1
  191. package/dist/mjs/tools/PasteHandler.d.ts +0 -23
  192. package/dist/mjs/tools/PasteHandler.mjs +0 -103
  193. package/dist/mjs/tools/Pen.d.ts +0 -53
  194. package/dist/mjs/tools/Pen.mjs +0 -312
  195. package/dist/mjs/tools/Pen.test.d.ts +0 -1
  196. package/dist/mjs/tools/PipetteTool.d.ts +0 -28
  197. package/dist/mjs/tools/PipetteTool.mjs +0 -63
  198. package/dist/mjs/tools/ScrollbarTool.d.ts +0 -18
  199. package/dist/mjs/tools/ScrollbarTool.mjs +0 -79
  200. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
  201. package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +0 -26
  202. package/dist/mjs/tools/SelectionTool/Selection.d.ts +0 -71
  203. package/dist/mjs/tools/SelectionTool/Selection.mjs +0 -592
  204. package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
  205. package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +0 -137
  206. package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
  207. package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +0 -488
  208. package/dist/mjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
  209. package/dist/mjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
  210. package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
  211. package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.mjs +0 -77
  212. package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +0 -42
  213. package/dist/mjs/tools/SelectionTool/TransformMode.mjs +0 -146
  214. package/dist/mjs/tools/SelectionTool/types.d.ts +0 -28
  215. package/dist/mjs/tools/SelectionTool/types.mjs +0 -11
  216. package/dist/mjs/tools/SoundUITool.d.ts +0 -26
  217. package/dist/mjs/tools/SoundUITool.mjs +0 -165
  218. package/dist/mjs/tools/TextTool.d.ts +0 -36
  219. package/dist/mjs/tools/TextTool.mjs +0 -279
  220. package/dist/mjs/tools/TextTool.test.d.ts +0 -1
  221. package/dist/mjs/tools/ToolController.d.ts +0 -73
  222. package/dist/mjs/tools/ToolController.mjs +0 -275
  223. package/dist/mjs/tools/ToolController.test.d.ts +0 -1
  224. package/dist/mjs/tools/ToolEnabledGroup.d.ts +0 -6
  225. package/dist/mjs/tools/ToolEnabledGroup.mjs +0 -10
  226. package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +0 -16
  227. package/dist/mjs/tools/ToolSwitcherShortcut.mjs +0 -34
  228. package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +0 -12
  229. package/dist/mjs/tools/ToolbarShortcutHandler.mjs +0 -28
  230. package/dist/mjs/tools/UndoRedoShortcut.d.ts +0 -8
  231. package/dist/mjs/tools/UndoRedoShortcut.mjs +0 -21
  232. package/dist/mjs/tools/UndoRedoShortcut.test.d.ts +0 -1
  233. package/dist/mjs/tools/keybindings.d.ts +0 -18
  234. package/dist/mjs/tools/keybindings.mjs +0 -43
  235. package/dist/mjs/tools/lib.d.ts +0 -14
  236. package/dist/mjs/tools/lib.mjs +0 -14
  237. package/dist/mjs/tools/localization.d.ts +0 -34
  238. package/dist/mjs/tools/localization.mjs +0 -33
  239. package/dist/mjs/tools/util/StationaryPenDetector.d.ts +0 -22
  240. package/dist/mjs/tools/util/StationaryPenDetector.mjs +0 -92
  241. package/src/tools/FindTool.css +0 -7
  242. package/src/tools/ScrollbarTool.scss +0 -57
  243. package/src/tools/SelectionTool/SelectionTool.scss +0 -137
  244. package/src/tools/SoundUITool.scss +0 -22
  245. package/src/tools/tools.scss +0 -5
@@ -1,172 +0,0 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _BaseTool_enabled, _BaseTool_group, _BaseTool_inputMapper, _BaseTool_readOnlyEditorChangeListener;
13
- import { EditorEventType } from '../types.mjs';
14
- import { InputEvtType } from '../inputEvents.mjs';
15
- import { ReactiveValue } from '../util/ReactiveValue.mjs';
16
- class BaseTool {
17
- constructor(notifier, description) {
18
- this.notifier = notifier;
19
- this.description = description;
20
- _BaseTool_enabled.set(this, void 0);
21
- _BaseTool_group.set(this, null);
22
- _BaseTool_inputMapper.set(this, null);
23
- _BaseTool_readOnlyEditorChangeListener.set(this, null);
24
- __classPrivateFieldSet(this, _BaseTool_enabled, ReactiveValue.fromInitialValue(true), "f");
25
- __classPrivateFieldGet(this, _BaseTool_enabled, "f").onUpdate(enabled => {
26
- // Ensure that at most one tool in the group is enabled.
27
- if (enabled) {
28
- __classPrivateFieldGet(this, _BaseTool_group, "f")?.notifyEnabled(this);
29
- this.notifier.dispatch(EditorEventType.ToolEnabled, {
30
- kind: EditorEventType.ToolEnabled,
31
- tool: this,
32
- });
33
- }
34
- else {
35
- this.notifier.dispatch(EditorEventType.ToolDisabled, {
36
- kind: EditorEventType.ToolDisabled,
37
- tool: this,
38
- });
39
- }
40
- });
41
- }
42
- /** Override this to allow this tool to be enabled in a read-only editor */
43
- canReceiveInputInReadOnlyEditor() {
44
- return false;
45
- }
46
- setInputMapper(mapper) {
47
- __classPrivateFieldSet(this, _BaseTool_inputMapper, mapper, "f");
48
- if (mapper) {
49
- mapper.setEmitListener(event => this.dispatchEventToCallback(event));
50
- }
51
- }
52
- getInputMapper() {
53
- return __classPrivateFieldGet(this, _BaseTool_inputMapper, "f");
54
- }
55
- dispatchEventToCallback(event) {
56
- let exhaustivenessCheck;
57
- switch (event.kind) {
58
- case InputEvtType.PointerDownEvt:
59
- return this.onPointerDown(event);
60
- case InputEvtType.PointerMoveEvt:
61
- this.onPointerMove(event);
62
- break;
63
- case InputEvtType.PointerUpEvt:
64
- return this.onPointerUp(event) ?? false;
65
- case InputEvtType.GestureCancelEvt:
66
- this.onGestureCancel(event);
67
- break;
68
- case InputEvtType.WheelEvt:
69
- return this.onWheel(event);
70
- case InputEvtType.KeyPressEvent:
71
- return this.onKeyPress(event);
72
- case InputEvtType.KeyUpEvent:
73
- return this.onKeyUp(event);
74
- case InputEvtType.CopyEvent:
75
- return this.onCopy(event);
76
- case InputEvtType.PasteEvent:
77
- return this.onPaste(event);
78
- default:
79
- exhaustivenessCheck = event;
80
- return exhaustivenessCheck;
81
- }
82
- return true;
83
- }
84
- // @internal
85
- onEvent(event) {
86
- if (__classPrivateFieldGet(this, _BaseTool_inputMapper, "f")) {
87
- return __classPrivateFieldGet(this, _BaseTool_inputMapper, "f").onEvent(event);
88
- }
89
- return this.dispatchEventToCallback(event);
90
- }
91
- /**
92
- * Returns true iff the tool handled the event and thus should receive additional
93
- * events.
94
- */
95
- onPointerDown(_event) { return false; }
96
- onPointerMove(_event) { }
97
- /**
98
- * Returns true iff there are additional pointers down and the tool should
99
- * remain active to handle the additional events.
100
- *
101
- * For most purposes, this should return `false` or nothing.
102
- */
103
- onPointerUp(_event) { }
104
- onGestureCancel(_event) { }
105
- onWheel(_event) {
106
- return false;
107
- }
108
- onCopy(_event) {
109
- return false;
110
- }
111
- onPaste(_event) {
112
- return false;
113
- }
114
- onKeyPress(_event) {
115
- return false;
116
- }
117
- onKeyUp(_event) {
118
- return false;
119
- }
120
- /**
121
- * Return true if, while this tool is active, `_event` can be delivered to
122
- * another tool that is higher priority than this.
123
- * @internal May be renamed
124
- */
125
- eventCanBeDeliveredToNonActiveTool(_event) {
126
- return true;
127
- }
128
- setEnabled(enabled) {
129
- __classPrivateFieldGet(this, _BaseTool_enabled, "f").set(enabled);
130
- }
131
- isEnabled() {
132
- return __classPrivateFieldGet(this, _BaseTool_enabled, "f").get();
133
- }
134
- /**
135
- * Returns a {@link ReactiveValue} that updates based on whether this tool is
136
- * enabled.
137
- *
138
- * @example
139
- * ```ts
140
- * const tool = new SomeTool();
141
- *
142
- * // Watch for changes in enabled status
143
- * tool.enabledValue().onUpdate(enabled => doSomething(enabled));
144
- * ```
145
- */
146
- enabledValue() {
147
- return __classPrivateFieldGet(this, _BaseTool_enabled, "f");
148
- }
149
- // Connect this tool to a set of other tools, ensuring that at most one
150
- // of the tools in the group is enabled.
151
- setToolGroup(group) {
152
- if (this.isEnabled()) {
153
- group.notifyEnabled(this);
154
- }
155
- __classPrivateFieldSet(this, _BaseTool_group, group, "f");
156
- }
157
- getToolGroup() {
158
- if (__classPrivateFieldGet(this, _BaseTool_group, "f")) {
159
- return __classPrivateFieldGet(this, _BaseTool_group, "f");
160
- }
161
- return null;
162
- }
163
- // Called when the tool is removed/when the editor is destroyed.
164
- // Subclasses that override this method **must call super.onDestroy()**.
165
- onDestroy() {
166
- __classPrivateFieldGet(this, _BaseTool_readOnlyEditorChangeListener, "f")?.remove();
167
- __classPrivateFieldSet(this, _BaseTool_readOnlyEditorChangeListener, null, "f");
168
- __classPrivateFieldSet(this, _BaseTool_group, null, "f");
169
- }
170
- }
171
- _BaseTool_enabled = new WeakMap(), _BaseTool_group = new WeakMap(), _BaseTool_inputMapper = new WeakMap(), _BaseTool_readOnlyEditorChangeListener = new WeakMap();
172
- export default BaseTool;
@@ -1,56 +0,0 @@
1
- import { GestureCancelEvt, KeyPressEvent, PointerEvt } from '../inputEvents';
2
- import BaseTool from './BaseTool';
3
- import Editor from '../Editor';
4
- import { MutableReactiveValue } from '../util/ReactiveValue';
5
- export declare enum EraserMode {
6
- PartialStroke = "partial-stroke",
7
- FullStroke = "full-stroke"
8
- }
9
- export interface InitialEraserOptions {
10
- thickness?: number;
11
- mode?: EraserMode;
12
- }
13
- export default class Eraser extends BaseTool {
14
- private editor;
15
- private lastPoint;
16
- private isFirstEraseEvt;
17
- private thickness;
18
- private thicknessValue;
19
- private modeValue;
20
- private toRemove;
21
- private toAdd;
22
- private eraseCommands;
23
- private addCommands;
24
- constructor(editor: Editor, description: string, options?: InitialEraserOptions);
25
- /**
26
- * @returns a tool that briefly enables the eraser when a physical eraser is used.
27
- * This tool should be added to the tool list after the primary tools.
28
- */
29
- makeEraserSwitcherTool(): BaseTool;
30
- private clearPreview;
31
- private getSizeOnCanvas;
32
- private drawPreviewAt;
33
- /**
34
- * @returns the eraser rectangle in canvas coordinates.
35
- *
36
- * For now, all erasers are rectangles or points.
37
- */
38
- private getEraserRect;
39
- /** Erases in a line from the last point to the current. */
40
- private eraseTo;
41
- onPointerDown(event: PointerEvt): boolean;
42
- onPointerMove(event: PointerEvt): void;
43
- onPointerUp(event: PointerEvt): void;
44
- onGestureCancel(_event: GestureCancelEvt): void;
45
- onKeyPress(event: KeyPressEvent): boolean;
46
- /** Returns the side-length of the tip of this eraser. */
47
- getThickness(): number;
48
- /** Sets the side-length of this' tip. */
49
- setThickness(thickness: number): void;
50
- /**
51
- * Returns a {@link MutableReactiveValue} that can be used to watch
52
- * this tool's thickness.
53
- */
54
- getThicknessValue(): MutableReactiveValue<number>;
55
- getModeValue(): MutableReactiveValue<EraserMode>;
56
- }
@@ -1,288 +0,0 @@
1
- import { EditorEventType } from '../types.mjs';
2
- import BaseTool from './BaseTool.mjs';
3
- import { Vec2, LineSegment2, Color4, Rect2, Path } from '@js-draw/math';
4
- import Erase from '../commands/Erase.mjs';
5
- import { PointerDevice } from '../Pointer.mjs';
6
- import { decreaseSizeKeyboardShortcutId, increaseSizeKeyboardShortcutId } from './keybindings.mjs';
7
- import { ReactiveValue } from '../util/ReactiveValue.mjs';
8
- import EditorImage from '../image/EditorImage.mjs';
9
- import uniteCommands from '../commands/uniteCommands.mjs';
10
- import { pathToRenderable } from '../rendering/RenderablePathSpec.mjs';
11
- export var EraserMode;
12
- (function (EraserMode) {
13
- EraserMode["PartialStroke"] = "partial-stroke";
14
- EraserMode["FullStroke"] = "full-stroke";
15
- })(EraserMode || (EraserMode = {}));
16
- /** Handles switching from other primary tools to the eraser and back */
17
- class EraserSwitcher extends BaseTool {
18
- constructor(editor, eraser) {
19
- super(editor.notifier, editor.localization.changeTool);
20
- this.editor = editor;
21
- this.eraser = eraser;
22
- }
23
- onPointerDown(event) {
24
- if (event.allPointers.length === 1 && event.current.device === PointerDevice.Eraser) {
25
- const toolController = this.editor.toolController;
26
- const enabledPrimaryTools = toolController.getPrimaryTools().filter(tool => tool.isEnabled());
27
- if (enabledPrimaryTools.length) {
28
- this.previousEnabledTool = enabledPrimaryTools[0];
29
- }
30
- else {
31
- this.previousEnabledTool = null;
32
- }
33
- this.previousEraserEnabledState = this.eraser.isEnabled();
34
- this.eraser.setEnabled(true);
35
- if (this.eraser.onPointerDown(event)) {
36
- return true;
37
- }
38
- else {
39
- this.restoreOriginalTool();
40
- }
41
- }
42
- return false;
43
- }
44
- onPointerMove(event) {
45
- this.eraser.onPointerMove(event);
46
- }
47
- restoreOriginalTool() {
48
- this.eraser.setEnabled(this.previousEraserEnabledState);
49
- if (this.previousEnabledTool) {
50
- this.previousEnabledTool.setEnabled(true);
51
- }
52
- }
53
- onPointerUp(event) {
54
- this.eraser.onPointerUp(event);
55
- this.restoreOriginalTool();
56
- }
57
- onGestureCancel(event) {
58
- this.eraser.onGestureCancel(event);
59
- this.restoreOriginalTool();
60
- }
61
- }
62
- export default class Eraser extends BaseTool {
63
- constructor(editor, description, options) {
64
- super(editor.notifier, description);
65
- this.editor = editor;
66
- this.lastPoint = null;
67
- this.isFirstEraseEvt = true;
68
- this.toAdd = new Set();
69
- // Commands that each remove one element
70
- this.eraseCommands = [];
71
- this.addCommands = [];
72
- this.thickness = options?.thickness ?? 10;
73
- this.thicknessValue = ReactiveValue.fromInitialValue(this.thickness);
74
- this.thicknessValue.onUpdate(value => {
75
- this.thickness = value;
76
- this.editor.notifier.dispatch(EditorEventType.ToolUpdated, {
77
- kind: EditorEventType.ToolUpdated,
78
- tool: this,
79
- });
80
- });
81
- this.modeValue = ReactiveValue.fromInitialValue(options?.mode ?? EraserMode.FullStroke);
82
- this.modeValue.onUpdate(_value => {
83
- this.editor.notifier.dispatch(EditorEventType.ToolUpdated, {
84
- kind: EditorEventType.ToolUpdated,
85
- tool: this,
86
- });
87
- });
88
- }
89
- /**
90
- * @returns a tool that briefly enables the eraser when a physical eraser is used.
91
- * This tool should be added to the tool list after the primary tools.
92
- */
93
- makeEraserSwitcherTool() {
94
- return new EraserSwitcher(this.editor, this);
95
- }
96
- clearPreview() {
97
- this.editor.clearWetInk();
98
- }
99
- getSizeOnCanvas() {
100
- return this.thickness / this.editor.viewport.getScaleFactor();
101
- }
102
- drawPreviewAt(point) {
103
- this.clearPreview();
104
- const size = this.getSizeOnCanvas();
105
- const renderer = this.editor.display.getWetInkRenderer();
106
- const rect = this.getEraserRect(point);
107
- const rect2 = this.getEraserRect(this.lastPoint ?? point);
108
- const fill = {
109
- fill: Color4.transparent,
110
- stroke: { width: size / 10, color: Color4.gray },
111
- };
112
- renderer.drawPath(pathToRenderable(Path.fromConvexHullOf([...rect.corners, ...rect2.corners]), fill));
113
- }
114
- /**
115
- * @returns the eraser rectangle in canvas coordinates.
116
- *
117
- * For now, all erasers are rectangles or points.
118
- */
119
- getEraserRect(centerPoint) {
120
- const size = this.getSizeOnCanvas();
121
- const halfSize = Vec2.of(size / 2, size / 2);
122
- return Rect2.fromCorners(centerPoint.minus(halfSize), centerPoint.plus(halfSize));
123
- }
124
- /** Erases in a line from the last point to the current. */
125
- eraseTo(currentPoint) {
126
- if (!this.isFirstEraseEvt && currentPoint.distanceTo(this.lastPoint) === 0) {
127
- return;
128
- }
129
- this.isFirstEraseEvt = false;
130
- // Currently only objects within eraserRect or that intersect a straight line
131
- // from the center of the current rect to the previous are erased. TODO: Erase
132
- // all objects as if there were pointerMove events between the two points.
133
- const eraserRect = this.getEraserRect(currentPoint);
134
- const line = new LineSegment2(this.lastPoint, currentPoint);
135
- const region = Rect2.union(line.bbox, eraserRect);
136
- const intersectingElems = this.editor.image.getElementsIntersectingRegion(region).filter(component => {
137
- return component.intersects(line) || component.intersectsRect(eraserRect);
138
- });
139
- // Only erase components that could be selected (and thus interacted with)
140
- // by the user.
141
- const eraseableElems = intersectingElems.filter(elem => elem.isSelectable());
142
- if (this.modeValue.get() === EraserMode.FullStroke) {
143
- // Remove any intersecting elements.
144
- this.toRemove.push(...eraseableElems);
145
- // Create new Erase commands for the now-to-be-erased elements and apply them.
146
- const newPartialCommands = eraseableElems.map(elem => new Erase([elem]));
147
- newPartialCommands.forEach(cmd => cmd.apply(this.editor));
148
- this.eraseCommands.push(...newPartialCommands);
149
- }
150
- else {
151
- const toErase = [];
152
- const toAdd = [];
153
- for (const targetElem of eraseableElems) {
154
- toErase.push(targetElem);
155
- // Completely delete items that can't be divided.
156
- if (!targetElem.withRegionErased) {
157
- continue;
158
- }
159
- // Completely delete items that are completely or almost completely
160
- // contained within the eraser.
161
- const grownRect = eraserRect.grownBy(eraserRect.maxDimension / 3);
162
- if (grownRect.containsRect(targetElem.getExactBBox())) {
163
- continue;
164
- }
165
- // Join the current and previous rectangles so that points between events are also
166
- // erased.
167
- const erasePath = Path.fromConvexHullOf([
168
- ...eraserRect.corners, ...this.getEraserRect(this.lastPoint ?? currentPoint).corners
169
- ].map(p => this.editor.viewport.roundPoint(p)));
170
- toAdd.push(...targetElem.withRegionErased(erasePath, this.editor.viewport));
171
- }
172
- const eraseCommand = new Erase(toErase);
173
- const newAddCommands = toAdd.map(elem => EditorImage.addElement(elem));
174
- eraseCommand.apply(this.editor);
175
- newAddCommands.forEach(command => command.apply(this.editor));
176
- const finalToErase = [];
177
- for (const item of toErase) {
178
- if (this.toAdd.has(item)) {
179
- this.toAdd.delete(item);
180
- }
181
- else {
182
- finalToErase.push(item);
183
- }
184
- }
185
- this.toRemove.push(...finalToErase);
186
- for (const item of toAdd) {
187
- this.toAdd.add(item);
188
- }
189
- this.eraseCommands.push(new Erase(finalToErase));
190
- this.addCommands.push(...newAddCommands);
191
- }
192
- this.drawPreviewAt(currentPoint);
193
- this.lastPoint = currentPoint;
194
- }
195
- onPointerDown(event) {
196
- if (event.allPointers.length === 1 || event.current.device === PointerDevice.Eraser) {
197
- this.lastPoint = event.current.canvasPos;
198
- this.toRemove = [];
199
- this.toAdd.clear();
200
- this.isFirstEraseEvt = true;
201
- this.drawPreviewAt(event.current.canvasPos);
202
- return true;
203
- }
204
- return false;
205
- }
206
- onPointerMove(event) {
207
- const currentPoint = event.current.canvasPos;
208
- this.eraseTo(currentPoint);
209
- }
210
- onPointerUp(event) {
211
- this.eraseTo(event.current.canvasPos);
212
- const commands = [];
213
- if (this.addCommands.length > 0) {
214
- this.addCommands.forEach(cmd => cmd.unapply(this.editor));
215
- // Remove items from toAdd that are also present in toRemove -- adding, then
216
- // removing these does nothing, and can break undo/redo.
217
- for (const item of this.toAdd) {
218
- if (this.toRemove.includes(item)) {
219
- this.toAdd.delete(item);
220
- this.toRemove = this.toRemove.filter(other => other !== item);
221
- }
222
- }
223
- for (const item of this.toRemove) {
224
- if (this.toAdd.has(item)) {
225
- this.toAdd.delete(item);
226
- this.toRemove = this.toRemove.filter(other => other !== item);
227
- }
228
- }
229
- commands.push(...[...this.toAdd].map(a => EditorImage.addElement(a)));
230
- this.addCommands = [];
231
- }
232
- if (this.eraseCommands.length > 0) {
233
- // Undo commands for each individual component and unite into a single command.
234
- this.eraseCommands.forEach(cmd => cmd.unapply(this.editor));
235
- this.eraseCommands = [];
236
- const command = new Erase(this.toRemove);
237
- commands.push(command);
238
- }
239
- if (commands.length === 1) {
240
- this.editor.dispatch(commands[0]); // dispatch: Makes undo-able.
241
- }
242
- else {
243
- this.editor.dispatch(uniteCommands(commands));
244
- }
245
- this.clearPreview();
246
- }
247
- onGestureCancel(_event) {
248
- this.addCommands.forEach(cmd => cmd.unapply(this.editor));
249
- this.eraseCommands.forEach(cmd => cmd.unapply(this.editor));
250
- this.eraseCommands = [];
251
- this.addCommands = [];
252
- this.clearPreview();
253
- }
254
- onKeyPress(event) {
255
- const shortcuts = this.editor.shortcuts;
256
- let newThickness;
257
- if (shortcuts.matchesShortcut(decreaseSizeKeyboardShortcutId, event)) {
258
- newThickness = this.getThickness() * 2 / 3;
259
- }
260
- else if (shortcuts.matchesShortcut(increaseSizeKeyboardShortcutId, event)) {
261
- newThickness = this.getThickness() * 3 / 2;
262
- }
263
- if (newThickness !== undefined) {
264
- newThickness = Math.min(Math.max(1, newThickness), 200);
265
- this.setThickness(newThickness);
266
- return true;
267
- }
268
- return false;
269
- }
270
- /** Returns the side-length of the tip of this eraser. */
271
- getThickness() {
272
- return this.thickness;
273
- }
274
- /** Sets the side-length of this' tip. */
275
- setThickness(thickness) {
276
- this.thicknessValue.set(thickness);
277
- }
278
- /**
279
- * Returns a {@link MutableReactiveValue} that can be used to watch
280
- * this tool's thickness.
281
- */
282
- getThicknessValue() {
283
- return this.thicknessValue;
284
- }
285
- getModeValue() {
286
- return this.modeValue;
287
- }
288
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,21 +0,0 @@
1
- import Editor from '../Editor';
2
- import { KeyPressEvent } from '../inputEvents';
3
- import BaseTool from './BaseTool';
4
- export default class FindTool extends BaseTool {
5
- private editor;
6
- private overlay;
7
- private searchInput;
8
- private currentMatchIdx;
9
- constructor(editor: Editor);
10
- canReceiveInputInReadOnlyEditor(): boolean;
11
- private getMatches;
12
- private focusCurrentMatch;
13
- private toNextMatch;
14
- private toPrevMatch;
15
- private fillOverlay;
16
- private isVisible;
17
- private setVisible;
18
- private toggleVisible;
19
- onKeyPress(event: KeyPressEvent): boolean;
20
- setEnabled(enabled: boolean): void;
21
- }
@@ -1,131 +0,0 @@
1
- // Displays a find dialog that allows the user to search for and focus text.
2
- //
3
- // @packageDocumentation
4
- import TextComponent from '../components/TextComponent.mjs';
5
- import ImageComponent from '../components/ImageComponent.mjs';
6
- import BaseTool from './BaseTool.mjs';
7
- import { toggleFindVisibleShortcutId } from './keybindings.mjs';
8
- const cssPrefix = 'find-tool';
9
- export default class FindTool extends BaseTool {
10
- constructor(editor) {
11
- super(editor.notifier, editor.localization.findLabel);
12
- this.editor = editor;
13
- this.currentMatchIdx = 0;
14
- this.overlay = document.createElement('div');
15
- this.fillOverlay();
16
- editor.createHTMLOverlay(this.overlay);
17
- this.overlay.style.display = 'none';
18
- this.overlay.classList.add(`${cssPrefix}-overlay`);
19
- }
20
- canReceiveInputInReadOnlyEditor() {
21
- return true;
22
- }
23
- getMatches(searchFor) {
24
- const lowerSearchFor = searchFor.toLocaleLowerCase();
25
- const matchingComponents = this.editor.image.getAllElements().filter(component => {
26
- let text = '';
27
- if (component instanceof TextComponent) {
28
- text = component.getText();
29
- }
30
- else if (component instanceof ImageComponent) {
31
- text = component.getAltText() ?? '';
32
- }
33
- else {
34
- return false;
35
- }
36
- const hasLowercaseMatch = text.toLocaleLowerCase().indexOf(lowerSearchFor) !== -1;
37
- const hasSameCaseMatch = text.indexOf(searchFor) !== -1;
38
- return hasLowercaseMatch || hasSameCaseMatch;
39
- });
40
- return matchingComponents.map(match => match.getBBox());
41
- }
42
- focusCurrentMatch() {
43
- const matches = this.getMatches(this.searchInput.value);
44
- let matchIdx = this.currentMatchIdx % matches.length;
45
- if (matchIdx < 0) {
46
- matchIdx = matches.length + matchIdx;
47
- }
48
- if (matchIdx < matches.length) {
49
- const undoable = false;
50
- void this.editor.dispatch(this.editor.viewport.zoomTo(matches[matchIdx], true, true), undoable);
51
- this.editor.announceForAccessibility(this.editor.localization.focusedFoundText(matchIdx + 1, matches.length));
52
- }
53
- }
54
- toNextMatch() {
55
- this.currentMatchIdx++;
56
- this.focusCurrentMatch();
57
- }
58
- toPrevMatch() {
59
- this.currentMatchIdx--;
60
- this.focusCurrentMatch();
61
- }
62
- fillOverlay() {
63
- const label = document.createElement('label');
64
- this.searchInput = document.createElement('input');
65
- const nextBtn = document.createElement('button');
66
- const closeBtn = document.createElement('button');
67
- // Math.random() ensures that the ID is unique (to allow us to refer to it
68
- // with an htmlFor).
69
- this.searchInput.setAttribute('id', `${cssPrefix}-searchInput-${Math.random()}`);
70
- label.htmlFor = this.searchInput.getAttribute('id');
71
- label.innerText = this.editor.localization.findLabel;
72
- nextBtn.innerText = this.editor.localization.toNextMatch;
73
- closeBtn.innerText = this.editor.localization.closeDialog;
74
- this.searchInput.onkeydown = (ev) => {
75
- if (ev.key === 'Enter') {
76
- if (ev.shiftKey) {
77
- this.toPrevMatch();
78
- }
79
- else {
80
- this.toNextMatch();
81
- }
82
- }
83
- else if (ev.key === 'Escape') {
84
- this.setVisible(false);
85
- }
86
- else if (this.editor.shortcuts.matchesShortcut(toggleFindVisibleShortcutId, ev)) {
87
- ev.preventDefault();
88
- this.toggleVisible();
89
- }
90
- };
91
- nextBtn.onclick = () => {
92
- this.toNextMatch();
93
- };
94
- closeBtn.onclick = () => {
95
- this.setVisible(false);
96
- };
97
- this.overlay.replaceChildren(label, this.searchInput, nextBtn, closeBtn);
98
- }
99
- isVisible() {
100
- return this.overlay.style.display !== 'none';
101
- }
102
- setVisible(visible) {
103
- if (visible !== this.isVisible()) {
104
- this.overlay.style.display = visible ? 'block' : 'none';
105
- if (visible) {
106
- this.searchInput.focus();
107
- this.editor.announceForAccessibility(this.editor.localization.findDialogShown);
108
- }
109
- else {
110
- this.editor.focus();
111
- this.editor.announceForAccessibility(this.editor.localization.findDialogHidden);
112
- }
113
- }
114
- }
115
- toggleVisible() {
116
- this.setVisible(!this.isVisible());
117
- }
118
- onKeyPress(event) {
119
- if (this.editor.shortcuts.matchesShortcut(toggleFindVisibleShortcutId, event)) {
120
- this.toggleVisible();
121
- return true;
122
- }
123
- return false;
124
- }
125
- setEnabled(enabled) {
126
- super.setEnabled(enabled);
127
- if (this.isEnabled()) {
128
- this.setVisible(false);
129
- }
130
- }
131
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1,12 +0,0 @@
1
- import { InputEvt } from '../../inputEvents';
2
- import InputMapper from './InputMapper';
3
- /**
4
- * An `InputMapper` that applies a function to all events it receives.
5
- *
6
- * Useful for automated testing.
7
- */
8
- export default class FunctionMapper extends InputMapper {
9
- private fn;
10
- constructor(fn: (event: InputEvt) => InputEvt);
11
- onEvent(event: InputEvt): boolean;
12
- }