-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCrossBlockSelection.js
More file actions
74 lines (65 loc) · 1.9 KB
/
Copy pathCrossBlockSelection.js
File metadata and controls
74 lines (65 loc) · 1.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/**
* Stores the cross-block Range that native Selection cannot represent.
* Browsers clip Selection to the focused contentEditable, so this service
* preserves the full range across editing hosts for copy/cut/format/convert.
*
* Also manages the visual side-effects: CSS Highlight API painting and
* the `.oe-editor--cross-selecting` class that suppresses `::selection`.
*/
/** Highlight key used across the editor for cross-block visual highlight. */
const HIGHLIGHT_KEY = 'oe-cross-select'
export class CrossBlockSelection {
/** @type {Range | null} */
#range = null
/** @returns {Range | null} */
get range() {
return this.#range
}
/** @param {Range} range */
set(range) {
this.#range = range
}
clear() {
this.#range = null
}
/** @returns {Range | null} */
clone() {
return this.#range?.cloneRange() ?? null
}
/**
* Show a visual-only CSS Highlight for a range (no state change).
* @param {Range} range
*/
static showHighlight(range) {
if (typeof Highlight !== 'undefined' && CSS.highlights) {
CSS.highlights.set(HIGHLIGHT_KEY, new Highlight(range))
}
}
/**
* Remove the visual-only CSS Highlight (no state change).
*/
static hideHighlight() {
if (typeof CSS !== 'undefined' && CSS.highlights) {
CSS.highlights.delete(HIGHLIGHT_KEY)
}
}
/**
* Store the range and activate visual highlight.
* @param {Range} range
* @param {HTMLElement} rootEl - `.oe-editor` element
*/
activate(range, rootEl) {
this.#range = range
rootEl.classList.add('oe-editor--cross-selecting')
CrossBlockSelection.showHighlight(range)
}
/**
* Clear the stored range and remove visual highlight.
* @param {HTMLElement} [rootEl] - `.oe-editor` element
*/
deactivate(rootEl) {
this.#range = null
if (rootEl) rootEl.classList.remove('oe-editor--cross-selecting')
CrossBlockSelection.hideHighlight()
}
}