edytor 0.1.0-next.17 → 0.1.0-next.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/components/Edytor.svelte +3 -8
- package/dist/events/onFocus.d.ts +16 -0
- package/dist/events/onFocus.js +94 -18
- package/dist/plugins/blockMenu/blockMenuPlugin.js +4 -2
- package/dist/plugins/columns/ColumnResize.svelte +1 -1
- package/dist/plugins/columns/resize.svelte.d.ts +14 -2
- package/dist/plugins/columns/resize.svelte.js +31 -10
- package/dist/plugins/slashMenu/slashMenuPlugin.js +4 -2
- package/dist/selection/selection.svelte.d.ts +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
Edytor aims to be for Svelte what Slate.js is for React: a heavily customizable editor with an API to build any kind of collaborative rich text editor.
|
|
17
17
|
|
|
18
|
-
> **Work in progress.** Edytor is a pre-release (`0.1.0-next.
|
|
18
|
+
> **Work in progress.** Edytor is a pre-release (`0.1.0-next.19`, `edytor@next` on npm) and not ready for production; the API changes between releases without a compatibility layer. The untagged `edytor@0.0.11` on npm predates the current API. Issues and PRs are welcome: when you report a bug, include the document's JSON value.
|
|
19
19
|
|
|
20
20
|
## Features
|
|
21
21
|
|
|
@@ -323,18 +323,13 @@
|
|
|
323
323
|
|
|
324
324
|
const nonNativeEditableBlockChromeSelection = (node: HTMLElement) => {
|
|
325
325
|
const { selection } = edytor;
|
|
326
|
-
const pointerdown = (event: PointerEvent) =>
|
|
327
|
-
selection.handleNonNativeEditableBlockChromePointerDown(event);
|
|
328
|
-
node.addEventListener('pointerdown', pointerdown, true);
|
|
329
326
|
// `selectstart` is the only event fired before a drag-selection
|
|
330
327
|
// begins — the guard keeps one from starting on non-editable
|
|
331
|
-
// chrome (markers, void/island chrome, plugin UI).
|
|
328
|
+
// chrome (markers, void/island chrome, plugin UI). A press on that
|
|
329
|
+
// chrome is the press's (`events/onFocus.ts`).
|
|
332
330
|
node.addEventListener('selectstart', selection.onSelectStart);
|
|
333
331
|
return {
|
|
334
|
-
destroy: () =>
|
|
335
|
-
node.removeEventListener('pointerdown', pointerdown, true);
|
|
336
|
-
node.removeEventListener('selectstart', selection.onSelectStart);
|
|
337
|
-
}
|
|
332
|
+
destroy: () => node.removeEventListener('selectstart', selection.onSelectStart)
|
|
338
333
|
};
|
|
339
334
|
};
|
|
340
335
|
</script>
|
package/dist/events/onFocus.d.ts
CHANGED
|
@@ -12,4 +12,20 @@ export declare const selectionIsInside: (node: HTMLElement) => boolean;
|
|
|
12
12
|
* already inside the host, or the view is gone.
|
|
13
13
|
*/
|
|
14
14
|
export declare const takeKeys: (edytor: Edytor) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Whether `event` is the press of a primary `mousedown` no `pointerdown`
|
|
17
|
+
* came before (WebKit's first press after a drag). Asked during the
|
|
18
|
+
* event's dispatch, after the document's capture phase saw it: by a
|
|
19
|
+
* listener the view's attach installs later (a plugin's `onEdytorAttached`)
|
|
20
|
+
* or by an element's own (bubbling, target phase), such as the chrome in the
|
|
21
|
+
* overlay, which starts from it as from a `pointerdown`.
|
|
22
|
+
*/
|
|
23
|
+
export declare const isLonePress: (edytor: Edytor, event: MouseEvent) => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Every press on `target` (`isLonePress`): its `pointerdown`, or the lone
|
|
26
|
+
* `mousedown` standing for a missing one, never both for one press. For a
|
|
27
|
+
* listener installed after the view's attach (a plugin's press outside its
|
|
28
|
+
* menu). Answers the teardown.
|
|
29
|
+
*/
|
|
30
|
+
export declare const onPress: (edytor: Edytor, target: EventTarget, listener: (event: MouseEvent) => void, options?: boolean | AddEventListenerOptions) => () => void;
|
|
15
31
|
export declare const attachFocus: (edytor: Edytor, node: HTMLElement) => (() => void)[];
|
package/dist/events/onFocus.js
CHANGED
|
@@ -37,8 +37,70 @@ export const takeKeys = (edytor) => {
|
|
|
37
37
|
node.focus({ preventScroll: true });
|
|
38
38
|
edytor.projector.parked();
|
|
39
39
|
};
|
|
40
|
+
/*
|
|
41
|
+
* The press: one per primary button press, its `pointerdown`, or a
|
|
42
|
+
* `mousedown` no `pointerdown` came before. WebKit fires no `pointercancel`
|
|
43
|
+
* at a native `dragstart` (a block handle's drag) and, believing the button
|
|
44
|
+
* still down, no `pointerdown` for the next press, only its `mousedown`
|
|
45
|
+
* (WebKit bugs 202287, 222632, 279749): that primary `mousedown` is the
|
|
46
|
+
* press (lone). `attachFocus` classifies each `mousedown` of its view's
|
|
47
|
+
* document at the capture phase, first of the view's listeners; the lone one
|
|
48
|
+
* of each view is kept here, read by `isLonePress` and `onPress`.
|
|
49
|
+
*/
|
|
50
|
+
const lonePresses = new WeakMap();
|
|
51
|
+
/**
|
|
52
|
+
* Whether `event` is the press of a primary `mousedown` no `pointerdown`
|
|
53
|
+
* came before (WebKit's first press after a drag). Asked during the
|
|
54
|
+
* event's dispatch, after the document's capture phase saw it: by a
|
|
55
|
+
* listener the view's attach installs later (a plugin's `onEdytorAttached`)
|
|
56
|
+
* or by an element's own (bubbling, target phase), such as the chrome in the
|
|
57
|
+
* overlay, which starts from it as from a `pointerdown`.
|
|
58
|
+
*/
|
|
59
|
+
export const isLonePress = (edytor, event) => lonePresses.get(edytor) === event;
|
|
60
|
+
/**
|
|
61
|
+
* Every press on `target` (`isLonePress`): its `pointerdown`, or the lone
|
|
62
|
+
* `mousedown` standing for a missing one, never both for one press. For a
|
|
63
|
+
* listener installed after the view's attach (a plugin's press outside its
|
|
64
|
+
* menu). Answers the teardown.
|
|
65
|
+
*/
|
|
66
|
+
export const onPress = (edytor, target, listener, options) => {
|
|
67
|
+
const lone = (event) => {
|
|
68
|
+
if (isLonePress(edytor, event))
|
|
69
|
+
listener(event);
|
|
70
|
+
};
|
|
71
|
+
target.addEventListener('pointerdown', listener, options);
|
|
72
|
+
target.addEventListener('mousedown', lone, options);
|
|
73
|
+
return () => {
|
|
74
|
+
target.removeEventListener('pointerdown', listener, options);
|
|
75
|
+
target.removeEventListener('mousedown', lone, options);
|
|
76
|
+
};
|
|
77
|
+
};
|
|
40
78
|
export const attachFocus = (edytor, node) => {
|
|
41
79
|
let lastPointerDownInsideEditorAt = Number.NEGATIVE_INFINITY;
|
|
80
|
+
/*
|
|
81
|
+
* A primary `pointerdown` arms `compat` until the `mousedown` it is
|
|
82
|
+
* followed by (before or after its release, a touch's comes after), so a
|
|
83
|
+
* pair counts once. Only the browser's own `mousedown` stands for a
|
|
84
|
+
* missing press; a script's is none (`lonePresses`).
|
|
85
|
+
*/
|
|
86
|
+
let compat = false;
|
|
87
|
+
const lone = (event) => isLonePress(edytor, event);
|
|
88
|
+
/** Where the press landed: the gesture serial, and whether the user went outside. */
|
|
89
|
+
const gesture = (event) => {
|
|
90
|
+
edytor.markUserGesture();
|
|
91
|
+
edytor.lastUserGestureOutsideEditor = Boolean(event.target instanceof Node && !edytor.node?.contains(event.target));
|
|
92
|
+
};
|
|
93
|
+
/** A press inside the host (its bubbling phase: an element inside that took it keeps it). */
|
|
94
|
+
const pressInside = (event) => {
|
|
95
|
+
// A pointer gesture abandons a live composition (D-7).
|
|
96
|
+
edytor.composition.abandon();
|
|
97
|
+
lastPointerDownInsideEditorAt = getEventTimeStamp(event);
|
|
98
|
+
edytor.projector.pressed();
|
|
99
|
+
edytor.selection.clearModelSelectionPreservation();
|
|
100
|
+
edytor.selection.capturePointerDragStart(event);
|
|
101
|
+
edytor.selection.clearInlineBlockSelection();
|
|
102
|
+
edytor.selection.collapseSelectedBlocksAtPointer(event);
|
|
103
|
+
};
|
|
42
104
|
const clearNativeSelectionAfterExternalFocus = () => {
|
|
43
105
|
const activeElement = getActiveElement(node);
|
|
44
106
|
if (activeElement instanceof Node && node.contains(activeElement)) {
|
|
@@ -112,26 +174,39 @@ export const attachFocus = (edytor, node) => {
|
|
|
112
174
|
queueMicrotask(restore);
|
|
113
175
|
};
|
|
114
176
|
return [
|
|
115
|
-
// Any
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
//
|
|
177
|
+
// Any press anywhere disarms pending restores — Firefox can move
|
|
178
|
+
// the DOM selection on outside clicks without blurring the editor,
|
|
179
|
+
// so node-local marking is not enough. The target also records
|
|
180
|
+
// where the gesture landed: an outside press means the current
|
|
181
|
+
// focus/selection is user-owned until an inside gesture or focusin
|
|
182
|
+
// returns it.
|
|
121
183
|
on(node.ownerDocument, 'pointerdown', (event) => {
|
|
122
|
-
|
|
123
|
-
|
|
184
|
+
if (event.isPrimary)
|
|
185
|
+
compat = true;
|
|
186
|
+
lonePresses.delete(edytor);
|
|
187
|
+
gesture(event);
|
|
188
|
+
}, { capture: true }),
|
|
189
|
+
on(node.ownerDocument, 'mousedown', (event) => {
|
|
190
|
+
const press = !compat && event.isTrusted && event.button === 0;
|
|
191
|
+
compat = false;
|
|
192
|
+
if (!press)
|
|
193
|
+
return void lonePresses.delete(edytor);
|
|
194
|
+
lonePresses.set(edytor, event);
|
|
195
|
+
gesture(event);
|
|
196
|
+
}, { capture: true }),
|
|
197
|
+
// A press on a block's non-editable chrome places the caret in its text.
|
|
198
|
+
on(node, 'pointerdown', edytor.selection.handleNonNativeEditableBlockChromePointerDown, {
|
|
199
|
+
capture: true
|
|
200
|
+
}),
|
|
201
|
+
on(node, 'mousedown', (event) => {
|
|
202
|
+
if (lone(event))
|
|
203
|
+
edytor.selection.handleNonNativeEditableBlockChromePointerDown(event);
|
|
124
204
|
}, { capture: true }),
|
|
125
205
|
// The document's capture listener already marked the gesture.
|
|
126
|
-
on(node, 'pointerdown',
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
edytor.projector.pressed();
|
|
131
|
-
edytor.selection.clearModelSelectionPreservation();
|
|
132
|
-
edytor.selection.capturePointerDragStart(event);
|
|
133
|
-
edytor.selection.clearInlineBlockSelection();
|
|
134
|
-
edytor.selection.collapseSelectedBlocksAtPointer(event);
|
|
206
|
+
on(node, 'pointerdown', pressInside),
|
|
207
|
+
on(node, 'mousedown', (event) => {
|
|
208
|
+
if (lone(event))
|
|
209
|
+
pressInside(event);
|
|
135
210
|
}),
|
|
136
211
|
on(node, 'pointerup', (event) => {
|
|
137
212
|
edytor.markUserGesture();
|
|
@@ -185,6 +260,7 @@ export const attachFocus = (edytor, node) => {
|
|
|
185
260
|
// Focus leaving abandons a live composition: the browser committed what it shows.
|
|
186
261
|
edytor.composition.abandon();
|
|
187
262
|
setTimeout(clearNativeSelectionAfterExternalFocus);
|
|
188
|
-
})
|
|
263
|
+
}),
|
|
264
|
+
() => void lonePresses.delete(edytor)
|
|
189
265
|
];
|
|
190
266
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BLOCK_ACTIVATE_EVENT, BLOCK_ADD_EVENT } from '../blockHandles/BlockHandleController.svelte.js';
|
|
2
|
+
import { onPress } from '../../events/onFocus.js';
|
|
2
3
|
import { getSelectedBlocksInDocumentOrder } from '../../selection/replaceSelection.js';
|
|
3
4
|
import BlockMenu from './BlockMenu.svelte';
|
|
4
5
|
import { BlockMenuController } from './BlockMenuController.svelte.js';
|
|
@@ -103,12 +104,13 @@ export const createBlockMenuPlugin = (options = {}) => (edytor) => {
|
|
|
103
104
|
const add = () => controller.close(false);
|
|
104
105
|
node.addEventListener(BLOCK_ACTIVATE_EVENT, activate);
|
|
105
106
|
node.addEventListener(BLOCK_ADD_EVENT, add);
|
|
106
|
-
|
|
107
|
+
// Every press, WebKit's lone `mousedown` after a drag too (`onPress`).
|
|
108
|
+
const offPress = onPress(edytor, node.ownerDocument, outside, true);
|
|
107
109
|
const unmount = edytor.overlay.mount(BlockMenu, { controller, menu: options.menu }, 'edytor-block-menu-host', 70, place);
|
|
108
110
|
return () => {
|
|
109
111
|
node.removeEventListener(BLOCK_ACTIVATE_EVENT, activate);
|
|
110
112
|
node.removeEventListener(BLOCK_ADD_EVENT, add);
|
|
111
|
-
|
|
113
|
+
offPress();
|
|
112
114
|
unmount();
|
|
113
115
|
};
|
|
114
116
|
}
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
data-dragging={resize.drag ? 'true' : undefined}
|
|
34
34
|
data-selecting={resize.selecting ? 'true' : undefined}
|
|
35
35
|
onpointerdown={(event) => resize.start(event, strip)}
|
|
36
|
-
onmousedown={(event) =>
|
|
36
|
+
onmousedown={(event) => resize.mousedown(event, strip)}
|
|
37
37
|
></div>
|
|
38
38
|
{/each}
|
|
39
39
|
{/if}
|
|
@@ -93,8 +93,20 @@ export declare class ColumnResize {
|
|
|
93
93
|
private gaps;
|
|
94
94
|
/** The left column's width at the drag's pointer, held to the minimum on both sides. */
|
|
95
95
|
private widthAt;
|
|
96
|
-
/**
|
|
97
|
-
|
|
96
|
+
/**
|
|
97
|
+
* A `mousedown` on `strip`: no native selection starts there; the press
|
|
98
|
+
* itself when no `pointerdown` came before it (`isLonePress`: WebKit's
|
|
99
|
+
* first press after a block drag), which starts the drag as one would.
|
|
100
|
+
*/
|
|
101
|
+
mousedown: (event: MouseEvent, strip: Strip) => void;
|
|
102
|
+
/**
|
|
103
|
+
* Press on `strip`: the drag starts, nothing is written until the release.
|
|
104
|
+
* A `pointerdown` tracks its pointer (captured, on the document); a lone
|
|
105
|
+
* `mousedown` (`mousedown`) tracks the mouse on the window, its
|
|
106
|
+
* `mousemove`s and its `mouseup`, with the same preview, minimum, Escape
|
|
107
|
+
* and release.
|
|
108
|
+
*/
|
|
109
|
+
start: (event: PointerEvent | MouseEvent, strip: Strip) => void;
|
|
98
110
|
/**
|
|
99
111
|
* The view turned readonly (or the document read-only): a drag in progress
|
|
100
112
|
* ends at once, its preview dropped, nothing written (its release would be
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { takeKeys } from '../../events/onFocus.js';
|
|
1
|
+
import { isLonePress, takeKeys } from '../../events/onFocus.js';
|
|
2
2
|
import { bandOf, gapBefore } from './gaps.js';
|
|
3
3
|
import { stacks } from './stacking.js';
|
|
4
4
|
/** The guide line's width (the hover guide's and the drag's). */
|
|
@@ -141,7 +141,23 @@ export class ColumnResize {
|
|
|
141
141
|
const hi = Math.max(sum - min, width);
|
|
142
142
|
return Math.min(hi, Math.max(lo, width + at - from));
|
|
143
143
|
}
|
|
144
|
-
/**
|
|
144
|
+
/**
|
|
145
|
+
* A `mousedown` on `strip`: no native selection starts there; the press
|
|
146
|
+
* itself when no `pointerdown` came before it (`isLonePress`: WebKit's
|
|
147
|
+
* first press after a block drag), which starts the drag as one would.
|
|
148
|
+
*/
|
|
149
|
+
mousedown = (event, strip) => {
|
|
150
|
+
event.preventDefault();
|
|
151
|
+
if (isLonePress(this.edytor, event))
|
|
152
|
+
this.start(event, strip);
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Press on `strip`: the drag starts, nothing is written until the release.
|
|
156
|
+
* A `pointerdown` tracks its pointer (captured, on the document); a lone
|
|
157
|
+
* `mousedown` (`mousedown`) tracks the mouse on the window, its
|
|
158
|
+
* `mousemove`s and its `mouseup`, with the same preview, minimum, Escape
|
|
159
|
+
* and release.
|
|
160
|
+
*/
|
|
145
161
|
start = (event, strip) => {
|
|
146
162
|
const { edytor } = this;
|
|
147
163
|
if (event.button !== 0 || edytor.readonly || this.drag)
|
|
@@ -155,7 +171,9 @@ export class ColumnResize {
|
|
|
155
171
|
event.preventDefault();
|
|
156
172
|
event.stopPropagation();
|
|
157
173
|
const target = event.currentTarget;
|
|
158
|
-
|
|
174
|
+
const pointer = event.type === 'pointerdown';
|
|
175
|
+
if (pointer)
|
|
176
|
+
target?.setPointerCapture?.(event.pointerId);
|
|
159
177
|
this.drag = {
|
|
160
178
|
strip,
|
|
161
179
|
left,
|
|
@@ -171,6 +189,8 @@ export class ColumnResize {
|
|
|
171
189
|
height: box.height
|
|
172
190
|
};
|
|
173
191
|
const document = target?.ownerDocument ?? edytor.node?.ownerDocument;
|
|
192
|
+
const tracked = pointer ? document : document?.defaultView;
|
|
193
|
+
const [moves, ups] = pointer ? ['pointermove', 'pointerup'] : ['mousemove', 'mouseup'];
|
|
174
194
|
const move = (moved) => {
|
|
175
195
|
if (!this.drag)
|
|
176
196
|
return;
|
|
@@ -181,16 +201,16 @@ export class ColumnResize {
|
|
|
181
201
|
edytor.overlay.invalidate();
|
|
182
202
|
};
|
|
183
203
|
const end = (ended) => {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
204
|
+
tracked?.removeEventListener(moves, move);
|
|
205
|
+
tracked?.removeEventListener(ups, end);
|
|
206
|
+
tracked?.removeEventListener('pointercancel', end);
|
|
187
207
|
document?.removeEventListener('keydown', escape, true);
|
|
188
208
|
const drag = this.drag;
|
|
189
209
|
this.drag = null;
|
|
190
210
|
this.guide = null;
|
|
191
211
|
this.#cancel = null;
|
|
192
212
|
edytor.overlay.invalidate();
|
|
193
|
-
if (drag && ended.type ===
|
|
213
|
+
if (drag && ended.type === ups) {
|
|
194
214
|
drag.at = ended.clientX;
|
|
195
215
|
this.release(drag);
|
|
196
216
|
// The editor holds the keys after the release (Notion: Mod+Z right after).
|
|
@@ -207,9 +227,10 @@ export class ColumnResize {
|
|
|
207
227
|
end(key);
|
|
208
228
|
};
|
|
209
229
|
this.#cancel = () => end(new Event('cancel'));
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
230
|
+
tracked?.addEventListener(moves, move);
|
|
231
|
+
tracked?.addEventListener(ups, end);
|
|
232
|
+
if (pointer)
|
|
233
|
+
tracked?.addEventListener('pointercancel', end);
|
|
213
234
|
document?.addEventListener('keydown', escape, true);
|
|
214
235
|
edytor.overlay.invalidate();
|
|
215
236
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BLOCK_ACTIVATE_EVENT, BLOCK_ADD_EVENT } from '../blockHandles/BlockHandleController.svelte.js';
|
|
2
|
+
import { onPress } from '../../events/onFocus.js';
|
|
2
3
|
import SlashMenu from './SlashMenu.svelte';
|
|
3
4
|
import { SlashMenuController } from './SlashMenuController.svelte.js';
|
|
4
5
|
/** The slash menu, with your own markup through `menu` or `item` snippets. */
|
|
@@ -90,12 +91,13 @@ export const createSlashMenuPlugin = (options = {}) => (edytor) => {
|
|
|
90
91
|
};
|
|
91
92
|
node.addEventListener(BLOCK_ADD_EVENT, offer);
|
|
92
93
|
node.addEventListener(BLOCK_ACTIVATE_EVENT, activate);
|
|
93
|
-
|
|
94
|
+
// Every press, WebKit's lone `mousedown` after a drag too (`onPress`).
|
|
95
|
+
const offPress = onPress(edytor, node.ownerDocument, outside, true);
|
|
94
96
|
const unmount = edytor.overlay.mount(SlashMenu, { controller, menu: options.menu, item: options.item }, 'edytor-slash-menu-host', 50, positionMenu);
|
|
95
97
|
return () => {
|
|
96
98
|
node.removeEventListener(BLOCK_ADD_EVENT, offer);
|
|
97
99
|
node.removeEventListener(BLOCK_ACTIVATE_EVENT, activate);
|
|
98
|
-
|
|
100
|
+
offPress();
|
|
99
101
|
unmount();
|
|
100
102
|
};
|
|
101
103
|
}
|
|
@@ -166,7 +166,7 @@ export declare class EdytorSelection {
|
|
|
166
166
|
private isInsideEditableText;
|
|
167
167
|
private getNonNativeEditableIslandBlock;
|
|
168
168
|
private getNonNativeEditableBlockChromeBlock;
|
|
169
|
-
handleNonNativeEditableBlockChromePointerDown: (event:
|
|
169
|
+
handleNonNativeEditableBlockChromePointerDown: (event: MouseEvent) => void;
|
|
170
170
|
private normalizeTextRangePoints;
|
|
171
171
|
init: () => void;
|
|
172
172
|
/**
|
|
@@ -179,7 +179,7 @@ export declare class EdytorSelection {
|
|
|
179
179
|
private getTextPointFromClientPoint;
|
|
180
180
|
private getTextOffsetFromClientPoint;
|
|
181
181
|
setTextSelectionFromPointer: (text: Text, clientX: number, clientY: number) => void;
|
|
182
|
-
capturePointerDragStart: (event:
|
|
182
|
+
capturePointerDragStart: (event: MouseEvent) => void;
|
|
183
183
|
clearPointerDragStart: () => void;
|
|
184
184
|
/**
|
|
185
185
|
* The block selection value over which the DOM caret was put — a primary
|
|
@@ -191,7 +191,7 @@ export declare class EdytorSelection {
|
|
|
191
191
|
* when the block selection shows no DOM range (for the paste's own keys).
|
|
192
192
|
*/
|
|
193
193
|
placedOver: SelectionValue | null;
|
|
194
|
-
collapseSelectedBlocksAtPointer: (event:
|
|
194
|
+
collapseSelectedBlocksAtPointer: (event: MouseEvent) => void;
|
|
195
195
|
restoreInlineAtomDragRange: (event: PointerEvent) => void;
|
|
196
196
|
/**
|
|
197
197
|
* `selectstart` is the only event fired before a drag-selection begins.
|