forked from hasinhayder/javascript-text-expander
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtextexpander.js
117 lines (107 loc) · 4.39 KB
/
textexpander.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
var textExpander = function (textObjects, dictionary) {
"use strict";
if (!dictionary || !textObjects) {
return;
}
if (!(textObjects instanceof Array)) {
textObjects = [textObjects];
}
textObjects.forEach(function (textObject) {
if (textObject) {
textObject.removeEventListener("keydown", textExpanderEventListener); //remove duplicate event listener, if any
textObject.addEventListener("keydown", textExpanderEventListener);
textObject.removeEventListener("keyup", textHistoryEventListener); //remove duplicate event listener, if any
textObject.addEventListener("keyup", textHistoryEventListener);
}
});
function textExpanderEventListener(data) {
var actionKeys, dataKey;
if (data.key == undefined) {
dataKey = "r" + data.keyCode + "x"; // used "r" as a prefix and "x" as a suffix for creating unique
actionKeys = "r32xr188xr190xr49xr191xr186x"; // keyCode of " ,.!?;:" with prefix and suffix
} else {
dataKey = data.key;
actionKeys = " ,.!?;:";
}
if ((data.which == 90 || data.keyCode == 90) && (data.ctrlKey || data.metaKey) && this.dataset.lastReplaced && this.dataset.lastKeystroke) {
//ctrl+z and cmd+z
var regexp = new RegExp(dictionary[this.dataset.lastReplaced] + this.dataset.lastKeystroke + '$');
if (regexp.test(this.value)) {
data.preventDefault();
this.value = this.value.replace(regexp, this.dataset.lastReplaced + this.dataset.lastKeystroke);
}
delete this.dataset.lastReplaced;
delete this.dataset.lastKeystroke;
return;
}
if (actionKeys.indexOf(dataKey) !== -1) {
var selection = getCaretPosition(this);
var result = /\S+$/.exec(this.value.slice(0, selection.end));
if (result) {
var lastWord = result[0];
var selectionStart = result.input.length - lastWord.length;
replaceLastWord(this, selectionStart, result.input.length, lastWord);
}
}
}
function textHistoryEventListener(data) {
var actionKeys, dataKey;
if (data.key == undefined) {
dataKey = "r" + data.keyCode + "x"; // used "r" as a prefix and "x" as a suffix for creating unique
actionKeys = "r32xr188xr190xr49xr191xr186x"; // keyCode of " ,.!?;:" with prefix and suffix
} else {
dataKey = data.key;
actionKeys = " ,.!?;:";
}
if (actionKeys.indexOf(dataKey) !== -1) {
this.dataset.lastKeystroke = this.value.substr(-1);
}else{
delete this.dataset.lastReplaced;
}
}
function getCaretPosition(ctrl) {
var start, end;
if (ctrl.setSelectionRange) {
start = ctrl.selectionStart;
end = ctrl.selectionEnd;
} else if (document.selection && document.selection.createRange) {
var range = document.selection.createRange();
start = 0 - range.duplicate().moveStart('character', -100000);
end = start + range.text.length;
}
return {
start: start,
end: end
}
}
function replaceLastWord(ctrl, start, end, key) {
var isCap = key.toUpperCase() === key;
var rangeLength = end - start;
var replaceWith = dictionary[key.toLowerCase()];
if (!replaceWith) {
return;
}
if (ctrl.setSelectionRange) {
/* WebKit */
ctrl.focus();
ctrl.setSelectionRange(start, end);
}
else if (ctrl.createTextRange) {
/* IE */
var range = ctrl.createTextRange();
rangctrl.collapse(true);
rangctrl.moveEnd('character', end);
rangctrl.moveStart('character', start);
rangctrl.select();
}
else if (ctrl.selectionStart) {
ctrl.selectionStart = start;
ctrl.selectionEnd = end;
}
if (replaceWith) {
ctrl.value = ctrl.value.substring(0, start) + (isCap ? replaceWith.toUpperCase() : replaceWith) + ctrl.value.substr(end);
ctrl.setSelectionRange(end + replaceWith.length, end + replaceWith.length - (rangeLength));
ctrl.dataset.lastReplaced = key;
}
}
};