forked from taruncx101/vue-text-selection
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathselection.js
68 lines (66 loc) · 1.99 KB
/
selection.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
const vueSelection = {
bind(el, binding, vnode) {
document.body.addEventListener('mouseup', handleMouseUp)
/**
* handle mouseup event on body
*/
function handleMouseUp(event) {
if (!el.parentElement) {
document.body.removeEventListener('mouseup', handleMouseUp)
return
}
var rtn = handleRange()
rtn.fixStr && binding.value.getSelection && binding.value.getSelection(rtn.fixStr, rtn.allStr, event)
}
/**
* handle range fix
*/
function handleRange() {
var selection = window.getSelection()
var rtn = {
allStr: '',
fixStr: ''
}
if (selection.rangeCount > 0) {
var range = selection.getRangeAt(0)
var region = document.createRange()
region.selectNode(el)
if (CheckIntersection(range, region)) {
rtn.allStr = range.toString()
if (binding.modifiers.fix) {
fixRange(range, region)
rtn.fixStr = range.toString()
} else {
var copyRange = range.cloneRange()
fixRange(copyRange, region)
rtn.fixStr = copyRange.toString()
copyRange.detach()
}
}
}
return rtn
}
/**
* check if the range intersects the region
* @param {*} range
* @param {*} region
*/
function CheckIntersection(range, region) {
return !(range.compareBoundaryPoints(Range.END_TO_START, region) > 0 || range.compareBoundaryPoints(Range.START_TO_END, region) < 0)
}
/**
* fix the range according to the region
* @param {*} range
* @param {*} region
*/
function fixRange(range, region) {
if (range.compareBoundaryPoints(Range.START_TO_START, region) < 0) {
range.setStart(region.startContainer, region.startOffset)
}
if (range.compareBoundaryPoints(Range.END_TO_END, region) > 0) {
range.setEnd(region.endContainer, region.endOffset)
}
}
}
}
export default vueSelection;