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.
- package/LICENSE +1 -1
- package/dist/Editor.css +136 -26
- package/dist/bundle.js +2 -2
- package/dist/bundledStyles.js +1 -1
- package/dist/cjs/Editor.d.ts +27 -6
- package/dist/cjs/Editor.js +30 -8
- package/dist/cjs/SVGLoader/SVGLoader.js +2 -2
- package/dist/cjs/Viewport.d.ts +2 -2
- package/dist/cjs/commands/Command.d.ts +5 -0
- package/dist/cjs/commands/Command.js +5 -0
- package/dist/cjs/commands/SerializableCommand.d.ts +7 -0
- package/dist/cjs/commands/SerializableCommand.js +9 -0
- package/dist/cjs/dialogs/makeAboutDialog.d.ts +1 -1
- package/dist/cjs/dialogs/makeAboutDialog.js +10 -25
- package/dist/cjs/dialogs/makeMessageDialog.d.ts +11 -0
- package/dist/cjs/dialogs/makeMessageDialog.js +56 -0
- package/dist/cjs/image/EditorImage.d.ts +15 -1
- package/dist/cjs/image/EditorImage.js +15 -5
- package/dist/cjs/inputEvents.d.ts +10 -2
- package/dist/cjs/inputEvents.js +1 -0
- package/dist/cjs/localizations/es.js +3 -0
- package/dist/cjs/rendering/Display.d.ts +1 -0
- package/dist/cjs/rendering/Display.js +1 -0
- package/dist/cjs/rendering/TextRenderingStyle.d.ts +7 -6
- package/dist/cjs/rendering/TextRenderingStyle.js +1 -0
- package/dist/cjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
- package/dist/cjs/rendering/renderers/CanvasRenderer.js +15 -2
- package/dist/cjs/rendering/renderers/DummyRenderer.d.ts +1 -1
- package/dist/cjs/testing/firstElementAncestorOfNode.d.ts +1 -1
- package/dist/cjs/testing/firstElementAncestorOfNode.js +1 -1
- package/dist/cjs/testing/sendPenEvent.d.ts +2 -2
- package/dist/cjs/testing/sendTouchEvent.d.ts +2 -2
- package/dist/cjs/toolbar/AbstractToolbar.d.ts +6 -1
- package/dist/cjs/toolbar/AbstractToolbar.js +6 -1
- package/dist/cjs/toolbar/IconProvider.d.ts +1 -1
- package/dist/cjs/toolbar/IconProvider.js +6 -1
- package/dist/cjs/toolbar/widgets/BaseWidget.d.ts +8 -0
- package/dist/cjs/toolbar/widgets/BaseWidget.js +8 -0
- package/dist/cjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/cjs/toolbar/widgets/HandToolWidget.js +1 -0
- package/dist/cjs/toolbar/widgets/InsertImageWidget/ImageWrapper.d.ts +1 -1
- package/dist/cjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
- package/dist/cjs/toolbar/widgets/PenToolWidget.js +5 -0
- package/dist/cjs/types.d.ts +5 -0
- package/dist/cjs/types.js +1 -0
- package/dist/cjs/util/ClipboardHandler.d.ts +9 -1
- package/dist/cjs/util/ClipboardHandler.js +82 -24
- package/dist/cjs/version.js +1 -1
- package/dist/mjs/Editor.d.ts +27 -6
- package/dist/mjs/Editor.mjs +31 -9
- package/dist/mjs/SVGLoader/SVGLoader.mjs +2 -2
- package/dist/mjs/Viewport.d.ts +2 -2
- package/dist/mjs/commands/Command.d.ts +5 -0
- package/dist/mjs/commands/Command.mjs +5 -0
- package/dist/mjs/commands/SerializableCommand.d.ts +7 -0
- package/dist/mjs/commands/SerializableCommand.mjs +9 -0
- package/dist/mjs/dialogs/makeAboutDialog.d.ts +1 -1
- package/dist/mjs/dialogs/makeAboutDialog.mjs +7 -25
- package/dist/mjs/dialogs/makeMessageDialog.d.ts +11 -0
- package/dist/mjs/dialogs/makeMessageDialog.mjs +51 -0
- package/dist/mjs/image/EditorImage.d.ts +15 -1
- package/dist/mjs/image/EditorImage.mjs +15 -5
- package/dist/mjs/inputEvents.d.ts +10 -2
- package/dist/mjs/inputEvents.mjs +1 -0
- package/dist/mjs/localizations/es.mjs +3 -0
- package/dist/mjs/rendering/Display.d.ts +1 -0
- package/dist/mjs/rendering/Display.mjs +1 -0
- package/dist/mjs/rendering/TextRenderingStyle.d.ts +7 -6
- package/dist/mjs/rendering/TextRenderingStyle.mjs +1 -0
- package/dist/mjs/rendering/renderers/CanvasRenderer.d.ts +12 -3
- package/dist/mjs/rendering/renderers/CanvasRenderer.mjs +15 -2
- package/dist/mjs/rendering/renderers/DummyRenderer.d.ts +1 -1
- package/dist/mjs/testing/firstElementAncestorOfNode.d.ts +1 -1
- package/dist/mjs/testing/firstElementAncestorOfNode.mjs +1 -1
- package/dist/mjs/testing/sendPenEvent.d.ts +2 -2
- package/dist/mjs/testing/sendTouchEvent.d.ts +2 -2
- package/dist/mjs/toolbar/AbstractToolbar.d.ts +6 -1
- package/dist/mjs/toolbar/AbstractToolbar.mjs +6 -1
- package/dist/mjs/toolbar/IconProvider.d.ts +1 -1
- package/dist/mjs/toolbar/IconProvider.mjs +6 -1
- package/dist/mjs/toolbar/widgets/BaseWidget.d.ts +8 -0
- package/dist/mjs/toolbar/widgets/BaseWidget.mjs +8 -0
- package/dist/mjs/toolbar/widgets/HandToolWidget.d.ts +1 -0
- package/dist/mjs/toolbar/widgets/HandToolWidget.mjs +1 -0
- package/dist/mjs/toolbar/widgets/InsertImageWidget/ImageWrapper.d.ts +1 -1
- package/dist/mjs/toolbar/widgets/PenToolWidget.d.ts +6 -0
- package/dist/mjs/toolbar/widgets/PenToolWidget.mjs +5 -0
- package/dist/mjs/types.d.ts +5 -0
- package/dist/mjs/types.mjs +1 -0
- package/dist/mjs/util/ClipboardHandler.d.ts +9 -1
- package/dist/mjs/util/ClipboardHandler.mjs +82 -24
- package/dist/mjs/version.mjs +1 -1
- package/package.json +8 -9
- package/src/dialogs/dialogs.scss +9 -21
- package/src/dialogs/makeAboutDialog.scss +13 -33
- package/src/dialogs/makeMessageDialog.scss +46 -0
- package/dist/cjs/tools/BaseTool.d.ts +0 -60
- package/dist/cjs/tools/BaseTool.js +0 -174
- package/dist/cjs/tools/Eraser.d.ts +0 -56
- package/dist/cjs/tools/Eraser.js +0 -295
- package/dist/cjs/tools/Eraser.test.d.ts +0 -1
- package/dist/cjs/tools/FindTool.d.ts +0 -21
- package/dist/cjs/tools/FindTool.js +0 -137
- package/dist/cjs/tools/FindTool.test.d.ts +0 -1
- package/dist/cjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
- package/dist/cjs/tools/InputFilter/FunctionMapper.js +0 -21
- package/dist/cjs/tools/InputFilter/InputMapper.d.ts +0 -23
- package/dist/cjs/tools/InputFilter/InputMapper.js +0 -38
- package/dist/cjs/tools/InputFilter/InputPipeline.d.ts +0 -15
- package/dist/cjs/tools/InputFilter/InputPipeline.js +0 -54
- package/dist/cjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
- package/dist/cjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
- package/dist/cjs/tools/InputFilter/InputStabilizer.js +0 -181
- package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
- package/dist/cjs/tools/InputFilter/StrokeKeyboardControl.js +0 -84
- package/dist/cjs/tools/PanZoom.d.ts +0 -119
- package/dist/cjs/tools/PanZoom.js +0 -508
- package/dist/cjs/tools/PanZoom.test.d.ts +0 -1
- package/dist/cjs/tools/PasteHandler.d.ts +0 -23
- package/dist/cjs/tools/PasteHandler.js +0 -109
- package/dist/cjs/tools/Pen.d.ts +0 -53
- package/dist/cjs/tools/Pen.js +0 -318
- package/dist/cjs/tools/Pen.test.d.ts +0 -1
- package/dist/cjs/tools/PipetteTool.d.ts +0 -28
- package/dist/cjs/tools/PipetteTool.js +0 -69
- package/dist/cjs/tools/ScrollbarTool.d.ts +0 -18
- package/dist/cjs/tools/ScrollbarTool.js +0 -85
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
- package/dist/cjs/tools/SelectionTool/SelectAllShortcutHandler.js +0 -32
- package/dist/cjs/tools/SelectionTool/Selection.d.ts +0 -71
- package/dist/cjs/tools/SelectionTool/Selection.js +0 -620
- package/dist/cjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
- package/dist/cjs/tools/SelectionTool/SelectionHandle.js +0 -141
- package/dist/cjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
- package/dist/cjs/tools/SelectionTool/SelectionTool.js +0 -494
- package/dist/cjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
- package/dist/cjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
- package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
- package/dist/cjs/tools/SelectionTool/ToPointerAutoscroller.js +0 -83
- package/dist/cjs/tools/SelectionTool/TransformMode.d.ts +0 -42
- package/dist/cjs/tools/SelectionTool/TransformMode.js +0 -155
- package/dist/cjs/tools/SelectionTool/types.d.ts +0 -28
- package/dist/cjs/tools/SelectionTool/types.js +0 -14
- package/dist/cjs/tools/SoundUITool.d.ts +0 -26
- package/dist/cjs/tools/SoundUITool.js +0 -171
- package/dist/cjs/tools/TextTool.d.ts +0 -36
- package/dist/cjs/tools/TextTool.js +0 -285
- package/dist/cjs/tools/TextTool.test.d.ts +0 -1
- package/dist/cjs/tools/ToolController.d.ts +0 -73
- package/dist/cjs/tools/ToolController.js +0 -304
- package/dist/cjs/tools/ToolController.test.d.ts +0 -1
- package/dist/cjs/tools/ToolEnabledGroup.d.ts +0 -6
- package/dist/cjs/tools/ToolEnabledGroup.js +0 -13
- package/dist/cjs/tools/ToolSwitcherShortcut.d.ts +0 -16
- package/dist/cjs/tools/ToolSwitcherShortcut.js +0 -40
- package/dist/cjs/tools/ToolbarShortcutHandler.d.ts +0 -12
- package/dist/cjs/tools/ToolbarShortcutHandler.js +0 -34
- package/dist/cjs/tools/UndoRedoShortcut.d.ts +0 -8
- package/dist/cjs/tools/UndoRedoShortcut.js +0 -27
- package/dist/cjs/tools/UndoRedoShortcut.test.d.ts +0 -1
- package/dist/cjs/tools/keybindings.d.ts +0 -18
- package/dist/cjs/tools/keybindings.js +0 -49
- package/dist/cjs/tools/lib.d.ts +0 -14
- package/dist/cjs/tools/lib.js +0 -36
- package/dist/cjs/tools/localization.d.ts +0 -34
- package/dist/cjs/tools/localization.js +0 -36
- package/dist/cjs/tools/util/StationaryPenDetector.d.ts +0 -22
- package/dist/cjs/tools/util/StationaryPenDetector.js +0 -95
- package/dist/mjs/tools/BaseTool.d.ts +0 -60
- package/dist/mjs/tools/BaseTool.mjs +0 -172
- package/dist/mjs/tools/Eraser.d.ts +0 -56
- package/dist/mjs/tools/Eraser.mjs +0 -288
- package/dist/mjs/tools/Eraser.test.d.ts +0 -1
- package/dist/mjs/tools/FindTool.d.ts +0 -21
- package/dist/mjs/tools/FindTool.mjs +0 -131
- package/dist/mjs/tools/FindTool.test.d.ts +0 -1
- package/dist/mjs/tools/InputFilter/FunctionMapper.d.ts +0 -12
- package/dist/mjs/tools/InputFilter/FunctionMapper.mjs +0 -15
- package/dist/mjs/tools/InputFilter/InputMapper.d.ts +0 -23
- package/dist/mjs/tools/InputFilter/InputMapper.mjs +0 -36
- package/dist/mjs/tools/InputFilter/InputPipeline.d.ts +0 -15
- package/dist/mjs/tools/InputFilter/InputPipeline.mjs +0 -49
- package/dist/mjs/tools/InputFilter/InputPipeline.test.d.ts +0 -1
- package/dist/mjs/tools/InputFilter/InputStabilizer.d.ts +0 -29
- package/dist/mjs/tools/InputFilter/InputStabilizer.mjs +0 -175
- package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.d.ts +0 -21
- package/dist/mjs/tools/InputFilter/StrokeKeyboardControl.mjs +0 -78
- package/dist/mjs/tools/PanZoom.d.ts +0 -119
- package/dist/mjs/tools/PanZoom.mjs +0 -501
- package/dist/mjs/tools/PanZoom.test.d.ts +0 -1
- package/dist/mjs/tools/PasteHandler.d.ts +0 -23
- package/dist/mjs/tools/PasteHandler.mjs +0 -103
- package/dist/mjs/tools/Pen.d.ts +0 -53
- package/dist/mjs/tools/Pen.mjs +0 -312
- package/dist/mjs/tools/Pen.test.d.ts +0 -1
- package/dist/mjs/tools/PipetteTool.d.ts +0 -28
- package/dist/mjs/tools/PipetteTool.mjs +0 -63
- package/dist/mjs/tools/ScrollbarTool.d.ts +0 -18
- package/dist/mjs/tools/ScrollbarTool.mjs +0 -79
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.d.ts +0 -9
- package/dist/mjs/tools/SelectionTool/SelectAllShortcutHandler.mjs +0 -26
- package/dist/mjs/tools/SelectionTool/Selection.d.ts +0 -71
- package/dist/mjs/tools/SelectionTool/Selection.mjs +0 -592
- package/dist/mjs/tools/SelectionTool/SelectionHandle.d.ts +0 -62
- package/dist/mjs/tools/SelectionTool/SelectionHandle.mjs +0 -137
- package/dist/mjs/tools/SelectionTool/SelectionTool.d.ts +0 -40
- package/dist/mjs/tools/SelectionTool/SelectionTool.mjs +0 -488
- package/dist/mjs/tools/SelectionTool/SelectionTool.selecting.test.d.ts +0 -1
- package/dist/mjs/tools/SelectionTool/SelectionTool.test.d.ts +0 -1
- package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.d.ts +0 -23
- package/dist/mjs/tools/SelectionTool/ToPointerAutoscroller.mjs +0 -77
- package/dist/mjs/tools/SelectionTool/TransformMode.d.ts +0 -42
- package/dist/mjs/tools/SelectionTool/TransformMode.mjs +0 -146
- package/dist/mjs/tools/SelectionTool/types.d.ts +0 -28
- package/dist/mjs/tools/SelectionTool/types.mjs +0 -11
- package/dist/mjs/tools/SoundUITool.d.ts +0 -26
- package/dist/mjs/tools/SoundUITool.mjs +0 -165
- package/dist/mjs/tools/TextTool.d.ts +0 -36
- package/dist/mjs/tools/TextTool.mjs +0 -279
- package/dist/mjs/tools/TextTool.test.d.ts +0 -1
- package/dist/mjs/tools/ToolController.d.ts +0 -73
- package/dist/mjs/tools/ToolController.mjs +0 -275
- package/dist/mjs/tools/ToolController.test.d.ts +0 -1
- package/dist/mjs/tools/ToolEnabledGroup.d.ts +0 -6
- package/dist/mjs/tools/ToolEnabledGroup.mjs +0 -10
- package/dist/mjs/tools/ToolSwitcherShortcut.d.ts +0 -16
- package/dist/mjs/tools/ToolSwitcherShortcut.mjs +0 -34
- package/dist/mjs/tools/ToolbarShortcutHandler.d.ts +0 -12
- package/dist/mjs/tools/ToolbarShortcutHandler.mjs +0 -28
- package/dist/mjs/tools/UndoRedoShortcut.d.ts +0 -8
- package/dist/mjs/tools/UndoRedoShortcut.mjs +0 -21
- package/dist/mjs/tools/UndoRedoShortcut.test.d.ts +0 -1
- package/dist/mjs/tools/keybindings.d.ts +0 -18
- package/dist/mjs/tools/keybindings.mjs +0 -43
- package/dist/mjs/tools/lib.d.ts +0 -14
- package/dist/mjs/tools/lib.mjs +0 -14
- package/dist/mjs/tools/localization.d.ts +0 -34
- package/dist/mjs/tools/localization.mjs +0 -33
- package/dist/mjs/tools/util/StationaryPenDetector.d.ts +0 -22
- package/dist/mjs/tools/util/StationaryPenDetector.mjs +0 -92
- package/src/tools/FindTool.css +0 -7
- package/src/tools/ScrollbarTool.scss +0 -57
- package/src/tools/SelectionTool/SelectionTool.scss +0 -137
- package/src/tools/SoundUITool.scss +0 -22
- package/src/tools/tools.scss +0 -5
@@ -25,8 +25,9 @@ mime.endsWith('+xml') || mime.startsWith('text/');
|
|
25
25
|
* js-draw clipboard events.
|
26
26
|
*/
|
27
27
|
class ClipboardHandler {
|
28
|
-
constructor(editor) {
|
28
|
+
constructor(editor, callbacks) {
|
29
29
|
this.editor = editor;
|
30
|
+
this.callbacks = callbacks;
|
30
31
|
_ClipboardHandler_preferClipboardEvents.set(this, false);
|
31
32
|
}
|
32
33
|
/**
|
@@ -37,7 +38,27 @@ class ClipboardHandler {
|
|
37
38
|
* `navigator.clipboard` will be used instead.
|
38
39
|
* @returns true if the paste event was handled by the editor.
|
39
40
|
*/
|
40
|
-
|
41
|
+
paste(event) {
|
42
|
+
const onError = (error) => {
|
43
|
+
if (this.callbacks?.onPasteError) {
|
44
|
+
this.callbacks.onPasteError(error);
|
45
|
+
return Promise.resolve(false);
|
46
|
+
}
|
47
|
+
else {
|
48
|
+
throw error;
|
49
|
+
}
|
50
|
+
};
|
51
|
+
try {
|
52
|
+
// Use .catch rather than `async` to prevent future modifications from
|
53
|
+
// moving clipboard handling logic out of user event handlers.
|
54
|
+
// In the past, `await`s have caused permissions issues in some browsers.
|
55
|
+
return this.pasteInternal(event).catch(onError);
|
56
|
+
}
|
57
|
+
catch (error) {
|
58
|
+
return onError(error);
|
59
|
+
}
|
60
|
+
}
|
61
|
+
async pasteInternal(event) {
|
41
62
|
const editor = this.editor;
|
42
63
|
const clipboardData = event?.dataTransfer ?? event?.clipboardData ?? null;
|
43
64
|
const hasEvent = !!clipboardData;
|
@@ -136,45 +157,82 @@ class ClipboardHandler {
|
|
136
157
|
* images.
|
137
158
|
*/
|
138
159
|
copy(event) {
|
139
|
-
const
|
160
|
+
const onError = (error) => {
|
161
|
+
if (this.callbacks?.onCopyError) {
|
162
|
+
this.callbacks.onCopyError(error);
|
163
|
+
return Promise.resolve();
|
164
|
+
}
|
165
|
+
else {
|
166
|
+
throw error;
|
167
|
+
}
|
168
|
+
};
|
169
|
+
try {
|
170
|
+
// As above, use `.catch` to be certain that certain copyInternal
|
171
|
+
// is run now, before returning.
|
172
|
+
return this.copyInternal(event).catch(onError);
|
173
|
+
}
|
174
|
+
catch (error) {
|
175
|
+
return onError(error);
|
176
|
+
}
|
177
|
+
}
|
178
|
+
copyInternal(event) {
|
179
|
+
const mimeToData = new Map();
|
140
180
|
if (this.editor.toolController.dispatchInputEvent({
|
141
181
|
kind: inputEvents_1.InputEvtType.CopyEvent,
|
142
182
|
setData: (mime, data) => {
|
143
|
-
mimeToData
|
183
|
+
mimeToData.set(mime, data);
|
144
184
|
},
|
145
185
|
})) {
|
146
186
|
event?.preventDefault();
|
147
187
|
}
|
148
|
-
const mimeTypes =
|
188
|
+
const mimeTypes = [...mimeToData.keys()];
|
149
189
|
const hasNonTextMimeTypes = mimeTypes.some(mime => !isTextMimeType(mime));
|
150
|
-
const copyToEvent = () => {
|
190
|
+
const copyToEvent = (reason) => {
|
151
191
|
if (!event) {
|
152
|
-
throw new Error(
|
192
|
+
throw new Error(`Unable to copy -- no event provided${reason ? `. Original error: ${reason}` : ''}`);
|
153
193
|
}
|
154
|
-
for (const key
|
155
|
-
const value = mimeToData[key];
|
194
|
+
for (const [key, value] of mimeToData.entries()) {
|
156
195
|
if (typeof value === 'string') {
|
157
196
|
event.clipboardData?.setData(key, value);
|
158
197
|
}
|
159
198
|
}
|
160
199
|
};
|
161
200
|
const copyToClipboardApi = () => {
|
162
|
-
const
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
201
|
+
const mapInternalDataToBrowserData = (originalMimeToData) => {
|
202
|
+
const mappedMimeToData = Object.create(null);
|
203
|
+
for (const [key, data] of originalMimeToData.entries()) {
|
204
|
+
if (typeof data === 'string') {
|
205
|
+
const loadedData = new Blob([new TextEncoder().encode(data)], { type: key });
|
206
|
+
mappedMimeToData[key] = loadedData;
|
207
|
+
}
|
208
|
+
else {
|
209
|
+
mappedMimeToData[key] = data;
|
210
|
+
}
|
211
|
+
// Different platforms have varying support for different clipboard MIME types:
|
212
|
+
// - As of September 2024, image/svg+xml is unsupported on iOS
|
213
|
+
// - text/html is unsupported on Chrome/Android (and perhaps Chrome on other platforms).
|
214
|
+
// - See https://issues.chromium.org/issues/40851502
|
215
|
+
if (key === 'image/svg+xml') {
|
216
|
+
mappedMimeToData['text/html'] ??= mappedMimeToData[key];
|
217
|
+
}
|
172
218
|
}
|
173
|
-
|
174
|
-
|
219
|
+
return mappedMimeToData;
|
220
|
+
};
|
221
|
+
const removeUnsupportedMime = (originalMimeToData) => {
|
222
|
+
const filteredMimeToData = Object.create(null);
|
223
|
+
for (const [key, data] of Object.entries(originalMimeToData)) {
|
224
|
+
// Browser support for ClipboardItem.supports is limited as of mid 2024. However, some browsers
|
225
|
+
// that do support `.supports` throw an exception when attempting to copy an unsupported MIME type
|
226
|
+
// (e.g. Firefox).
|
227
|
+
const unsupported = 'supports' in ClipboardItem && typeof ClipboardItem.supports === 'function' && !ClipboardItem.supports(key);
|
228
|
+
if (!unsupported) {
|
229
|
+
filteredMimeToData[key] = data;
|
230
|
+
}
|
175
231
|
}
|
176
|
-
|
177
|
-
|
232
|
+
return filteredMimeToData;
|
233
|
+
};
|
234
|
+
const browserMimeToData = removeUnsupportedMime(mapInternalDataToBrowserData(mimeToData));
|
235
|
+
return navigator.clipboard.write([new ClipboardItem(browserMimeToData)]);
|
178
236
|
};
|
179
237
|
const supportsClipboardApi = (typeof ClipboardItem !== 'undefined'
|
180
238
|
&& typeof navigator?.clipboard?.write !== 'undefined');
|
@@ -183,7 +241,7 @@ class ClipboardHandler {
|
|
183
241
|
const fallBackToCopyEvent = (reason) => {
|
184
242
|
console.warn('Unable to copy to the clipboard API. Future calls to .copy will use ClipboardEvents if possible.', reason);
|
185
243
|
__classPrivateFieldSet(this, _ClipboardHandler_preferClipboardEvents, true, "f");
|
186
|
-
copyToEvent();
|
244
|
+
copyToEvent(reason);
|
187
245
|
};
|
188
246
|
try {
|
189
247
|
clipboardApiPromise = copyToClipboardApi();
|
package/dist/cjs/version.js
CHANGED
package/dist/mjs/Editor.d.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import EditorImage from './image/EditorImage';
|
2
2
|
import ToolController from './tools/ToolController';
|
3
3
|
import { EditorNotifier, ImageLoader } from './types';
|
4
|
-
import { HTMLPointerEventFilter, InputEvtType } from './inputEvents';
|
4
|
+
import { HTMLPointerEventFilter, InputEvtType, PointerEvtType } from './inputEvents';
|
5
5
|
import Command from './commands/Command';
|
6
6
|
import UndoRedoHistory from './UndoRedoHistory';
|
7
7
|
import Viewport from './Viewport';
|
@@ -68,8 +68,8 @@ export interface EditorSettings {
|
|
68
68
|
*/
|
69
69
|
notices: AboutDialogEntry[];
|
70
70
|
/**
|
71
|
-
* Information about the app/website js-draw is running within
|
72
|
-
*
|
71
|
+
* Information about the app/website js-draw is running within. This is shown
|
72
|
+
* at the beginning of the about dialog.
|
73
73
|
*/
|
74
74
|
appInfo: {
|
75
75
|
name: string;
|
@@ -291,8 +291,18 @@ export declare class Editor {
|
|
291
291
|
* ```
|
292
292
|
*/
|
293
293
|
getRootElement(): HTMLElement;
|
294
|
-
/**
|
294
|
+
/**
|
295
|
+
* @returns the bounding box of the main rendering region of the editor in the HTML viewport.
|
296
|
+
*
|
297
|
+
* @internal
|
298
|
+
*/
|
299
|
+
getOutputBBoxInDOM(): Rect2;
|
300
|
+
/**
|
301
|
+
* Shows a "Loading..." message.
|
302
|
+
* @param fractionLoaded - should be a number from 0 to 1, where 1 represents completely loaded.
|
303
|
+
*/
|
295
304
|
showLoadingWarning(fractionLoaded: number): void;
|
305
|
+
/** @see {@link showLoadingWarning} */
|
296
306
|
hideLoadingWarning(): void;
|
297
307
|
private previousAccessibilityAnnouncement;
|
298
308
|
/**
|
@@ -389,7 +399,12 @@ export declare class Editor {
|
|
389
399
|
setReadOnly(readOnly: boolean): void;
|
390
400
|
isReadOnlyReactiveValue(): ReactiveValue<boolean>;
|
391
401
|
isReadOnly(): MutableReactiveValue<boolean>;
|
392
|
-
/**
|
402
|
+
/**
|
403
|
+
* `apply` a command. `command` will be announced for accessibility.
|
404
|
+
*
|
405
|
+
* **Example**:
|
406
|
+
* [[include:doc-pages/inline-examples/adding-a-stroke.md]]
|
407
|
+
*/
|
393
408
|
dispatch(command: Command, addToHistory?: boolean): void | Promise<void>;
|
394
409
|
/**
|
395
410
|
* Dispatches a command without announcing it. By default, does not add to history.
|
@@ -414,7 +429,13 @@ export declare class Editor {
|
|
414
429
|
* has been applied.
|
415
430
|
*/
|
416
431
|
asyncApplyOrUnapplyCommands(commands: Command[], apply: boolean, updateChunkSize: number): Promise<void>;
|
432
|
+
/** @see {@link asyncApplyOrUnapplyCommands } */
|
417
433
|
asyncApplyCommands(commands: Command[], chunkSize: number): Promise<void>;
|
434
|
+
/**
|
435
|
+
* @see {@link asyncApplyOrUnapplyCommands}
|
436
|
+
*
|
437
|
+
* If `unapplyInReverseOrder`, commands are reversed before unapplying.
|
438
|
+
*/
|
418
439
|
asyncUnapplyCommands(commands: Command[], chunkSize: number, unapplyInReverseOrder?: boolean): Promise<void>;
|
419
440
|
private announceUndoCallback;
|
420
441
|
private announceRedoCallback;
|
@@ -492,7 +513,7 @@ export declare class Editor {
|
|
492
513
|
* @deprecated
|
493
514
|
* @see {@link sendPenEvent} {@link sendTouchEvent}
|
494
515
|
*/
|
495
|
-
sendPenEvent(eventType:
|
516
|
+
sendPenEvent(eventType: PointerEvtType, point: Point2, allPointers?: Pointer[]): void;
|
496
517
|
/**
|
497
518
|
* Adds all components in `components` such that they are in the center of the screen.
|
498
519
|
* This is a convenience method that creates **and applies** a single command.
|
package/dist/mjs/Editor.mjs
CHANGED
@@ -5,7 +5,7 @@ import { InputEvtType, keyUpEventFromHTMLEvent, keyPressEventFromHTMLEvent } f
|
|
5
5
|
import UndoRedoHistory from './UndoRedoHistory.mjs';
|
6
6
|
import Viewport from './Viewport.mjs';
|
7
7
|
import EventDispatcher from './EventDispatcher.mjs';
|
8
|
-
import { Vec2, Vec3, Color4, Mat33 } from '@js-draw/math';
|
8
|
+
import { Vec2, Vec3, Color4, Mat33, Rect2 } from '@js-draw/math';
|
9
9
|
import Display, { RenderingMode } from './rendering/Display.mjs';
|
10
10
|
import SVGLoader from './SVGLoader/SVGLoader.mjs';
|
11
11
|
import Pointer from './Pointer.mjs';
|
@@ -29,6 +29,7 @@ import { MutableReactiveValue } from './util/ReactiveValue.mjs';
|
|
29
29
|
import listenForKeyboardEventsFrom from './util/listenForKeyboardEventsFrom.mjs';
|
30
30
|
import mitLicenseAttribution from './util/mitLicenseAttribution.mjs';
|
31
31
|
import ClipboardHandler from './util/ClipboardHandler.mjs';
|
32
|
+
import ContextMenuRecognizer from './tools/InputFilter/ContextMenuRecognizer.mjs';
|
32
33
|
/**
|
33
34
|
* The main entrypoint for the full editor.
|
34
35
|
*
|
@@ -164,6 +165,7 @@ export class Editor {
|
|
164
165
|
this.toolController = new ToolController(this, this.localization);
|
165
166
|
// TODO: Make this pipeline configurable (e.g. allow users to add global input stabilization)
|
166
167
|
this.toolController.addInputMapper(StrokeKeyboardControl.fromEditor(this));
|
168
|
+
this.toolController.addInputMapper(new ContextMenuRecognizer());
|
167
169
|
parent.appendChild(this.container);
|
168
170
|
this.viewport.updateScreenSize(Vec2.of(this.display.width, this.display.height));
|
169
171
|
this.registerListeners();
|
@@ -221,12 +223,24 @@ export class Editor {
|
|
221
223
|
getRootElement() {
|
222
224
|
return this.container;
|
223
225
|
}
|
224
|
-
/**
|
226
|
+
/**
|
227
|
+
* @returns the bounding box of the main rendering region of the editor in the HTML viewport.
|
228
|
+
*
|
229
|
+
* @internal
|
230
|
+
*/
|
231
|
+
getOutputBBoxInDOM() {
|
232
|
+
return Rect2.of(this.renderingRegion.getBoundingClientRect());
|
233
|
+
}
|
234
|
+
/**
|
235
|
+
* Shows a "Loading..." message.
|
236
|
+
* @param fractionLoaded - should be a number from 0 to 1, where 1 represents completely loaded.
|
237
|
+
*/
|
225
238
|
showLoadingWarning(fractionLoaded) {
|
226
239
|
const loadingPercent = Math.round(fractionLoaded * 100);
|
227
240
|
this.loadingWarning.innerText = this.localization.loading(loadingPercent);
|
228
241
|
this.loadingWarning.style.display = 'block';
|
229
242
|
}
|
243
|
+
/** @see {@link showLoadingWarning} */
|
230
244
|
hideLoadingWarning() {
|
231
245
|
this.loadingWarning.style.display = 'none';
|
232
246
|
this.announceForAccessibility(this.localization.doneLoading);
|
@@ -340,8 +354,8 @@ export class Editor {
|
|
340
354
|
delta = Vec3.of(0, 0, event.deltaY);
|
341
355
|
}
|
342
356
|
// Ensure that `pos` is relative to `this.renderingRegion`
|
343
|
-
const bbox = this.
|
344
|
-
const pos = Vec2.of(event.clientX, event.clientY).minus(
|
357
|
+
const bbox = this.getOutputBBoxInDOM();
|
358
|
+
const pos = Vec2.of(event.clientX, event.clientY).minus(bbox.topLeft);
|
345
359
|
if (this.toolController.dispatchInputEvent({
|
346
360
|
kind: InputEvtType.WheelEvt,
|
347
361
|
delta,
|
@@ -689,7 +703,12 @@ export class Editor {
|
|
689
703
|
isReadOnly() {
|
690
704
|
return this.readOnly;
|
691
705
|
}
|
692
|
-
/**
|
706
|
+
/**
|
707
|
+
* `apply` a command. `command` will be announced for accessibility.
|
708
|
+
*
|
709
|
+
* **Example**:
|
710
|
+
* [[include:doc-pages/inline-examples/adding-a-stroke.md]]
|
711
|
+
*/
|
693
712
|
dispatch(command, addToHistory = true) {
|
694
713
|
const dispatchResult = this.dispatchNoAnnounce(command, addToHistory);
|
695
714
|
const commandDescription = command.description(this, this.localization);
|
@@ -750,12 +769,15 @@ export class Editor {
|
|
750
769
|
this.display.setDraftMode(false);
|
751
770
|
this.hideLoadingWarning();
|
752
771
|
}
|
753
|
-
|
772
|
+
/** @see {@link asyncApplyOrUnapplyCommands } */
|
754
773
|
asyncApplyCommands(commands, chunkSize) {
|
755
774
|
return this.asyncApplyOrUnapplyCommands(commands, true, chunkSize);
|
756
775
|
}
|
757
|
-
|
758
|
-
|
776
|
+
/**
|
777
|
+
* @see {@link asyncApplyOrUnapplyCommands}
|
778
|
+
*
|
779
|
+
* If `unapplyInReverseOrder`, commands are reversed before unapplying.
|
780
|
+
*/
|
759
781
|
asyncUnapplyCommands(commands, chunkSize, unapplyInReverseOrder = false) {
|
760
782
|
if (unapplyInReverseOrder) {
|
761
783
|
commands = [...commands]; // copy
|
@@ -1233,7 +1255,7 @@ export class Editor {
|
|
1233
1255
|
'',
|
1234
1256
|
'',
|
1235
1257
|
'== js-draw ==',
|
1236
|
-
mitLicenseAttribution('2023 Henry Heino'),
|
1258
|
+
mitLicenseAttribution('2023-2024 Henry Heino'),
|
1237
1259
|
'',
|
1238
1260
|
].join('\n'),
|
1239
1261
|
minimized: true,
|
@@ -54,7 +54,7 @@ export default class SVGLoader {
|
|
54
54
|
try {
|
55
55
|
fill = Color4.fromString(fillAttribute);
|
56
56
|
}
|
57
|
-
catch
|
57
|
+
catch {
|
58
58
|
console.error('Unknown fill color,', fillAttribute);
|
59
59
|
}
|
60
60
|
}
|
@@ -241,7 +241,7 @@ export default class SVGLoader {
|
|
241
241
|
supportedAttrs?.push(highpTransformAttribute);
|
242
242
|
}
|
243
243
|
catch (e) {
|
244
|
-
console.warn(`Unable to parse raw transform data, ${rawTransformData}. Falling back to CSS data
|
244
|
+
console.warn(`Unable to parse raw transform data, ${rawTransformData}. Falling back to CSS data. Error:`, e);
|
245
245
|
}
|
246
246
|
}
|
247
247
|
if (!transform) {
|
package/dist/mjs/Viewport.d.ts
CHANGED
@@ -78,14 +78,14 @@ export declare class Viewport {
|
|
78
78
|
minus(v: Vec3): Vec3;
|
79
79
|
dot(other: Vec3): number;
|
80
80
|
cross(other: Vec3): Vec3;
|
81
|
-
scale(other:
|
81
|
+
scale(other: Vec3 | number): Vec3;
|
82
82
|
orthog(): Vec3;
|
83
83
|
extend(distance: number, direction: Vec3): Vec3;
|
84
84
|
lerp(target: Vec3, fractionTo: number): Vec3;
|
85
85
|
zip(other: Vec3, zip: (componentInThis: number, componentInOther: number) => number): Vec3;
|
86
86
|
map(fn: (component: number, index: number) => number): Vec3;
|
87
87
|
asArray(): [number, number, number];
|
88
|
-
eq(other: Vec3, fuzz?: number
|
88
|
+
eq(other: Vec3, fuzz?: number): boolean;
|
89
89
|
toString(): string;
|
90
90
|
};
|
91
91
|
/** Returns the size of one screen pixel in canvas units. */
|
@@ -1,5 +1,10 @@
|
|
1
1
|
import Editor from '../Editor';
|
2
2
|
import { EditorLocalization } from '../localization';
|
3
|
+
/**
|
4
|
+
* A `Command` is an action that can be done, redone, and undone. It's used to enable undo/redo.
|
5
|
+
*
|
6
|
+
* See {@link Editor.dispatch}.
|
7
|
+
*/
|
3
8
|
export declare abstract class Command {
|
4
9
|
abstract apply(editor: Editor): Promise<void> | void;
|
5
10
|
abstract unapply(editor: Editor): Promise<void> | void;
|
@@ -1,8 +1,15 @@
|
|
1
1
|
import Editor from '../Editor';
|
2
2
|
import Command from './Command';
|
3
3
|
export type DeserializationCallback = (data: Record<string, any> | any[], editor: Editor) => SerializableCommand;
|
4
|
+
/**
|
5
|
+
* A command that can be serialized to or deserialized from JSON. To allow a command to be deserialized, {@link SerializableCommand.register}
|
6
|
+
* must be called for each {@link SerializableCommand}.
|
7
|
+
*
|
8
|
+
* This is used to [allow collaborative editing](https://github.com/personalizedrefrigerator/js-draw/tree/main/docs/examples/example-collaborative).
|
9
|
+
*/
|
4
10
|
export default abstract class SerializableCommand extends Command {
|
5
11
|
#private;
|
12
|
+
/** @param commandTypeId - A unique identifier for this command. */
|
6
13
|
constructor(commandTypeId: string);
|
7
14
|
protected abstract serializeToJSON(): string | Record<string, any> | any[];
|
8
15
|
private static deserializationCallbacks;
|
@@ -11,7 +11,14 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
11
11
|
};
|
12
12
|
var _SerializableCommand_commandTypeId;
|
13
13
|
import Command from './Command.mjs';
|
14
|
+
/**
|
15
|
+
* A command that can be serialized to or deserialized from JSON. To allow a command to be deserialized, {@link SerializableCommand.register}
|
16
|
+
* must be called for each {@link SerializableCommand}.
|
17
|
+
*
|
18
|
+
* This is used to [allow collaborative editing](https://github.com/personalizedrefrigerator/js-draw/tree/main/docs/examples/example-collaborative).
|
19
|
+
*/
|
14
20
|
class SerializableCommand extends Command {
|
21
|
+
/** @param commandTypeId - A unique identifier for this command. */
|
15
22
|
constructor(commandTypeId) {
|
16
23
|
super();
|
17
24
|
_SerializableCommand_commandTypeId.set(this, void 0);
|
@@ -32,6 +39,8 @@ class SerializableCommand extends Command {
|
|
32
39
|
}
|
33
40
|
// Convert a `string` containing JSON data (or the output of `JSON.parse`) into a
|
34
41
|
// `Command`.
|
42
|
+
//
|
43
|
+
// Implementations should assume that `data` is untrusted.
|
35
44
|
static deserialize(data, editor) {
|
36
45
|
const json = typeof data === 'string' ? JSON.parse(data) : data;
|
37
46
|
const commandType = json.commandType;
|
@@ -1,24 +1,9 @@
|
|
1
|
+
import makeMessageDialog from './makeMessageDialog.mjs';
|
1
2
|
const makeAboutDialog = (editor, entries) => {
|
2
|
-
const
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
const heading = document.createElement('h1');
|
7
|
-
heading.innerText = editor.localization.about;
|
8
|
-
heading.setAttribute('autofocus', 'true');
|
9
|
-
const closeButton = document.createElement('button');
|
10
|
-
closeButton.innerText = editor.localization.closeDialog;
|
11
|
-
closeButton.classList.add('close-button');
|
12
|
-
closeButton.onclick = () => removeOverlay();
|
13
|
-
overlay.onclick = event => {
|
14
|
-
if (event.target === overlay) {
|
15
|
-
removeOverlay();
|
16
|
-
}
|
17
|
-
};
|
18
|
-
const licenseContainer = document.createElement('div');
|
19
|
-
licenseContainer.classList.add('about-entry-container');
|
20
|
-
// Allow scrolling in the license container -- don't forward wheel events.
|
21
|
-
licenseContainer.onwheel = evt => evt.stopPropagation();
|
3
|
+
const dialog = makeMessageDialog(editor, {
|
4
|
+
title: editor.localization.about,
|
5
|
+
contentClassNames: ['about-dialog-content'],
|
6
|
+
});
|
22
7
|
for (const entry of entries) {
|
23
8
|
const container = document.createElement(entry.minimized ? 'details' : 'div');
|
24
9
|
container.classList.add('about-entry');
|
@@ -38,14 +23,11 @@ const makeAboutDialog = (editor, entries) => {
|
|
38
23
|
bodyText.innerText = entry.text;
|
39
24
|
container.appendChild(bodyText);
|
40
25
|
}
|
41
|
-
|
26
|
+
dialog.appendChild(container);
|
42
27
|
}
|
43
|
-
dialog.replaceChildren(heading, licenseContainer, closeButton);
|
44
|
-
overlay.replaceChildren(dialog);
|
45
|
-
dialog.show();
|
46
28
|
return {
|
47
29
|
close: () => {
|
48
|
-
|
30
|
+
return dialog.close();
|
49
31
|
},
|
50
32
|
};
|
51
33
|
};
|
@@ -0,0 +1,11 @@
|
|
1
|
+
import type Editor from '../Editor';
|
2
|
+
export interface MessageDialogOptions {
|
3
|
+
title: string;
|
4
|
+
classNames?: string[];
|
5
|
+
contentClassNames?: string[];
|
6
|
+
}
|
7
|
+
declare const makeAboutDialog: (editor: Editor, options: MessageDialogOptions) => {
|
8
|
+
close: () => Promise<void>;
|
9
|
+
appendChild: (child: Node) => void;
|
10
|
+
};
|
11
|
+
export default makeAboutDialog;
|
@@ -0,0 +1,51 @@
|
|
1
|
+
import waitForTimeout from '../util/waitForTimeout.mjs';
|
2
|
+
const makeAboutDialog = (editor, options) => {
|
3
|
+
const overlay = document.createElement('div');
|
4
|
+
const { remove: removeOverlay } = editor.createHTMLOverlay(overlay);
|
5
|
+
overlay.classList.add('dialog-container', 'message-dialog-container', ...(options.classNames ?? []));
|
6
|
+
const dialog = document.createElement('dialog');
|
7
|
+
const contentWrapper = document.createElement('div');
|
8
|
+
contentWrapper.classList.add('message-dialog-content', ...(options.contentClassNames ?? []));
|
9
|
+
const heading = document.createElement('h1');
|
10
|
+
heading.textContent = options.title;
|
11
|
+
heading.setAttribute('autofocus', 'true');
|
12
|
+
const closeButton = document.createElement('button');
|
13
|
+
closeButton.innerText = editor.localization.closeDialog;
|
14
|
+
closeButton.classList.add('close');
|
15
|
+
const scrollRegion = document.createElement('div');
|
16
|
+
scrollRegion.classList.add('scroll');
|
17
|
+
// Allow scrolling in the scrollable container -- don't forward wheel events.
|
18
|
+
scrollRegion.onwheel = evt => evt.stopPropagation();
|
19
|
+
contentWrapper.replaceChildren(heading, scrollRegion, closeButton);
|
20
|
+
dialog.replaceChildren(contentWrapper);
|
21
|
+
overlay.replaceChildren(dialog);
|
22
|
+
const closeTimeout = 300;
|
23
|
+
dialog.style.setProperty('--close-delay', `${closeTimeout}ms`);
|
24
|
+
const closeDialog = async () => {
|
25
|
+
dialog.classList.add('-closing');
|
26
|
+
await waitForTimeout(closeTimeout);
|
27
|
+
dialog.close();
|
28
|
+
};
|
29
|
+
const addCloseListeners = () => {
|
30
|
+
dialog.addEventListener('pointerdown', event => {
|
31
|
+
if (event.target === dialog) {
|
32
|
+
void closeDialog();
|
33
|
+
}
|
34
|
+
});
|
35
|
+
dialog.onclose = () => {
|
36
|
+
removeOverlay();
|
37
|
+
};
|
38
|
+
closeButton.onclick = () => closeDialog();
|
39
|
+
};
|
40
|
+
addCloseListeners();
|
41
|
+
dialog.showModal();
|
42
|
+
return {
|
43
|
+
close: () => {
|
44
|
+
return closeDialog();
|
45
|
+
},
|
46
|
+
appendChild: (child) => {
|
47
|
+
scrollRegion.appendChild(child);
|
48
|
+
},
|
49
|
+
};
|
50
|
+
};
|
51
|
+
export default makeAboutDialog;
|
@@ -21,6 +21,9 @@ export type EditorImageNotifier = EventDispatcher<EditorImageEventType, {
|
|
21
21
|
* 3. stop the render process early by returning `false`.
|
22
22
|
*/
|
23
23
|
export type PreRenderComponentCallback = (component: AbstractComponent, componentsProcessed: number, totalComponents: number) => Promise<boolean>;
|
24
|
+
/**
|
25
|
+
* Handles lookup/storage of elements in the image.
|
26
|
+
*/
|
24
27
|
export default class EditorImage {
|
25
28
|
private root;
|
26
29
|
private background;
|
@@ -88,7 +91,8 @@ export default class EditorImage {
|
|
88
91
|
*
|
89
92
|
* @see {@link Display.flatten}
|
90
93
|
*
|
91
|
-
*
|
94
|
+
* **Example**:
|
95
|
+
*
|
92
96
|
* [[include:doc-pages/inline-examples/adding-a-stroke.md]]
|
93
97
|
*/
|
94
98
|
static addElement(elem: AbstractComponent, applyByFlattening?: boolean): SerializableCommand;
|
@@ -199,6 +203,16 @@ export declare class ImageNode {
|
|
199
203
|
getParent(): ImageNode | null;
|
200
204
|
protected getChildrenIntersectingRegion(region: Rect2, isTooSmallFilter?: TooSmallToRenderCheck): ImageNode[];
|
201
205
|
getChildrenOrSelfIntersectingRegion(region: Rect2): ImageNode[];
|
206
|
+
/**
|
207
|
+
* Returns a list of `ImageNode`s with content (and thus no children).
|
208
|
+
* Override getChildrenIntersectingRegion to customize how this method
|
209
|
+
* determines whether/which children are in `region`.
|
210
|
+
*
|
211
|
+
* @paran region - All resultant `ImageNode`s must intersect `region`.
|
212
|
+
* @param isTooSmall - If `isTooSmall` returns true for an image node, that node
|
213
|
+
* is excluded from the output.
|
214
|
+
*
|
215
|
+
*/
|
202
216
|
getLeavesIntersectingRegion(region: Rect2, isTooSmall?: TooSmallToRenderCheck): ImageNode[];
|
203
217
|
getChildWithContent(target: AbstractComponent): ImageNode | null;
|
204
218
|
getLeaves(): ImageNode[];
|
@@ -20,7 +20,9 @@ export var EditorImageEventType;
|
|
20
20
|
EditorImageEventType[EditorImageEventType["AutoresizeModeChanged"] = 1] = "AutoresizeModeChanged";
|
21
21
|
})(EditorImageEventType || (EditorImageEventType = {}));
|
22
22
|
let debugMode = false;
|
23
|
-
|
23
|
+
/**
|
24
|
+
* Handles lookup/storage of elements in the image.
|
25
|
+
*/
|
24
26
|
class EditorImage {
|
25
27
|
// @internal
|
26
28
|
constructor() {
|
@@ -181,7 +183,8 @@ class EditorImage {
|
|
181
183
|
*
|
182
184
|
* @see {@link Display.flatten}
|
183
185
|
*
|
184
|
-
*
|
186
|
+
* **Example**:
|
187
|
+
*
|
185
188
|
* [[include:doc-pages/inline-examples/adding-a-stroke.md]]
|
186
189
|
*/
|
187
190
|
static addElement(elem, applyByFlattening = false) {
|
@@ -518,9 +521,16 @@ export class ImageNode {
|
|
518
521
|
}
|
519
522
|
return this.getChildrenIntersectingRegion(region);
|
520
523
|
}
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
+
/**
|
525
|
+
* Returns a list of `ImageNode`s with content (and thus no children).
|
526
|
+
* Override getChildrenIntersectingRegion to customize how this method
|
527
|
+
* determines whether/which children are in `region`.
|
528
|
+
*
|
529
|
+
* @paran region - All resultant `ImageNode`s must intersect `region`.
|
530
|
+
* @param isTooSmall - If `isTooSmall` returns true for an image node, that node
|
531
|
+
* is excluded from the output.
|
532
|
+
*
|
533
|
+
*/
|
524
534
|
getLeavesIntersectingRegion(region, isTooSmall) {
|
525
535
|
const result = [];
|
526
536
|
const workList = [];
|