forked from ianstormtaylor/slate
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfind-range.js
84 lines (71 loc) · 2.04 KB
/
find-range.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import getWindow from 'get-window'
import invariant from 'tiny-invariant'
import { IS_IE, IS_EDGE } from 'slate-dev-environment'
import { Value } from 'slate'
import findPoint from './find-point'
import findDOMPoint from './find-dom-point'
/**
* Find a Slate range from a DOM `native` selection.
*
* @param {Selection} native
* @param {Editor} editor
* @return {Range}
*/
function findRange(native, editor) {
invariant(
!Value.isValue(editor),
'As of Slate 0.42.0, the `findNode` utility takes an `editor` instead of a `value`.'
)
const el = native.anchorNode || native.startContainer
if (!el) return null
const window = getWindow(el)
// If the `native` object is a DOM `Range` or `StaticRange` object, change it
// into something that looks like a DOM `Selection` instead.
if (
native instanceof window.Range ||
(window.StaticRange && native instanceof window.StaticRange)
) {
native = {
anchorNode: native.startContainer,
anchorOffset: native.startOffset,
focusNode: native.endContainer,
focusOffset: native.endOffset,
}
}
const {
anchorNode,
anchorOffset,
focusNode,
focusOffset,
isCollapsed,
} = native
const { value } = editor
const anchor = findPoint(anchorNode, anchorOffset, editor)
const focus = isCollapsed ? anchor : findPoint(focusNode, focusOffset, editor)
if (!anchor || !focus) return null
// COMPAT: ??? The Edge browser seems to have a case where if you select the
// last word of a span, it sets the endContainer to the containing span.
// `selection-is-backward` doesn't handle this case.
if (IS_IE || IS_EDGE) {
const domAnchor = findDOMPoint(anchor)
const domFocus = findDOMPoint(focus)
native = {
anchorNode: domAnchor.node,
anchorOffset: domAnchor.offset,
focusNode: domFocus.node,
focusOffset: domFocus.offset,
}
}
const { document } = value
const range = document.createRange({
anchor,
focus,
})
return range
}
/**
* Export.
*
* @type {Function}
*/
export default findRange