This repository has been archived by the owner on Nov 11, 2020. It is now read-only.
forked from ianstormtaylor/slate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdom-snapshot.js
67 lines (57 loc) · 1.93 KB
/
dom-snapshot.js
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
import getSelectionFromDom from './get-selection-from-dom'
import ElementSnapshot from './element-snapshot'
/**
* Returns the closest element that matches the selector.
* Unlike the native `Element.closest` method, this doesn't require the
* starting node to be an Element.
*
* @param {Node} node to start at
* @param {String} css selector to match
* @return {Element} the closest matching element
*/
function closest(node, selector, win = window) {
if (node.nodeType === win.Node.TEXT_NODE) {
node = node.parentNode
}
return node.closest(selector)
}
/**
* A DomSnapshot remembers the state of elements at a given point in time
* and also remembers the state of the Editor at that time as well.
* The state can be applied to the DOM at a time in the future.
*/
export default class DomSnapshot {
/**
* Constructor.
*
* @param {Window} window
* @param {Editor} editor
* @param {Boolean} options.before - should we remember the element before the one passed in
*/
constructor(window, editor, { before = false } = {}) {
const domSelection = window.getSelection()
const { anchorNode } = domSelection
const subrootEl = closest(anchorNode, '[data-slate-editor] > *')
const elements = [subrootEl]
// The before option is for when we need to take a snapshot of the current
// subroot and the element before when the user hits the backspace key.
if (before) {
const { previousElementSibling } = subrootEl
if (previousElementSibling) {
elements.unshift(previousElementSibling)
}
}
this.snapshot = new ElementSnapshot(elements)
this.selection = getSelectionFromDom(window, editor, domSelection)
}
/**
* Apply the snapshot to the DOM and set the selection in the Editor.
*
* @param {Editor} editor
*/
apply(editor) {
const { snapshot, selection } = this
snapshot.apply()
editor.moveTo(selection.anchor.key, selection.anchor.offset)
}
}