-
Notifications
You must be signed in to change notification settings - Fork 3
/
jquery.caret.js
120 lines (101 loc) · 3.91 KB
/
jquery.caret.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* https://github.com/garyharan/jQuery-caret-utilities
*
* Licensed under the incredibly permissive MIT License.
*/
(function($){
$.fn.insertAtCaret = function(text, opts) {
var element = $(this).get(0);
if (document.selection) {
element.focus();
var orig = element.value.replace(/\r\n/g, "\n");
var range = document.selection.createRange();
if (range.parentElement() != element) {
return false;
}
range.text = text;
var actual = tmp = element.value.replace(/\r\n/g, "\n");
for (var diff = 0; diff < orig.length; diff++) {
if (orig.charAt(diff) != actual.charAt(diff)) break;
}
for (var index = 0, start = 0; tmp.match(text) && (tmp = tmp.replace(text, "")) && index <= diff; index = start + text.length ) {
start = actual.indexOf(text, index);
}
} else if (typeof element.selectionStart !== 'undefined') {
var start = element.selectionStart;
var end = element.selectionEnd;
element.value = element.value.substr(0, start) + text + element.value.substr(end, element.value.length);
} else if (document.getSelection() && document.getSelection().anchorNode) {
// Selection of contenteditable elements (divs)
element.focus();
anchorNode = document.getSelection().anchorNode;
focusNode = document.getSelection().focusNode;
// Ignore selection over multiple nodes (TODO?)
if (! $(anchorNode).closest(element).length || anchorNode != focusNode) {
return false;
}
origContent = anchorNode.textContent;
anchorOffset = document.getSelection().anchorOffset || 0;
focusOffset = document.getSelection().focusOffset || 0;
if (anchorOffset == focusOffset) {
// No selection: insert at caret position
anchorNode.textContent = [origContent.slice(0, anchorOffset), text, origContent.slice(anchorOffset)].join('');
} else {
// Selection within the same node: replace selection
anchorNode.textContent = [origContent.slice(0, anchorOffset), text, origContent.slice(focusOffset)].join('');
}
// Don't need to position caret
return this;
}
if (typeof start !== 'undefined') {
setCaretTo(element, start + text.length);
} else {
element.value = text + element.value;
}
return this;
}
$.fn.setCaretPosition = function(start, end) {
var element = $(this).get(0);
element.focus();
setCaretTo(element, start, end);
return this;
}
$.fn.getCaretPosition = function() {
var element = $(this).get(0);
$(element).focus();
return getCaretPosition(element);
}
$.fn.getSelectedText = function() {
var element = $(this).get(0);
// workaround for firefox because window.getSelection does not work inside inputs
if (typeof element.selectionStart !== 'undefined') {
return $(element).val().substr(element.selectionStart, element.selectionEnd - element.selectionStart);
} else if (document.getSelection) {
return document.getSelection();
} else if (window.getSelection) {
return window.getSelection();
}
}
// privates
function setCaretTo(element, start, end) {
if (typeof element.createTextRange !== 'undefined') {
var range = element.createTextRange();
range.moveStart('character', start);
range.moveEnd('character', (end || start));
range.select();
} else if (typeof element.selectionStart !== 'undefined') {
element.focus();
element.setSelectionRange(start, (end || start));
}
}
function getCaretPosition(element) {
if (typeof element.selectionStart !== 'undefined') {
return element.selectionStart;
} else if (document.selection) {
var range = document.selection.createRange();
var rangeLength = range.text.length;
range.moveStart('character', -element.value.length);
return range.text.length - rangeLength;
}
}
})(jQuery);