forked from bschug/poedit
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.js
214 lines (182 loc) · 5.3 KB
/
utils.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
var StrUtils = {
// Checks if string haystack contains needle
contains: function (needle, haystack) {
return haystack.indexOf( needle ) > -1;
},
// Checks if str starts with prefix.
startsWith: function (str, prefix) {
return str.indexOf( prefix ) === 0;
},
// Alphabetically sorts all characters in the string.
// Characters must either be all uppercase or all lowercase.
// Does not take locale into account.
sortChars: function (str) {
return str.split('').sort().join('');
},
// Checks if string A consists only of the characters in string B
consistsOf: function (a, b) {
var validChars = b.split('');
return a.split('').every( function(c) { return validChars.indexOf(c) >= 0; } );
},
// Counts how often a character occurs in the string.
countChar: function (c, str) {
var count = 0;
for (var i=0; i < str.length; i++) {
if (str[i] === c) {
count++;
}
}
return count;
},
// Counts all chars in the string. Returns an object with char -> amount.
countChars: function (str) {
var result = { };
for (var i=0; i < str.length; i++) {
var c = str[i];
if (c in result) {
result[c]++;
}
else {
result[c] = 1;
}
}
return result;
},
ltrim: function (stringToTrim) {
return stringToTrim.replace(/^\s+/,"");
},
rtrim: function (stringToTrim) {
return stringToTrim.replace(/\s+$/,"");
},
replaceAll: function (str, old, replacement) {
return str.split( old ).join( replacement );
}
};
var ArrayUtils = {
//+ Jonas Raoni Soares Silva
//@ http://jsfromhell.com/array/shuffle [v1.0]
shuffle: function(o) {
for(var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
return o;
}
};
var DomUtils = {
endsWithBR: function (elem) {
if (elem.childNodes.length == 0) {
return false;
}
// look at child nodes, start at the end
for (var i = elem.childNodes.length - 1; i >= 0; i++) {
var child = elem.childNodes[i];
// skip comments
if (child.nodeType === 8) {
continue;
}
if (child.nodeType === 1) {
if (child.nodeName === 'BR') {
return true;
}
}
return false;
}
},
// Returns all text inside the given node(s).
// <br> elements and blocks like <div> appear as newlines in the text.
// This behaves similarly to the innerText property available in Chrome and IE.
getText: function (elem) {
return DomUtils._getText( elem.childNodes, '' );
},
_getText: function (elems, text) {
for (var i = 0; elems[i]; i++) {
var elem = elems[i];
// Get the text from Text and CDATA nodes
if (elem.nodeType === 3 || elem.nodeType === 4) {
text += elem.nodeValue;
}
// Special handling for certain elements:
else if (elem.nodeType === 1) {
// Insert newlines for <br> elements
if (elem.nodeName === 'BR') {
text += '\n';
continue;
}
// Ignore invisible elements
var style = window.getComputedStyle( elem );
if (style.display === 'none' || style.visibility === 'hidden') {
continue;
}
// Add newline before each block, unless we are already on a new line
// or this is the very first block in the list
if (style.display === 'block') {
if (text.length > 0 && text[text.length - 1] !== '\n') {
text += '\n';
}
}
// Traverse child nodes
text = DomUtils._getText( elem.childNodes, text );
// Add newline after each block unless there already is a new line.
if (style.display === 'block') {
if (text.length > 0 && text[text.length - 1] !== '\n') {
text += '\n';
}
}
}
// Traverse all other nodes, except for comments
else if ( elem.nodeType !== 8 ) {
text = DomUtils._getText( elem.childNodes, text );
}
}
return text;
},
setText: function (elem, text) {
// text = StrUtils.replaceAll( text, '\n', '<br>' );
var lines = StrUtils.replaceAll( text, ' ', ' ' ).split( '\n' );
DomUtils.removeAllChildren( elem );
for (var i=0; i < lines.length; i++) {
elem.appendChild( document.createTextNode( lines[i] ) );
if (i < lines.length - 1) {
elem.appendChild( document.createElement( 'br' ) );
}
}
},
// Returns the current selection in the given element.
// Selection is stored as character offsets.
saveSelection: function (element) {
return rangy.getSelection().saveCharacterRanges( element );
},
// Restores a saved selection on the given element.
// Selection is applied based on character counts.
// If text is inserted, you need to manually adjust the selection by providing an offset.
restoreSelection: function (element, selection, offset) {
if (selection !== null && selection.length > 0) {
selection[0].characterRange.start += offset;
selection[0].characterRange.end += offset;
}
rangy.getSelection().restoreCharacterRanges( element, selection );
},
removeAllChildren: function (elem) {
while (elem.lastChild) {
elem.removeChild( elem.lastChild );
}
}
};
var MathUtils = {
clamp: function (value, min, max) {
return Math.min( max, Math.max( min, value ) );
}
};
var StorageUtils = {
save: function (key, value) {
if (typeof(Storage) !== 'undefined') {
localStorage.setItem( key, value );
}
},
load: function (key, defaultValue) {
if (typeof(Storage) !== 'undefined') {
if (key in localStorage) {
return localStorage[key];
}
}
return defaultValue;
},
};