forked from bevacqua/insignia
-
Notifications
You must be signed in to change notification settings - Fork 0
/
selection.js
98 lines (81 loc) · 2.04 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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
'use strict';
var get = easyGet;
var set = easySet;
var inputTag = /input/i;
var textareaTag = /textarea/i;
if (document.selection && document.selection.createRange) {
get = hardGet;
set = hardSet;
}
function easyGet (el) {
return {
start: el.selectionStart,
end: el.selectionEnd
};
}
function hardGet (el) {
var active = document.activeElement;
if (active !== el) {
el.focus();
}
var range = document.selection.createRange();
var bookmark = range.getBookmark();
var original = el.value;
var marker = getUniqueMarker(original);
var parent = range.parentElement();
if (parent === null || !inputs(parent)) {
return result(0, 0);
}
range.text = marker + range.text + marker;
var contents = el.value;
el.value = original;
range.moveToBookmark(bookmark);
range.select();
return result(contents.indexOf(marker), contents.lastIndexOf(marker) - marker.length);
function result (start, end) {
if (active !== el) { // don't disrupt pre-existing state
if (active) {
active.focus();
} else {
el.blur();
}
}
return { start: start, end: end };
}
}
function getUniqueMarker (contents) {
var marker;
do {
marker = '@@marker.' + Math.random() * new Date();
} while (contents.indexOf(marker) !== -1);
return marker;
}
function inputs (el) {
return ((inputTag.test(el.tagName) && el.type === 'text') || textareaTag.test(el.tagName));
}
function easySet (el, p) {
el.selectionStart = special(el, p.start);
el.selectionEnd = special(el, p.end);
}
function hardSet (el, p) {
var range = el.createTextRange();
if (p.start === 'end' && p.end === 'end') {
range.collapse(false);
range.select();
} else {
range.collapse(true);
range.moveEnd('character', p.end);
range.moveStart('character', p.start);
range.select();
}
}
function special (el, value) {
return value === 'end' ? el.value.length : value || 0;
}
function selection (el, p) {
if (arguments.length === 2) {
set(el, p);
}
return get(el);
}
module.exports = selection;