hlp 3.7.2 → 3.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/_js/_build/script.js +34 -27
- package/_js/script.js +3174 -0
- package/hlp.js +1 -2
- package/package.json +16 -7
package/_js/script.js
ADDED
|
@@ -0,0 +1,3174 @@
|
|
|
1
|
+
export default class hlp {
|
|
2
|
+
static x(input) {
|
|
3
|
+
if (typeof input === 'function') {
|
|
4
|
+
try {
|
|
5
|
+
input = input();
|
|
6
|
+
return this.x(input);
|
|
7
|
+
} catch (e) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
if (
|
|
12
|
+
input === null ||
|
|
13
|
+
input === false ||
|
|
14
|
+
(typeof input === 'string' && input.trim() == '') ||
|
|
15
|
+
(typeof input === 'object' && Object.keys(input).length === 0 && input.constructor === Object) ||
|
|
16
|
+
typeof input === 'undefined' ||
|
|
17
|
+
(Array.isArray(input) && input.length === 0) ||
|
|
18
|
+
(Array.isArray(input) && input.length === 1 && input[0] === '')
|
|
19
|
+
) {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
static nx(input) {
|
|
26
|
+
return !this.x(input);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static true(input) {
|
|
30
|
+
if (typeof input === 'function') {
|
|
31
|
+
try {
|
|
32
|
+
input = input();
|
|
33
|
+
return this.true(input);
|
|
34
|
+
} catch (e) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (input === undefined) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
if (input === null) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
if (input === false) {
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(input) && input.length === 0) {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
if (Array.isArray(input) && hlp.first(input) === '') {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (typeof input === 'object' && Object.keys(input).length === 0 && input.constructor === Object) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
if (input === 0) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
if (input === '0') {
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
if (input === '') {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
if (input === ' ') {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
if (input === 'null') {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
if (input === 'false') {
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
return true;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
static false(input) {
|
|
78
|
+
if (typeof input === 'function') {
|
|
79
|
+
try {
|
|
80
|
+
input = input();
|
|
81
|
+
return this.false(input);
|
|
82
|
+
} catch (e) {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (input === undefined) {
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
if (input === null) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
if (input === false) {
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
if (Array.isArray(input) && input.length === 0) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
if (Array.isArray(input) && hlp.first(input) === '') {
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
if (typeof input === 'object' && Object.keys(input).length === 0 && input.constructor === Object) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
if (input === 0) {
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
if (input === '0') {
|
|
108
|
+
return true;
|
|
109
|
+
}
|
|
110
|
+
if (input === '') {
|
|
111
|
+
return false;
|
|
112
|
+
}
|
|
113
|
+
if (input === ' ') {
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
if (input === 'null') {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
if (input === 'false') {
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static v() {
|
|
126
|
+
if (this.nx(arguments)) {
|
|
127
|
+
return '';
|
|
128
|
+
}
|
|
129
|
+
for (let i = 0; i < arguments.length; i++) {
|
|
130
|
+
if (this.x(arguments[i])) {
|
|
131
|
+
return arguments[i];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return '';
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
static loop(input, fun) {
|
|
138
|
+
if (this.nx(input)) {
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
if (Array.isArray(input)) {
|
|
142
|
+
input.forEach((input__value, input__key) => {
|
|
143
|
+
fun(input__value, input__key);
|
|
144
|
+
});
|
|
145
|
+
} else if (typeof input === 'object') {
|
|
146
|
+
Object.entries(input).forEach(([input__key, input__value]) => {
|
|
147
|
+
fun(input__value, input__key);
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
static map(obj, fn, ctx) {
|
|
153
|
+
return Object.keys(obj).reduce((a, b) => {
|
|
154
|
+
a[b] = fn.call(ctx || null, b, obj[b]);
|
|
155
|
+
return a;
|
|
156
|
+
}, {});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
static first(input) {
|
|
160
|
+
if (Array.isArray(input)) {
|
|
161
|
+
var ret = null;
|
|
162
|
+
input.forEach((input__value, input__key) => {
|
|
163
|
+
if (ret === null) {
|
|
164
|
+
ret = input__value;
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
return ret;
|
|
168
|
+
}
|
|
169
|
+
if (typeof input === 'object') {
|
|
170
|
+
var ret = null;
|
|
171
|
+
Object.entries(input).forEach(([input__key, input__value]) => {
|
|
172
|
+
if (ret === null) {
|
|
173
|
+
ret = input__value;
|
|
174
|
+
}
|
|
175
|
+
});
|
|
176
|
+
return ret;
|
|
177
|
+
}
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
static last(input) {
|
|
182
|
+
if (Array.isArray(input)) {
|
|
183
|
+
let ret = null;
|
|
184
|
+
input.forEach((input__value, input__key) => {
|
|
185
|
+
ret = input__value;
|
|
186
|
+
});
|
|
187
|
+
return ret;
|
|
188
|
+
}
|
|
189
|
+
if (typeof input === 'object') {
|
|
190
|
+
let ret = null;
|
|
191
|
+
Object.entries(input).forEach(([input__key, input__value]) => {
|
|
192
|
+
ret = input__value;
|
|
193
|
+
});
|
|
194
|
+
return ret;
|
|
195
|
+
}
|
|
196
|
+
return null;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
static rand(input) {
|
|
200
|
+
if (Array.isArray(input)) {
|
|
201
|
+
return input[Math.floor(Math.random() * input.length)];
|
|
202
|
+
}
|
|
203
|
+
if (typeof input === 'object') {
|
|
204
|
+
var input = Object.values(input);
|
|
205
|
+
return input[Math.floor(Math.random() * input.length)];
|
|
206
|
+
}
|
|
207
|
+
return null;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
static random_string(length = 8, chars = null) {
|
|
211
|
+
if (chars === null) {
|
|
212
|
+
chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
213
|
+
}
|
|
214
|
+
let chars_length = chars.length,
|
|
215
|
+
random_string = '';
|
|
216
|
+
for (let i = 0; i < length; i++) {
|
|
217
|
+
random_string += chars[~~(Math.random() * (chars_length - 1 - 0 + 1)) + 0];
|
|
218
|
+
}
|
|
219
|
+
return random_string;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
static round(value = 0, decimals = 0) {
|
|
223
|
+
return Number(Math.round(value + 'e' + decimals) + 'e-' + decimals);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
static isInteger(value) {
|
|
227
|
+
return !isNaN(value) && parseInt(Number(value)) == value && !isNaN(parseInt(value, 10));
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
static random_int(min = 0, max = 99999) {
|
|
231
|
+
if (!this.isInteger(min) || !this.isInteger(max)) {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
if (min > max) {
|
|
235
|
+
[min, max] = [max, min];
|
|
236
|
+
}
|
|
237
|
+
return ~~(Math.random() * (max - min + 1)) + min;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
static capitalize(string = null) {
|
|
241
|
+
if (string === null) {
|
|
242
|
+
return string;
|
|
243
|
+
}
|
|
244
|
+
if (string === '') {
|
|
245
|
+
return string;
|
|
246
|
+
}
|
|
247
|
+
return string.charAt(0).toUpperCase() + string.slice(1);
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
static cookieExists(cookie_name) {
|
|
251
|
+
if (document.cookie !== undefined && this.cookieGet(cookie_name) !== null) {
|
|
252
|
+
return true;
|
|
253
|
+
}
|
|
254
|
+
return false;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
static cookieGet(cookie_name) {
|
|
258
|
+
var cookie_match = document.cookie.match(new RegExp(cookie_name + '=([^;]+)'));
|
|
259
|
+
if (cookie_match) {
|
|
260
|
+
return decodeURIComponent(cookie_match[1]);
|
|
261
|
+
}
|
|
262
|
+
return null;
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
static cookieSet(cookie_name, cookie_value, days, full_domain = true) {
|
|
266
|
+
let samesite = '';
|
|
267
|
+
if (window.location.protocol.indexOf('https') > -1) {
|
|
268
|
+
samesite = '; SameSite=None; Secure';
|
|
269
|
+
}
|
|
270
|
+
document.cookie =
|
|
271
|
+
cookie_name +
|
|
272
|
+
'=' +
|
|
273
|
+
encodeURIComponent(cookie_value) +
|
|
274
|
+
'; ' +
|
|
275
|
+
'expires=' +
|
|
276
|
+
new Date(new Date().getTime() + days * 24 * 60 * 60 * 1000).toUTCString() +
|
|
277
|
+
'; path=/' +
|
|
278
|
+
samesite +
|
|
279
|
+
'; domain=' +
|
|
280
|
+
(full_domain === true ? this.urlHostTopLevel() : '');
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
static cookieDelete(cookie_name, full_domain = true) {
|
|
284
|
+
let samesite = '';
|
|
285
|
+
if (window.location.protocol.indexOf('https') > -1) {
|
|
286
|
+
samesite = '; SameSite=None; Secure';
|
|
287
|
+
}
|
|
288
|
+
document.cookie =
|
|
289
|
+
cookie_name +
|
|
290
|
+
'=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/' +
|
|
291
|
+
samesite +
|
|
292
|
+
'; domain=' +
|
|
293
|
+
(full_domain === true ? this.urlHostTopLevel() : '');
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
static localStorageSet(key, value, ttl = 0) {
|
|
297
|
+
ttl = ttl * (24 * 60 * 60 * 1000);
|
|
298
|
+
let now = new Date(),
|
|
299
|
+
item = {
|
|
300
|
+
value: value,
|
|
301
|
+
expiry: now.getTime() + ttl,
|
|
302
|
+
};
|
|
303
|
+
localStorage.setItem(key, JSON.stringify(item));
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
static localStorageGet(key) {
|
|
307
|
+
let itemStr = localStorage.getItem(key);
|
|
308
|
+
if (!itemStr) {
|
|
309
|
+
return null;
|
|
310
|
+
}
|
|
311
|
+
let item = JSON.parse(itemStr),
|
|
312
|
+
now = new Date();
|
|
313
|
+
if (now.getTime() > item.expiry) {
|
|
314
|
+
localStorage.removeItem(key);
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
return item.value;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
static localStorageDelete(key) {
|
|
321
|
+
localStorage.removeItem(key);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
static localStorageExists(key) {
|
|
325
|
+
return this.localStorageGet(key) !== null;
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
static getParam(variable) {
|
|
329
|
+
let url = window.location.search;
|
|
330
|
+
if (this.nx(url)) {
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
let query = url.substring(1),
|
|
334
|
+
vars = query.split('&');
|
|
335
|
+
for (var i = 0; i < vars.length; i++) {
|
|
336
|
+
var pair = vars[i].split('=');
|
|
337
|
+
if (pair[0] == variable && this.x(pair[1])) {
|
|
338
|
+
return pair[1];
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
static getDevice() {
|
|
345
|
+
if (this.isPhone()) {
|
|
346
|
+
return 'phone';
|
|
347
|
+
}
|
|
348
|
+
if (this.isTablet()) {
|
|
349
|
+
return 'tablet';
|
|
350
|
+
}
|
|
351
|
+
return 'desktop';
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
static isPhone() {
|
|
355
|
+
// based on detectmobilebrowsers.com
|
|
356
|
+
let a = navigator.userAgent || navigator.vendor || window.opera;
|
|
357
|
+
return (
|
|
358
|
+
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
|
|
359
|
+
a,
|
|
360
|
+
) ||
|
|
361
|
+
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
|
|
362
|
+
a.substr(0, 4),
|
|
363
|
+
)
|
|
364
|
+
);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
static isTablet() {
|
|
368
|
+
// based on detectmobilebrowsers.com
|
|
369
|
+
let a = navigator.userAgent || navigator.vendor || window.opera;
|
|
370
|
+
return (
|
|
371
|
+
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test(
|
|
372
|
+
a,
|
|
373
|
+
) ||
|
|
374
|
+
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
|
|
375
|
+
a.substr(0, 4),
|
|
376
|
+
)
|
|
377
|
+
);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
static isDesktop() {
|
|
381
|
+
return !this.isPhone() && !this.isTablet();
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
static isMobile() {
|
|
385
|
+
// viewport width based OR phone based
|
|
386
|
+
if (window.innerWidth < 750 || this.isPhone()) {
|
|
387
|
+
return true;
|
|
388
|
+
}
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
static isTouch() {
|
|
393
|
+
return 'ontouchstart' in window || navigator.maxTouchPoints || false;
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
static isPageSpeed() {
|
|
397
|
+
const ua = navigator.userAgent || '';
|
|
398
|
+
let score = 0;
|
|
399
|
+
|
|
400
|
+
if (/Lighthouse|HeadlessChrome|Chrome-Lighthouse|Speed Insights|PTST|PageSpeed/i.test(ua)) {
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
if (navigator.webdriver) {
|
|
405
|
+
return true;
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
if (!navigator.languages || navigator.languages.length === 0) {
|
|
409
|
+
score += 3;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (/moto g power|Moto G4/i.test(ua)) {
|
|
413
|
+
score += 2;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
if (/Chrome\/\d{3}\.0\.0\.0/i.test(ua)) {
|
|
417
|
+
score += 1;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (typeof window !== 'undefined') {
|
|
421
|
+
const w = window.innerWidth;
|
|
422
|
+
const h = window.innerHeight;
|
|
423
|
+
if ((w === 1350 && h === 940) || (w === 412 && (h === 823 || h === 915)) || (w === 360 && h === 640)) {
|
|
424
|
+
score += 2;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
if (navigator.plugins && navigator.plugins.length === 0) {
|
|
429
|
+
score += 1;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
if (!navigator.connection && !navigator.deviceMemory && !navigator.hardwareConcurrency) {
|
|
433
|
+
score += 1;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (typeof navigator.permissions === 'undefined') {
|
|
437
|
+
score += 1;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
if (/Chrome/i.test(ua) && typeof window.chrome === 'undefined') {
|
|
441
|
+
score += 2;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return score >= 4;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
static isMac() {
|
|
448
|
+
return hlp.getOs() === 'mac';
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
static isLinux() {
|
|
452
|
+
return hlp.getOs() === 'linux';
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
static isWindows() {
|
|
456
|
+
return hlp.getOs() === 'windows';
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
static getOs() {
|
|
460
|
+
let userAgent = window.navigator.userAgent,
|
|
461
|
+
platform = window.navigator.platform,
|
|
462
|
+
macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'],
|
|
463
|
+
windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'],
|
|
464
|
+
iosPlatforms = ['iPhone', 'iPad', 'iPod'],
|
|
465
|
+
os = 'unknown';
|
|
466
|
+
|
|
467
|
+
if (macosPlatforms.indexOf(platform) !== -1) {
|
|
468
|
+
os = 'mac';
|
|
469
|
+
} else if (iosPlatforms.indexOf(platform) !== -1) {
|
|
470
|
+
os = 'mac';
|
|
471
|
+
} else if (windowsPlatforms.indexOf(platform) !== -1) {
|
|
472
|
+
os = 'windows';
|
|
473
|
+
} else if (/Android/.test(userAgent)) {
|
|
474
|
+
os = 'linux';
|
|
475
|
+
} else if (/Linux/.test(platform)) {
|
|
476
|
+
os = 'linux';
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
return os;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
static getBrowser() {
|
|
483
|
+
let browser_name = '',
|
|
484
|
+
isIE = /*@cc_on!@*/ false || !!document.documentMode,
|
|
485
|
+
isEdge = !isIE && !!window.StyleMedia;
|
|
486
|
+
|
|
487
|
+
if (navigator.userAgent.indexOf('Opera') != -1 || navigator.userAgent.indexOf('OPR') != -1) {
|
|
488
|
+
browser_name = 'opera';
|
|
489
|
+
} else if (navigator.userAgent.indexOf('Chrome') != -1 && !isEdge) {
|
|
490
|
+
browser_name = 'chrome';
|
|
491
|
+
} else if (navigator.userAgent.indexOf('Safari') != -1 && !isEdge) {
|
|
492
|
+
browser_name = 'safari';
|
|
493
|
+
} else if (navigator.userAgent.indexOf('Firefox') != -1) {
|
|
494
|
+
browser_name = 'firefox';
|
|
495
|
+
} else if (navigator.userAgent.indexOf('MSIE') != -1 || !!document.documentMode == true) {
|
|
496
|
+
//IF IE > 10
|
|
497
|
+
browser_name = 'ie';
|
|
498
|
+
} else if (isEdge) {
|
|
499
|
+
browser_name = 'edge';
|
|
500
|
+
} else {
|
|
501
|
+
browser_name = 'unknown';
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
return browser_name;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
static isObject(a) {
|
|
508
|
+
return !!a && a.constructor === Object;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
static isArray(a) {
|
|
512
|
+
return !!a && a.constructor === Array;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
static isString(string) {
|
|
516
|
+
return typeof string === 'string' || string instanceof String;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
static isDate(string) {
|
|
520
|
+
if (this.nx(string)) {
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
// if string is of object date
|
|
524
|
+
if (Object.prototype.toString.call(string) === '[object Date]') {
|
|
525
|
+
return true;
|
|
526
|
+
}
|
|
527
|
+
// if this is not a string
|
|
528
|
+
if (!this.isString(string)) {
|
|
529
|
+
return false;
|
|
530
|
+
}
|
|
531
|
+
// strong check
|
|
532
|
+
if (string.split('-').length !== 3) {
|
|
533
|
+
return false;
|
|
534
|
+
}
|
|
535
|
+
let day = parseInt(string.split('-')[2]),
|
|
536
|
+
month = parseInt(string.split('-')[1]),
|
|
537
|
+
year = parseInt(string.split('-')[0]),
|
|
538
|
+
date = new Date();
|
|
539
|
+
date.setFullYear(year, month - 1, day);
|
|
540
|
+
if (date.getFullYear() == year && date.getMonth() + 1 == month && date.getDate() == day) {
|
|
541
|
+
return true;
|
|
542
|
+
}
|
|
543
|
+
return false;
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
static password_generate(length = 20, chars = ['a-z', 'A-Z', '0-9', '$!?'], exclude = 'lI') {
|
|
547
|
+
if (chars === null || !chars.length || length < chars.length) {
|
|
548
|
+
return null;
|
|
549
|
+
}
|
|
550
|
+
let charGroups = [];
|
|
551
|
+
for (let group of chars) {
|
|
552
|
+
let expanded = [];
|
|
553
|
+
if (group === 'a-z') {
|
|
554
|
+
expanded = Array.from({ length: 26 }, (_, i) => String.fromCharCode(97 + i));
|
|
555
|
+
} else if (group === 'A-Z') {
|
|
556
|
+
expanded = Array.from({ length: 26 }, (_, i) => String.fromCharCode(65 + i));
|
|
557
|
+
} else if (group === '0-9') {
|
|
558
|
+
expanded = Array.from({ length: 10 }, (_, i) => String.fromCharCode(48 + i));
|
|
559
|
+
} else {
|
|
560
|
+
expanded = group.split('');
|
|
561
|
+
}
|
|
562
|
+
if (exclude) {
|
|
563
|
+
expanded = expanded.filter((c) => !exclude.includes(c));
|
|
564
|
+
}
|
|
565
|
+
if (expanded.length === 0) {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
charGroups.push(expanded);
|
|
569
|
+
}
|
|
570
|
+
let passwordChars = charGroups.map((group) => group[Math.floor(Math.random() * group.length)]);
|
|
571
|
+
let allChars = charGroups.flat();
|
|
572
|
+
while (passwordChars.length < length) {
|
|
573
|
+
let i = Math.floor(Math.random() * allChars.length);
|
|
574
|
+
passwordChars.push(allChars[i]);
|
|
575
|
+
}
|
|
576
|
+
for (let i = passwordChars.length - 1; i > 0; i--) {
|
|
577
|
+
let j = Math.floor(Math.random() * (i + 1));
|
|
578
|
+
[passwordChars[i], passwordChars[j]] = [passwordChars[j], passwordChars[i]];
|
|
579
|
+
}
|
|
580
|
+
return passwordChars.join('');
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
static formatNumber(number, decimals = 0, dec_point = '.', thousands_sep = ',') {
|
|
584
|
+
number = (number + '').replace(/[^0-9+\-Ee.]/g, '');
|
|
585
|
+
var n = !isFinite(+number) ? 0 : +number,
|
|
586
|
+
prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
|
|
587
|
+
sep = typeof thousands_sep === 'undefined' ? ',' : thousands_sep,
|
|
588
|
+
dec = typeof dec_point === 'undefined' ? '.' : dec_point,
|
|
589
|
+
s = '',
|
|
590
|
+
toFixedFix = function (n, prec) {
|
|
591
|
+
var k = Math.pow(10, prec);
|
|
592
|
+
return '' + Math.round(n * k) / k;
|
|
593
|
+
};
|
|
594
|
+
s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
|
|
595
|
+
if (s[0].length > 3) {
|
|
596
|
+
s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
|
|
597
|
+
}
|
|
598
|
+
if ((s[1] || '').length < prec) {
|
|
599
|
+
s[1] = s[1] || '';
|
|
600
|
+
s[1] += new Array(prec - s[1].length + 1).join('0');
|
|
601
|
+
}
|
|
602
|
+
return s.join(dec);
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
static formatDate(format, date = null) {
|
|
606
|
+
if (date === false || date === true || date === null || date === '') {
|
|
607
|
+
date = new Date();
|
|
608
|
+
} else if (typeof date !== 'object') {
|
|
609
|
+
date = new Date(date.replace(/-/g, '/').replace(/T|Z/g, ' '));
|
|
610
|
+
}
|
|
611
|
+
let string = '',
|
|
612
|
+
mo = date.getMonth(),
|
|
613
|
+
m1 = mo + 1,
|
|
614
|
+
dow = date.getDay(),
|
|
615
|
+
d = date.getDate(),
|
|
616
|
+
y = date.getFullYear(),
|
|
617
|
+
h = date.getHours(),
|
|
618
|
+
mi = date.getMinutes(),
|
|
619
|
+
s = date.getSeconds();
|
|
620
|
+
|
|
621
|
+
for (let i = 0, len = format.length; i < len; i++) {
|
|
622
|
+
switch (format[i]) {
|
|
623
|
+
case 'j':
|
|
624
|
+
string += d;
|
|
625
|
+
break;
|
|
626
|
+
case 'd':
|
|
627
|
+
string += d < 10 ? '0' + d : d;
|
|
628
|
+
break;
|
|
629
|
+
case 'l':
|
|
630
|
+
let days = Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
|
|
631
|
+
string += days[dow];
|
|
632
|
+
break;
|
|
633
|
+
case 'w':
|
|
634
|
+
string += dow;
|
|
635
|
+
break;
|
|
636
|
+
case 'D':
|
|
637
|
+
days = Array('Sun', 'Mon', 'Tue', 'Wed', 'Thr', 'Fri', 'Sat');
|
|
638
|
+
string += days[dow];
|
|
639
|
+
break;
|
|
640
|
+
case 'm':
|
|
641
|
+
string += m1 < 10 ? '0' + m1 : m1;
|
|
642
|
+
break;
|
|
643
|
+
case 'n':
|
|
644
|
+
string += m1;
|
|
645
|
+
break;
|
|
646
|
+
case 'F':
|
|
647
|
+
let months = Array(
|
|
648
|
+
'January',
|
|
649
|
+
'February',
|
|
650
|
+
'March',
|
|
651
|
+
'April',
|
|
652
|
+
'May',
|
|
653
|
+
'June',
|
|
654
|
+
'July',
|
|
655
|
+
'August',
|
|
656
|
+
'September',
|
|
657
|
+
'October',
|
|
658
|
+
'November',
|
|
659
|
+
'December',
|
|
660
|
+
);
|
|
661
|
+
string += months[mo];
|
|
662
|
+
break;
|
|
663
|
+
case 'M':
|
|
664
|
+
months = Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
|
|
665
|
+
string += months[mo];
|
|
666
|
+
break;
|
|
667
|
+
case 'Y':
|
|
668
|
+
string += y;
|
|
669
|
+
break;
|
|
670
|
+
case 'y':
|
|
671
|
+
string += y.toString().slice(-2);
|
|
672
|
+
break;
|
|
673
|
+
case 'H':
|
|
674
|
+
string += h < 10 ? '0' + h : h;
|
|
675
|
+
break;
|
|
676
|
+
case 'g':
|
|
677
|
+
let hour = h === 0 ? 12 : h;
|
|
678
|
+
string += hour > 12 ? hour - 12 : hour;
|
|
679
|
+
break;
|
|
680
|
+
case 'h':
|
|
681
|
+
hour = h === 0 ? 12 : h;
|
|
682
|
+
hour = hour > 12 ? hour - 12 : hour;
|
|
683
|
+
string += hour < 10 ? '0' + hour : hour;
|
|
684
|
+
break;
|
|
685
|
+
case 'a':
|
|
686
|
+
string += h < 12 ? 'am' : 'pm';
|
|
687
|
+
break;
|
|
688
|
+
case 'i':
|
|
689
|
+
string += mi < 10 ? '0' + mi : mi;
|
|
690
|
+
break;
|
|
691
|
+
case 's':
|
|
692
|
+
string += s < 10 ? '0' + s : s;
|
|
693
|
+
break;
|
|
694
|
+
case 'c':
|
|
695
|
+
string += date.toISOString();
|
|
696
|
+
break;
|
|
697
|
+
default:
|
|
698
|
+
string += format[i];
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
return string;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
static deepCopy(obj, hash = new WeakMap()) {
|
|
706
|
+
if (Object(obj) !== obj) return obj; // primitives
|
|
707
|
+
if (hash.has(obj)) return hash.get(obj); // cyclic reference
|
|
708
|
+
const result =
|
|
709
|
+
obj instanceof Date
|
|
710
|
+
? new Date(obj)
|
|
711
|
+
: obj instanceof RegExp
|
|
712
|
+
? new RegExp(obj.source, obj.flags)
|
|
713
|
+
: obj.constructor
|
|
714
|
+
? new obj.constructor()
|
|
715
|
+
: Object.create(null);
|
|
716
|
+
hash.set(obj, result);
|
|
717
|
+
if (obj instanceof Map) Array.from(obj, ([key, val]) => result.set(key, hlp.deepCopy(val, hash)));
|
|
718
|
+
return Object.assign(result, ...Object.keys(obj).map((key) => ({ [key]: hlp.deepCopy(obj[key], hash) })));
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
static jsonStringToObject(string) {
|
|
722
|
+
if (this.nx(string) || !this.isString(string)) {
|
|
723
|
+
return null;
|
|
724
|
+
}
|
|
725
|
+
try {
|
|
726
|
+
return JSON.parse(string);
|
|
727
|
+
} catch (error) {
|
|
728
|
+
return null;
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
static isJsonString(string) {
|
|
733
|
+
if (this.nx(string) || !this.isString(string)) {
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
try {
|
|
737
|
+
let json = JSON.parse(string);
|
|
738
|
+
return true;
|
|
739
|
+
} catch (error) {
|
|
740
|
+
return false;
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
static jsonObjectToString(object) {
|
|
745
|
+
try {
|
|
746
|
+
return JSON.stringify(object);
|
|
747
|
+
} catch (error) {
|
|
748
|
+
return null;
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
static uuid() {
|
|
753
|
+
function s4() {
|
|
754
|
+
return Math.floor((1 + Math.random()) * 0x10000)
|
|
755
|
+
.toString(16)
|
|
756
|
+
.substring(1);
|
|
757
|
+
}
|
|
758
|
+
return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
static guid() {
|
|
762
|
+
return this.uuid();
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
static replaceAll(string, search, replace) {
|
|
766
|
+
return string.split(search).join(replace);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
static replaceLast(string, search, replace) {
|
|
770
|
+
let n = string.lastIndexOf(search);
|
|
771
|
+
string = string.slice(0, n) + string.slice(n).replace(search, replace);
|
|
772
|
+
return string;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
static replaceFirst(string, search, replace) {
|
|
776
|
+
return string.replace(search, replace);
|
|
777
|
+
}
|
|
778
|
+
|
|
779
|
+
static findAllPositions(searchStr, str) {
|
|
780
|
+
let searchStrLen = searchStr.length,
|
|
781
|
+
startIndex = 0,
|
|
782
|
+
index,
|
|
783
|
+
indices = [];
|
|
784
|
+
if (searchStrLen == 0) {
|
|
785
|
+
return [];
|
|
786
|
+
}
|
|
787
|
+
while ((index = str.indexOf(searchStr, startIndex)) > -1) {
|
|
788
|
+
indices.push(index);
|
|
789
|
+
startIndex = index + searchStrLen;
|
|
790
|
+
}
|
|
791
|
+
return indices;
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
static findAllPositionsCaseInsensitive(searchStr, str) {
|
|
795
|
+
let searchStrLen = searchStr.length,
|
|
796
|
+
startIndex = 0,
|
|
797
|
+
index,
|
|
798
|
+
indices = [];
|
|
799
|
+
if (searchStrLen == 0) {
|
|
800
|
+
return [];
|
|
801
|
+
}
|
|
802
|
+
while ((index = this.indexOfCaseInsensitive(searchStr, str, startIndex)) > -1) {
|
|
803
|
+
indices.push(index);
|
|
804
|
+
startIndex = index + searchStrLen;
|
|
805
|
+
}
|
|
806
|
+
return indices;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
static countAllOccurences(value, str) {
|
|
810
|
+
let regExp = new RegExp(value, 'g');
|
|
811
|
+
return (str.match(regExp) || []).length;
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
static countAllOccurencesCaseInsensitive(value, str) {
|
|
815
|
+
let regExp = new RegExp(value, 'gi');
|
|
816
|
+
return (str.match(regExp) || []).length;
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
static indexOfCaseInsensitive(searchStr, str, offset) {
|
|
820
|
+
return str.toLowerCase().indexOf(searchStr.toLowerCase(), offset);
|
|
821
|
+
}
|
|
822
|
+
|
|
823
|
+
static highlight(string, query, strip = false, strip_length = 500) {
|
|
824
|
+
if (this.nx(string) || this.nx(query)) {
|
|
825
|
+
return string;
|
|
826
|
+
}
|
|
827
|
+
if (strip === true) {
|
|
828
|
+
let dots = '...';
|
|
829
|
+
// get all query begin positions in spot
|
|
830
|
+
let positions = this.findAllPositionsCaseInsensitive(query, string);
|
|
831
|
+
// strip away parts
|
|
832
|
+
let words = string.split(' ');
|
|
833
|
+
let i = 0;
|
|
834
|
+
words.forEach((words__value, words__key) => {
|
|
835
|
+
let strip_now = true;
|
|
836
|
+
positions.forEach((positions__value) => {
|
|
837
|
+
if (
|
|
838
|
+
i >= positions__value - strip_length &&
|
|
839
|
+
i <= positions__value + query.length + strip_length - 1
|
|
840
|
+
) {
|
|
841
|
+
strip_now = false;
|
|
842
|
+
}
|
|
843
|
+
});
|
|
844
|
+
if (strip_now === true) {
|
|
845
|
+
words[words__key] = dots;
|
|
846
|
+
}
|
|
847
|
+
i += words__value.length + 1;
|
|
848
|
+
});
|
|
849
|
+
string = words.join(' ');
|
|
850
|
+
while (string.indexOf(dots + ' ' + dots) > -1) {
|
|
851
|
+
string = this.replaceAll(string, dots + ' ' + dots, dots);
|
|
852
|
+
}
|
|
853
|
+
string = string.trim();
|
|
854
|
+
}
|
|
855
|
+
// again: get all query begin positions in spot
|
|
856
|
+
let positions = this.findAllPositionsCaseInsensitive(query, string);
|
|
857
|
+
// wrap span element around them
|
|
858
|
+
let wrap_begin = '<strong class="highlight">';
|
|
859
|
+
let wrap_end = '</strong>';
|
|
860
|
+
for (let x = 0; x < positions.length; x++) {
|
|
861
|
+
string =
|
|
862
|
+
string.substring(0, positions[x]) +
|
|
863
|
+
wrap_begin +
|
|
864
|
+
string.substring(positions[x], positions[x] + query.length) +
|
|
865
|
+
wrap_end +
|
|
866
|
+
string.substring(positions[x] + query.length);
|
|
867
|
+
// shift other positions
|
|
868
|
+
for (let y = x + 1; y < positions.length; y++) {
|
|
869
|
+
positions[y] = positions[y] + wrap_begin.length + wrap_end.length;
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
return string;
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
static get(url, args = null) {
|
|
876
|
+
return this.call('GET', url, args);
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
static post(url, args = null) {
|
|
880
|
+
return this.call('POST', url, args);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
static call(method, url, args = null) {
|
|
884
|
+
if (args === null) {
|
|
885
|
+
args = {};
|
|
886
|
+
}
|
|
887
|
+
if (!('data' in args)) {
|
|
888
|
+
args.data = {};
|
|
889
|
+
}
|
|
890
|
+
if (!('headers' in args)) {
|
|
891
|
+
args.headers = null;
|
|
892
|
+
}
|
|
893
|
+
if (!('throttle' in args)) {
|
|
894
|
+
args.throttle = 0;
|
|
895
|
+
}
|
|
896
|
+
if (!('allow_errors' in args)) {
|
|
897
|
+
args.allow_errors = true;
|
|
898
|
+
}
|
|
899
|
+
return new Promise((resolve, reject) => {
|
|
900
|
+
setTimeout(() => {
|
|
901
|
+
if (url.indexOf('http') !== 0) {
|
|
902
|
+
url = hlp.baseUrl() + '/' + url;
|
|
903
|
+
}
|
|
904
|
+
let xhr = new XMLHttpRequest();
|
|
905
|
+
xhr.open(method, url, true);
|
|
906
|
+
if (method === 'POST') {
|
|
907
|
+
if (
|
|
908
|
+
'data' in args &&
|
|
909
|
+
args.data !== null &&
|
|
910
|
+
typeof args.data === 'object' &&
|
|
911
|
+
!(args.data instanceof FormData)
|
|
912
|
+
) {
|
|
913
|
+
xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8');
|
|
914
|
+
args.data = JSON.stringify(args.data);
|
|
915
|
+
}
|
|
916
|
+
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
|
917
|
+
}
|
|
918
|
+
if (this.x(args.headers)) {
|
|
919
|
+
Object.entries(args.headers).forEach(([headers__key, headers__value]) => {
|
|
920
|
+
xhr.setRequestHeader(headers__key, headers__value);
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
xhr.onload = () => {
|
|
924
|
+
if (xhr.readyState != 4 || (args.allow_errors !== true && xhr.status != 200 && xhr.status != 304)) {
|
|
925
|
+
if (this.isJsonString(xhr.responseText)) {
|
|
926
|
+
reject(this.jsonStringToObject(xhr.responseText));
|
|
927
|
+
} else {
|
|
928
|
+
reject(xhr.responseText);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
if (this.isJsonString(xhr.responseText)) {
|
|
932
|
+
resolve(this.jsonStringToObject(xhr.responseText));
|
|
933
|
+
} else {
|
|
934
|
+
resolve(xhr.responseText);
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
xhr.onerror = () => {
|
|
938
|
+
reject([xhr.readyState, xhr.status, xhr.statusText]);
|
|
939
|
+
};
|
|
940
|
+
if (method === 'GET') {
|
|
941
|
+
xhr.send(null);
|
|
942
|
+
}
|
|
943
|
+
if (method === 'POST') {
|
|
944
|
+
xhr.send(args.data);
|
|
945
|
+
}
|
|
946
|
+
}, args.throttle);
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
static onResizeHorizontal(fun) {
|
|
951
|
+
let windowWidth = window.innerWidth,
|
|
952
|
+
windowWidthNew,
|
|
953
|
+
timeout;
|
|
954
|
+
window.addEventListener('resize', () => {
|
|
955
|
+
windowWidthNew = window.innerWidth;
|
|
956
|
+
if (windowWidthNew != windowWidth) {
|
|
957
|
+
windowWidth = windowWidthNew;
|
|
958
|
+
if (timeout) {
|
|
959
|
+
clearTimeout(timeout);
|
|
960
|
+
}
|
|
961
|
+
timeout = window.setTimeout(() => {
|
|
962
|
+
fun();
|
|
963
|
+
}, 50);
|
|
964
|
+
}
|
|
965
|
+
});
|
|
966
|
+
fun();
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
static onResizeVertical(fun) {
|
|
970
|
+
var windowHeight = window.innerHeight,
|
|
971
|
+
windowHeightNew,
|
|
972
|
+
timeout;
|
|
973
|
+
window.addEventListener('resize', () => {
|
|
974
|
+
windowHeightNew = window.innerHeight;
|
|
975
|
+
if (windowHeightNew != windowHeight) {
|
|
976
|
+
windowHeight = windowHeightNew;
|
|
977
|
+
if (timeout) {
|
|
978
|
+
clearTimeout(timeout);
|
|
979
|
+
}
|
|
980
|
+
timeout = window.setTimeout(() => {
|
|
981
|
+
fun();
|
|
982
|
+
}, 50);
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
fun();
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
static removeEmpty(array) {
|
|
989
|
+
if (this.nx(array) || !Array.isArray(array)) {
|
|
990
|
+
return array;
|
|
991
|
+
}
|
|
992
|
+
array = array.filter((array__value) => {
|
|
993
|
+
return this.x(array__value);
|
|
994
|
+
});
|
|
995
|
+
return array;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
static uniqueArray(array) {
|
|
999
|
+
let seen = {},
|
|
1000
|
+
ret_arr = [];
|
|
1001
|
+
for (let i = 0; i < array.length; i++) {
|
|
1002
|
+
if (!(array[i] in seen)) {
|
|
1003
|
+
ret_arr.push(array[i]);
|
|
1004
|
+
seen[array[i]] = true;
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
return ret_arr;
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
static powerset(array) {
|
|
1011
|
+
if (!Array.isArray(array)) {
|
|
1012
|
+
return array;
|
|
1013
|
+
}
|
|
1014
|
+
return array.reduce((subsets, value) => subsets.concat(subsets.map((set) => [...set, value])), [[]]);
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
static charToInt(val) {
|
|
1018
|
+
val = val.toUpperCase();
|
|
1019
|
+
let base = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
|
|
1020
|
+
i,
|
|
1021
|
+
j,
|
|
1022
|
+
result = 0;
|
|
1023
|
+
for (i = 0, j = val.length - 1; i < val.length; i += 1, j -= 1) {
|
|
1024
|
+
result += Math.pow(base.length, j) * (base.indexOf(val[i]) + 1);
|
|
1025
|
+
}
|
|
1026
|
+
return result;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
static intToChar(num) {
|
|
1030
|
+
for (var ret = '', a = 1, b = 26; (num -= a) >= 0; a = b, b *= 26) {
|
|
1031
|
+
ret = String.fromCharCode(parseInt((num % b) / a) + 65) + ret;
|
|
1032
|
+
}
|
|
1033
|
+
return ret;
|
|
1034
|
+
}
|
|
1035
|
+
|
|
1036
|
+
static slugify(text) {
|
|
1037
|
+
return text
|
|
1038
|
+
.toString()
|
|
1039
|
+
.toLowerCase()
|
|
1040
|
+
.trim()
|
|
1041
|
+
.split('ä')
|
|
1042
|
+
.join('ae')
|
|
1043
|
+
.split('ö')
|
|
1044
|
+
.join('oe')
|
|
1045
|
+
.split('ü')
|
|
1046
|
+
.join('ue')
|
|
1047
|
+
.split('ß')
|
|
1048
|
+
.join('ss')
|
|
1049
|
+
.replace(/[^\w\s-]/g, '') // remove non-word [a-z0-9_], non-whitespace, non-hyphen characters
|
|
1050
|
+
.replace(/[\s_-]+/g, '-') // swap any length of whitespace, underscore, hyphen characters with a single -
|
|
1051
|
+
.replace(/^-+|-+$/g, ''); // remove leading, trailing -
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
static incChar(char, shift = 1) {
|
|
1055
|
+
return this.intToChar(this.charToInt(char) + shift);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
static decChar(char, shift = 1) {
|
|
1059
|
+
return this.intToChar(this.charToInt(char) - shift);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
static range(start, end) {
|
|
1063
|
+
let range = [],
|
|
1064
|
+
typeofStart = typeof start,
|
|
1065
|
+
typeofEnd = typeof end,
|
|
1066
|
+
step = 1;
|
|
1067
|
+
if (typeofStart == 'undefined' || typeofEnd == 'undefined' || typeofStart != typeofEnd) {
|
|
1068
|
+
return null;
|
|
1069
|
+
}
|
|
1070
|
+
if (end < start) {
|
|
1071
|
+
step = -step;
|
|
1072
|
+
}
|
|
1073
|
+
if (typeofStart == 'number') {
|
|
1074
|
+
while (step > 0 ? end >= start : end <= start) {
|
|
1075
|
+
range.push(start);
|
|
1076
|
+
start += step;
|
|
1077
|
+
}
|
|
1078
|
+
} else if (typeofStart == 'string') {
|
|
1079
|
+
if (start.length != 1 || end.length != 1) {
|
|
1080
|
+
return null;
|
|
1081
|
+
}
|
|
1082
|
+
start = start.charCodeAt(0);
|
|
1083
|
+
end = end.charCodeAt(0);
|
|
1084
|
+
while (step > 0 ? end >= start : end <= start) {
|
|
1085
|
+
range.push(String.fromCharCode(start));
|
|
1086
|
+
start += step;
|
|
1087
|
+
}
|
|
1088
|
+
} else {
|
|
1089
|
+
return null;
|
|
1090
|
+
}
|
|
1091
|
+
return range;
|
|
1092
|
+
}
|
|
1093
|
+
|
|
1094
|
+
static dateToWeek(d = null) {
|
|
1095
|
+
if (d === null) {
|
|
1096
|
+
d = new Date();
|
|
1097
|
+
}
|
|
1098
|
+
d = new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate()));
|
|
1099
|
+
d.setUTCDate(d.getUTCDate() + 4 - (d.getUTCDay() || 7));
|
|
1100
|
+
let yearStart = new Date(Date.UTC(d.getUTCFullYear(), 0, 1)),
|
|
1101
|
+
weekNo = Math.ceil(((d - yearStart) / 86400000 + 1) / 7);
|
|
1102
|
+
return weekNo;
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
static weekToDate(week, year) {
|
|
1106
|
+
if (year == null) {
|
|
1107
|
+
year = new Date().getFullYear();
|
|
1108
|
+
}
|
|
1109
|
+
let date = new Date();
|
|
1110
|
+
date.setYear(year);
|
|
1111
|
+
date.setDate(1);
|
|
1112
|
+
date.setMonth(0);
|
|
1113
|
+
date.setHours(0);
|
|
1114
|
+
date.setMinutes(0);
|
|
1115
|
+
date.setSeconds(0);
|
|
1116
|
+
date.setMilliseconds(0);
|
|
1117
|
+
let FIRST_DAY_OF_WEEK = 1;
|
|
1118
|
+
let WEEK_LENGTH = 7;
|
|
1119
|
+
let day = date.getDay();
|
|
1120
|
+
day = day === 0 ? 7 : day;
|
|
1121
|
+
let dayOffset = -day + FIRST_DAY_OF_WEEK;
|
|
1122
|
+
if (WEEK_LENGTH - day + 1 < 4) {
|
|
1123
|
+
dayOffset += WEEK_LENGTH;
|
|
1124
|
+
}
|
|
1125
|
+
date = new Date(date.getTime() + dayOffset * 24 * 60 * 60 * 1000);
|
|
1126
|
+
let weekTime = 1000 * 60 * 60 * 24 * 7 * (week - 1);
|
|
1127
|
+
let targetTime = date.getTime() + weekTime;
|
|
1128
|
+
date.setTime(targetTime);
|
|
1129
|
+
date.setHours(0);
|
|
1130
|
+
date.setMinutes(0);
|
|
1131
|
+
date.setSeconds(0);
|
|
1132
|
+
date.setMilliseconds(0);
|
|
1133
|
+
return date;
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
static addDays(date, days) {
|
|
1137
|
+
var result = new Date(date);
|
|
1138
|
+
result.setDate(result.getDate() + days);
|
|
1139
|
+
return result;
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
static diffInMonths(date1, date2) {
|
|
1143
|
+
let d1 = new Date(date1),
|
|
1144
|
+
d2 = new Date(date2),
|
|
1145
|
+
yearDiff = d2.getFullYear() - d1.getFullYear(),
|
|
1146
|
+
monthDiff = d2.getMonth() - d1.getMonth(),
|
|
1147
|
+
dayDiff = d2.getDate() - d1.getDate(),
|
|
1148
|
+
daysInMonth = new Date(d2.getFullYear(), d2.getMonth() + 1, 0).getDate(),
|
|
1149
|
+
months = yearDiff * 12 + monthDiff + dayDiff / daysInMonth;
|
|
1150
|
+
return months;
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
static objectsAreEqual(x, y) {
|
|
1154
|
+
var _this = this;
|
|
1155
|
+
if (x === null || x === undefined || y === null || y === undefined) {
|
|
1156
|
+
return x === y;
|
|
1157
|
+
}
|
|
1158
|
+
if (x.constructor !== y.constructor) {
|
|
1159
|
+
return false;
|
|
1160
|
+
}
|
|
1161
|
+
if (x instanceof Function) {
|
|
1162
|
+
return x === y;
|
|
1163
|
+
}
|
|
1164
|
+
if (x instanceof RegExp) {
|
|
1165
|
+
return x === y;
|
|
1166
|
+
}
|
|
1167
|
+
if (x === y || x.valueOf() === y.valueOf()) {
|
|
1168
|
+
return true;
|
|
1169
|
+
}
|
|
1170
|
+
if (Array.isArray(x) && x.length !== y.length) {
|
|
1171
|
+
return false;
|
|
1172
|
+
}
|
|
1173
|
+
if (x instanceof Date) {
|
|
1174
|
+
return false;
|
|
1175
|
+
}
|
|
1176
|
+
if (!(x instanceof Object)) {
|
|
1177
|
+
return false;
|
|
1178
|
+
}
|
|
1179
|
+
if (!(y instanceof Object)) {
|
|
1180
|
+
return false;
|
|
1181
|
+
}
|
|
1182
|
+
var p = Object.keys(x);
|
|
1183
|
+
return (
|
|
1184
|
+
Object.keys(y).every(function (i) {
|
|
1185
|
+
return p.indexOf(i) !== -1;
|
|
1186
|
+
}) &&
|
|
1187
|
+
p.every(function (i) {
|
|
1188
|
+
return _this.objectsAreEqual(x[i], y[i]);
|
|
1189
|
+
})
|
|
1190
|
+
);
|
|
1191
|
+
}
|
|
1192
|
+
|
|
1193
|
+
static containsObject(obj, list) {
|
|
1194
|
+
var x;
|
|
1195
|
+
for (x in list) {
|
|
1196
|
+
if (list.hasOwnProperty(x) && this.objectsAreEqual(list[x], obj)) {
|
|
1197
|
+
return true;
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
return false;
|
|
1201
|
+
}
|
|
1202
|
+
|
|
1203
|
+
static fadeOut(el, speed = 1000) {
|
|
1204
|
+
if (speed <= 25) {
|
|
1205
|
+
speed = 25;
|
|
1206
|
+
}
|
|
1207
|
+
return new Promise((resolve) => {
|
|
1208
|
+
el.style.opacity = 1;
|
|
1209
|
+
(function fade() {
|
|
1210
|
+
if ((el.style.opacity -= 25 / speed) < 0) {
|
|
1211
|
+
el.style.display = 'none';
|
|
1212
|
+
resolve();
|
|
1213
|
+
} else {
|
|
1214
|
+
requestAnimationFrame(fade);
|
|
1215
|
+
}
|
|
1216
|
+
})();
|
|
1217
|
+
});
|
|
1218
|
+
}
|
|
1219
|
+
|
|
1220
|
+
static fadeIn(el, speed = 1000) {
|
|
1221
|
+
if (speed <= 25) {
|
|
1222
|
+
speed = 25;
|
|
1223
|
+
}
|
|
1224
|
+
return new Promise((resolve) => {
|
|
1225
|
+
el.style.opacity = 0;
|
|
1226
|
+
el.style.display = 'block';
|
|
1227
|
+
(function fade() {
|
|
1228
|
+
var val = parseFloat(el.style.opacity);
|
|
1229
|
+
if (!((val += 25 / speed) > 1)) {
|
|
1230
|
+
el.style.opacity = val;
|
|
1231
|
+
requestAnimationFrame(fade);
|
|
1232
|
+
} else {
|
|
1233
|
+
resolve();
|
|
1234
|
+
}
|
|
1235
|
+
})();
|
|
1236
|
+
});
|
|
1237
|
+
}
|
|
1238
|
+
|
|
1239
|
+
static scrollTop() {
|
|
1240
|
+
let doc = document.documentElement;
|
|
1241
|
+
return (window.pageYOffset || doc.scrollTop) - (doc.clientTop || 0);
|
|
1242
|
+
}
|
|
1243
|
+
|
|
1244
|
+
static scrollLeft() {
|
|
1245
|
+
let doc = document.documentElement;
|
|
1246
|
+
return (window.pageXOffset || doc.scrollLeft) - (doc.clientLeft || 0);
|
|
1247
|
+
}
|
|
1248
|
+
|
|
1249
|
+
static closestScrollable(node) {
|
|
1250
|
+
let isElement = node instanceof HTMLElement,
|
|
1251
|
+
overflowY = isElement && window.getComputedStyle(node).overflowY,
|
|
1252
|
+
isScrollable = overflowY && !(overflowY.includes('hidden') || overflowY.includes('visible'));
|
|
1253
|
+
if (!node) {
|
|
1254
|
+
return null;
|
|
1255
|
+
} else if (isScrollable && node.scrollHeight >= node.clientHeight) {
|
|
1256
|
+
return node;
|
|
1257
|
+
}
|
|
1258
|
+
return this.closestScrollable(node.parentNode) || document.scrollingElement || document.body;
|
|
1259
|
+
}
|
|
1260
|
+
|
|
1261
|
+
static offsetTop(el) {
|
|
1262
|
+
return el.getBoundingClientRect().top + window.pageYOffset - document.documentElement.clientTop;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
static offsetLeft(el) {
|
|
1266
|
+
return el.getBoundingClientRect().left + window.pageXOffset - document.documentElement.clientLeft;
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1269
|
+
static offsetRight(el) {
|
|
1270
|
+
return (
|
|
1271
|
+
el.getBoundingClientRect().left + window.pageXOffset - document.documentElement.clientLeft + el.offsetWidth
|
|
1272
|
+
);
|
|
1273
|
+
}
|
|
1274
|
+
|
|
1275
|
+
static offsetBottom(el) {
|
|
1276
|
+
return (
|
|
1277
|
+
el.getBoundingClientRect().top + window.pageYOffset - document.documentElement.clientTop + el.offsetHeight
|
|
1278
|
+
);
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
static offsetTopWithMargin(el) {
|
|
1282
|
+
return this.offsetTop(el) - parseInt(getComputedStyle(el).marginTop);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
static offsetLeftWithMargin(el) {
|
|
1286
|
+
return this.offsetLeft(el) - parseInt(getComputedStyle(el).marginLeft);
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
static offsetRightWithMargin(el) {
|
|
1290
|
+
return this.offsetRight(el) + parseInt(getComputedStyle(el).marginRight);
|
|
1291
|
+
}
|
|
1292
|
+
|
|
1293
|
+
static offsetBottomWithMargin(el) {
|
|
1294
|
+
return this.offsetBottom(el) + parseInt(getComputedStyle(el).marginBottom);
|
|
1295
|
+
}
|
|
1296
|
+
|
|
1297
|
+
static documentHeight() {
|
|
1298
|
+
return Math.max(
|
|
1299
|
+
document.body.offsetHeight,
|
|
1300
|
+
document.body.scrollHeight,
|
|
1301
|
+
document.documentElement.clientHeight,
|
|
1302
|
+
document.documentElement.offsetHeight,
|
|
1303
|
+
document.documentElement.scrollHeight,
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
static documentWidth() {
|
|
1308
|
+
return document.documentElement.clientWidth || document.body.clientWidth;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
static windowWidth() {
|
|
1312
|
+
return window.innerWidth;
|
|
1313
|
+
}
|
|
1314
|
+
static windowHeight() {
|
|
1315
|
+
return window.innerHeight;
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
static windowWidthWithoutScrollbar() {
|
|
1319
|
+
return document.documentElement.clientWidth || document.body.clientWidth;
|
|
1320
|
+
}
|
|
1321
|
+
static windowHeightWithoutScrollbar() {
|
|
1322
|
+
return document.documentElement.clientHeight || document.body.clientHeight;
|
|
1323
|
+
}
|
|
1324
|
+
|
|
1325
|
+
static outerWidthWithMargin(el) {
|
|
1326
|
+
return el.offsetWidth + parseInt(getComputedStyle(el).marginLeft) + parseInt(getComputedStyle(el).marginRight);
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1329
|
+
static outerHeightWithMargin(el) {
|
|
1330
|
+
return el.offsetHeight + parseInt(getComputedStyle(el).marginTop) + parseInt(getComputedStyle(el).marginBottom);
|
|
1331
|
+
}
|
|
1332
|
+
|
|
1333
|
+
static async cursorPosition() {
|
|
1334
|
+
// https://stackoverflow.com/a/43326327/2068362
|
|
1335
|
+
document.head.insertAdjacentHTML(
|
|
1336
|
+
'afterbegin',
|
|
1337
|
+
`
|
|
1338
|
+
<style type="text/css">
|
|
1339
|
+
.find-pointer-quad {
|
|
1340
|
+
--hit: 0;
|
|
1341
|
+
position: fixed;
|
|
1342
|
+
z-index:2147483647;
|
|
1343
|
+
transform: translateZ(0);
|
|
1344
|
+
&:hover { --hit: 1; }
|
|
1345
|
+
}
|
|
1346
|
+
</style>
|
|
1347
|
+
`,
|
|
1348
|
+
);
|
|
1349
|
+
|
|
1350
|
+
window.cursorPositionDelay = 50;
|
|
1351
|
+
window.cursorPositionQuads = [];
|
|
1352
|
+
|
|
1353
|
+
let dim = 10;
|
|
1354
|
+
let createQuad = (_, pos) => {
|
|
1355
|
+
let a = document.createElement('a');
|
|
1356
|
+
a.classList.add('find-pointer-quad');
|
|
1357
|
+
|
|
1358
|
+
let { style } = a;
|
|
1359
|
+
style.top = pos < 2 ? 0 : `${dim}%`;
|
|
1360
|
+
style.left = pos % 2 === 0 ? 0 : `${dim}%`;
|
|
1361
|
+
style.width = style.height = `${dim}%`;
|
|
1362
|
+
document.body.appendChild(a);
|
|
1363
|
+
return a;
|
|
1364
|
+
};
|
|
1365
|
+
window.cursorPositionQuads = [1, 2, 3, 4].map(createQuad);
|
|
1366
|
+
|
|
1367
|
+
return this.cursorPositionBisect(dim);
|
|
1368
|
+
}
|
|
1369
|
+
|
|
1370
|
+
static cursorPositionBisect(dim) {
|
|
1371
|
+
let hit;
|
|
1372
|
+
window.cursorPositionQuads.some((a) => {
|
|
1373
|
+
let style = getComputedStyle(a);
|
|
1374
|
+
let result = style.getPropertyValue(`--hit`);
|
|
1375
|
+
if (result === `1`) return (hit = { style, a });
|
|
1376
|
+
});
|
|
1377
|
+
|
|
1378
|
+
if (!hit) {
|
|
1379
|
+
let [q1] = window.cursorPositionQuads;
|
|
1380
|
+
let reset = Math.abs(dim) > 10000;
|
|
1381
|
+
let top = parseFloat(q1.style.top) - dim / 2;
|
|
1382
|
+
let left = parseFloat(q1.style.left) - dim / 2;
|
|
1383
|
+
window.cursorPositionQuads.forEach(({ style }, pos) => {
|
|
1384
|
+
if (reset) {
|
|
1385
|
+
style.top = pos < 2 ? 0 : `${dim}%`;
|
|
1386
|
+
style.left = pos % 2 === 0 ? 0 : `${dim}%`;
|
|
1387
|
+
style.width = style.height = `${dim}%`;
|
|
1388
|
+
} else {
|
|
1389
|
+
style.top = pos < 2 ? `${top}%` : `${top + dim}%`;
|
|
1390
|
+
style.left = pos % 2 === 0 ? `${left}%` : `${left + dim}%`;
|
|
1391
|
+
style.width = `${dim}%`;
|
|
1392
|
+
style.height = `${dim}%`;
|
|
1393
|
+
}
|
|
1394
|
+
});
|
|
1395
|
+
return new Promise((resolve) => {
|
|
1396
|
+
setTimeout(
|
|
1397
|
+
() => resolve(this.cursorPositionBisect(!reset ? 2 * dim : dim)),
|
|
1398
|
+
window.cursorPositionDelay,
|
|
1399
|
+
);
|
|
1400
|
+
});
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
let { style, a } = hit;
|
|
1404
|
+
let { top, left, width, height } = a.getBoundingClientRect();
|
|
1405
|
+
if (width < 3) {
|
|
1406
|
+
window.cursorPositionQuads.forEach((a) => a.remove());
|
|
1407
|
+
return {
|
|
1408
|
+
x: Math.round(left + width / 2 + window.scrollX),
|
|
1409
|
+
y: Math.round(top + height / 2 + window.scrollY),
|
|
1410
|
+
};
|
|
1411
|
+
}
|
|
1412
|
+
|
|
1413
|
+
let ox = a.style.left;
|
|
1414
|
+
let oy = a.style.top;
|
|
1415
|
+
let nextStep = dim / 2;
|
|
1416
|
+
window.cursorPositionQuads.forEach(({ style }, pos) => {
|
|
1417
|
+
style.top = pos < 2 ? oy : `${nextStep + parseFloat(oy)}%`;
|
|
1418
|
+
style.left = pos % 2 === 0 ? ox : `${nextStep + parseFloat(ox)}%`;
|
|
1419
|
+
style.width = `${nextStep}%`;
|
|
1420
|
+
style.height = `${nextStep}%`;
|
|
1421
|
+
});
|
|
1422
|
+
|
|
1423
|
+
return new Promise((resolve) => {
|
|
1424
|
+
setTimeout(() => resolve(this.cursorPositionBisect(nextStep)), window.cursorPositionDelay);
|
|
1425
|
+
});
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
static scrollTo(to, duration = 1000, element = null, offset = 0, only_up = false) {
|
|
1429
|
+
return new Promise((resolve) => {
|
|
1430
|
+
if (element === null) {
|
|
1431
|
+
element = document.scrollingElement || document.documentElement;
|
|
1432
|
+
}
|
|
1433
|
+
if (!hlp.isNumeric(to)) {
|
|
1434
|
+
if (element === (document.scrollingElement || documentElement)) {
|
|
1435
|
+
to = this.offsetTopWithMargin(to);
|
|
1436
|
+
} else {
|
|
1437
|
+
to =
|
|
1438
|
+
to.getBoundingClientRect().top -
|
|
1439
|
+
parseInt(getComputedStyle(to).marginTop) -
|
|
1440
|
+
(element.getBoundingClientRect().top -
|
|
1441
|
+
element.scrollTop -
|
|
1442
|
+
parseInt(getComputedStyle(element).marginTop));
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
let offset_calc = 0;
|
|
1446
|
+
if (!Array.isArray(offset)) {
|
|
1447
|
+
offset = [offset];
|
|
1448
|
+
}
|
|
1449
|
+
offset.forEach((offset__value) => {
|
|
1450
|
+
if (hlp.isNumeric(offset__value)) {
|
|
1451
|
+
offset_calc += offset__value;
|
|
1452
|
+
} else {
|
|
1453
|
+
if (offset__value !== null) {
|
|
1454
|
+
if (window.getComputedStyle(offset__value).position === 'fixed') {
|
|
1455
|
+
offset_calc += -1 * offset__value.offsetHeight;
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1460
|
+
to += offset_calc;
|
|
1461
|
+
const start = element.scrollTop,
|
|
1462
|
+
change = to - start,
|
|
1463
|
+
startDate = +new Date(),
|
|
1464
|
+
// t = current time
|
|
1465
|
+
// b = start value
|
|
1466
|
+
// c = change in value
|
|
1467
|
+
// d = duration
|
|
1468
|
+
easeInOutQuad = function (t, b, c, d) {
|
|
1469
|
+
t /= d / 2;
|
|
1470
|
+
if (t < 1) return (c / 2) * t * t + b;
|
|
1471
|
+
t--;
|
|
1472
|
+
return (-c / 2) * (t * (t - 2) - 1) + b;
|
|
1473
|
+
},
|
|
1474
|
+
easeInOutCirc = function (t, b, c, d) {
|
|
1475
|
+
t /= d / 2;
|
|
1476
|
+
if (t < 1) return (-c / 2) * (Math.sqrt(1 - t * t) - 1) + b;
|
|
1477
|
+
t -= 2;
|
|
1478
|
+
return (c / 2) * (Math.sqrt(1 - t * t) + 1) + b;
|
|
1479
|
+
},
|
|
1480
|
+
animateScroll = function () {
|
|
1481
|
+
const currentDate = +new Date();
|
|
1482
|
+
const currentTime = currentDate - startDate;
|
|
1483
|
+
element.scrollTop = parseInt(easeInOutCirc(currentTime, start, change, duration));
|
|
1484
|
+
if (currentTime < duration) {
|
|
1485
|
+
requestAnimationFrame(animateScroll);
|
|
1486
|
+
} else {
|
|
1487
|
+
element.scrollTop = to;
|
|
1488
|
+
resolve();
|
|
1489
|
+
}
|
|
1490
|
+
};
|
|
1491
|
+
if (only_up === true && change > 0) {
|
|
1492
|
+
resolve();
|
|
1493
|
+
return;
|
|
1494
|
+
}
|
|
1495
|
+
animateScroll();
|
|
1496
|
+
});
|
|
1497
|
+
}
|
|
1498
|
+
|
|
1499
|
+
static loadJs(urls) {
|
|
1500
|
+
if (!hlp.isArray(urls)) {
|
|
1501
|
+
urls = [urls];
|
|
1502
|
+
}
|
|
1503
|
+
let promises = [];
|
|
1504
|
+
hlp.loop(urls, (urls__value, urls__key) => {
|
|
1505
|
+
promises.push(
|
|
1506
|
+
new Promise((resolve, reject) => {
|
|
1507
|
+
let script = document.createElement('script');
|
|
1508
|
+
script.src = urls__value;
|
|
1509
|
+
script.onload = () => {
|
|
1510
|
+
resolve();
|
|
1511
|
+
};
|
|
1512
|
+
document.head.appendChild(script);
|
|
1513
|
+
}),
|
|
1514
|
+
);
|
|
1515
|
+
});
|
|
1516
|
+
return Promise.all(promises);
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
static async loadJsSequentially(urls) {
|
|
1520
|
+
if (!hlp.isArray(urls)) {
|
|
1521
|
+
urls = [urls];
|
|
1522
|
+
}
|
|
1523
|
+
for (let urls__value of urls) {
|
|
1524
|
+
await hlp.loadJs(urls__value);
|
|
1525
|
+
}
|
|
1526
|
+
return;
|
|
1527
|
+
}
|
|
1528
|
+
|
|
1529
|
+
static triggerAfterAllImagesLoaded(selectorContainer, selectorImage, fn) {
|
|
1530
|
+
window.addEventListener('load', (e) => {
|
|
1531
|
+
if (document.querySelector(selectorContainer + ' ' + selectorImage) !== null) {
|
|
1532
|
+
document.querySelectorAll(selectorContainer + ' ' + selectorImage).forEach((el) => {
|
|
1533
|
+
this.triggerAfterAllImagesLoadedBindLoadEvent(el, selectorContainer, selectorImage, fn);
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
});
|
|
1537
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
1538
|
+
if (document.querySelector(selectorContainer) !== null) {
|
|
1539
|
+
new MutationObserver((mutations) => {
|
|
1540
|
+
mutations.forEach((mutation) => {
|
|
1541
|
+
if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
|
|
1542
|
+
mutation.addedNodes.forEach((el) => {
|
|
1543
|
+
this.triggerAfterAllImagesLoadedHandleEl(el, selectorContainer, selectorImage, fn);
|
|
1544
|
+
});
|
|
1545
|
+
} else if (
|
|
1546
|
+
mutation.type === 'attributes' &&
|
|
1547
|
+
mutation.attributeName === 'src' &&
|
|
1548
|
+
mutation.target.classList.contains(selectorImage.replace('.', '')) &&
|
|
1549
|
+
mutation.oldValue !== mutation.target.getAttribute('src')
|
|
1550
|
+
) {
|
|
1551
|
+
this.triggerAfterAllImagesLoadedHandleEl(
|
|
1552
|
+
mutation.target,
|
|
1553
|
+
selectorContainer,
|
|
1554
|
+
selectorImage,
|
|
1555
|
+
fn,
|
|
1556
|
+
);
|
|
1557
|
+
}
|
|
1558
|
+
});
|
|
1559
|
+
}).observe(document.querySelector(selectorContainer), {
|
|
1560
|
+
attributes: true,
|
|
1561
|
+
childList: true,
|
|
1562
|
+
characterData: false,
|
|
1563
|
+
subtree: true,
|
|
1564
|
+
attributeOldValue: true,
|
|
1565
|
+
characterDataOldValue: false,
|
|
1566
|
+
});
|
|
1567
|
+
}
|
|
1568
|
+
});
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
static triggerAfterAllImagesLoadedHandleEl(el, selectorContainer, selectorImage, fn) {
|
|
1572
|
+
if (el.nodeType === Node.ELEMENT_NODE) {
|
|
1573
|
+
el.classList.remove('loaded-img');
|
|
1574
|
+
el.closest(selectorContainer).classList.remove('loaded-all');
|
|
1575
|
+
// only bind if not yet binded
|
|
1576
|
+
if (!el.classList.contains('binded-trigger')) {
|
|
1577
|
+
el.classList.add('binded-trigger');
|
|
1578
|
+
el.addEventListener('load', () => {
|
|
1579
|
+
this.triggerAfterAllImagesLoadedBindLoadEvent(el, selectorContainer, selectorImage, fn);
|
|
1580
|
+
});
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
static triggerAfterAllImagesLoadedBindLoadEvent(el, selectorContainer, selectorImage, fn) {
|
|
1586
|
+
el.classList.add('loaded-img');
|
|
1587
|
+
if (
|
|
1588
|
+
el.closest(selectorContainer).querySelectorAll('.loaded-img').length ===
|
|
1589
|
+
el.closest(selectorContainer).querySelectorAll(selectorImage).length
|
|
1590
|
+
) {
|
|
1591
|
+
el.closest(selectorContainer).classList.add('loaded-all');
|
|
1592
|
+
fn();
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
static isVisible(el) {
|
|
1597
|
+
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
static isVisibleInViewport(el) {
|
|
1601
|
+
if (!this.isVisible(el)) {
|
|
1602
|
+
return false;
|
|
1603
|
+
}
|
|
1604
|
+
let rect = el.getBoundingClientRect();
|
|
1605
|
+
return !(rect.bottom < 0 || rect.right < 0 || rect.left > window.innerWidth || rect.top > window.innerHeight);
|
|
1606
|
+
}
|
|
1607
|
+
|
|
1608
|
+
static textareaAutoHeight(selector = 'textarea') {
|
|
1609
|
+
this.textareaSetHeights(selector);
|
|
1610
|
+
|
|
1611
|
+
this.onResizeHorizontal(() => {
|
|
1612
|
+
this.textareaSetHeights(selector);
|
|
1613
|
+
});
|
|
1614
|
+
|
|
1615
|
+
[].forEach.call(document.querySelectorAll(selector), (el) => {
|
|
1616
|
+
el.addEventListener('keyup', (e) => {
|
|
1617
|
+
this.textareaSetHeight(e.target);
|
|
1618
|
+
});
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
|
|
1622
|
+
static textareaSetHeights(selector = 'textarea') {
|
|
1623
|
+
[].forEach.call(document.querySelectorAll(selector), (el) => {
|
|
1624
|
+
if (this.isVisible(el)) {
|
|
1625
|
+
this.textareaSetHeight(el);
|
|
1626
|
+
}
|
|
1627
|
+
});
|
|
1628
|
+
}
|
|
1629
|
+
|
|
1630
|
+
static textareaSetHeight(el) {
|
|
1631
|
+
el.style.height = '5px';
|
|
1632
|
+
el.style.height = el.scrollHeight + 'px';
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1635
|
+
static real100vh(selector = null, percent = 100) {
|
|
1636
|
+
if (selector === null) {
|
|
1637
|
+
// apply trick from https://css-tricks.com/the-trick-to-viewport-units-on-mobile/
|
|
1638
|
+
let fn = () => {
|
|
1639
|
+
let vh = window.innerHeight * 0.01;
|
|
1640
|
+
document.documentElement.style.setProperty('--vh', `${vh}px`);
|
|
1641
|
+
};
|
|
1642
|
+
fn();
|
|
1643
|
+
window.addEventListener('resize', () => {
|
|
1644
|
+
fn();
|
|
1645
|
+
});
|
|
1646
|
+
} else {
|
|
1647
|
+
let fn = () => {
|
|
1648
|
+
console.log(selector);
|
|
1649
|
+
if (document.querySelector(selector) !== null) {
|
|
1650
|
+
document.querySelectorAll(selector).forEach((selector__value) => {
|
|
1651
|
+
selector__value.style.height = window.innerHeight * (percent / 100) + 'px';
|
|
1652
|
+
});
|
|
1653
|
+
}
|
|
1654
|
+
};
|
|
1655
|
+
fn();
|
|
1656
|
+
window.addEventListener('resize', () => {
|
|
1657
|
+
fn();
|
|
1658
|
+
});
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1662
|
+
static iOsRemoveHover() {
|
|
1663
|
+
if (hlp.getBrowser() === 'safari' && hlp.getDevice() !== 'desktop') {
|
|
1664
|
+
hlp.on('touchend', 'a', (e, el) => {
|
|
1665
|
+
el.click();
|
|
1666
|
+
});
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
|
|
1670
|
+
static isNumeric(n) {
|
|
1671
|
+
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
1672
|
+
}
|
|
1673
|
+
|
|
1674
|
+
static animate(el, from, to, easing, duration) {
|
|
1675
|
+
return new Promise((resolve) => {
|
|
1676
|
+
// on durations smaller than 50, the end event does not trigger!
|
|
1677
|
+
if (duration <= 50) {
|
|
1678
|
+
duration = 50;
|
|
1679
|
+
}
|
|
1680
|
+
let properties = [];
|
|
1681
|
+
from.split(';').forEach((from__value) => {
|
|
1682
|
+
properties.push(from__value.split(':')[0].trim());
|
|
1683
|
+
});
|
|
1684
|
+
let transition = [];
|
|
1685
|
+
properties.forEach((properties__value) => {
|
|
1686
|
+
transition.push(properties__value + ' ' + Math.round((duration / 1000) * 10) / 10 + 's ' + easing);
|
|
1687
|
+
});
|
|
1688
|
+
transition = 'transition: ' + transition.join(', ') + ' !important;';
|
|
1689
|
+
|
|
1690
|
+
let els = null;
|
|
1691
|
+
if (NodeList.prototype.isPrototypeOf(el)) {
|
|
1692
|
+
els = Array.from(el);
|
|
1693
|
+
} else if (el === null) {
|
|
1694
|
+
console.log('cannot animate element from ' + from + ' to ' + to + ' because it does not exist');
|
|
1695
|
+
resolve();
|
|
1696
|
+
} else {
|
|
1697
|
+
els = [el];
|
|
1698
|
+
}
|
|
1699
|
+
|
|
1700
|
+
let toFinish = els.length;
|
|
1701
|
+
|
|
1702
|
+
els.forEach((els__value, els__key) => {
|
|
1703
|
+
// add random class
|
|
1704
|
+
let random_class = hlp.random_string(10, 'abcdefghijklmnopqrstuvwxyz');
|
|
1705
|
+
els__value.classList.add(random_class);
|
|
1706
|
+
|
|
1707
|
+
window.requestAnimationFrame(() => {
|
|
1708
|
+
// set from style inline (don't fully remove previous style)
|
|
1709
|
+
let new_style = [];
|
|
1710
|
+
let prev_style = els__value.getAttribute('style');
|
|
1711
|
+
if (prev_style !== null) {
|
|
1712
|
+
prev_style.split(';').forEach((prev_style__value) => {
|
|
1713
|
+
if (
|
|
1714
|
+
prev_style__value != '' &&
|
|
1715
|
+
!properties.includes(prev_style__value.split(':')[0].trim())
|
|
1716
|
+
) {
|
|
1717
|
+
new_style.push(prev_style__value);
|
|
1718
|
+
}
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
if (new_style.length > 0) {
|
|
1722
|
+
new_style = new_style.join(';') + ';' + from + ';';
|
|
1723
|
+
} else {
|
|
1724
|
+
new_style = from + ';';
|
|
1725
|
+
}
|
|
1726
|
+
els__value.setAttribute('style', new_style);
|
|
1727
|
+
|
|
1728
|
+
window.requestAnimationFrame(() => {
|
|
1729
|
+
// add transition property
|
|
1730
|
+
let style = document.createElement('style');
|
|
1731
|
+
style.innerHTML = '.' + random_class + ' { ' + transition + ' }';
|
|
1732
|
+
document.head.appendChild(style);
|
|
1733
|
+
|
|
1734
|
+
window.requestAnimationFrame(() => {
|
|
1735
|
+
// set last style inline
|
|
1736
|
+
els__value.setAttribute(
|
|
1737
|
+
'style',
|
|
1738
|
+
els__value.getAttribute('style').replace(from + ';', '') + to + ';',
|
|
1739
|
+
);
|
|
1740
|
+
|
|
1741
|
+
if (this.isVisible(els__value)) {
|
|
1742
|
+
let fired = false;
|
|
1743
|
+
|
|
1744
|
+
hlp.addEventListenerOnce(els__value, 'transitionend', (event) => {
|
|
1745
|
+
fired = true;
|
|
1746
|
+
|
|
1747
|
+
// transitionend fires also, when animating child elements
|
|
1748
|
+
// the following line ensures, that those events do not bubble up
|
|
1749
|
+
// in that case, we return false and ensure, the event listener is still alive
|
|
1750
|
+
if (event.target !== event.currentTarget) {
|
|
1751
|
+
return false;
|
|
1752
|
+
}
|
|
1753
|
+
|
|
1754
|
+
// remove previous styles property
|
|
1755
|
+
if (document.head.contains(style)) {
|
|
1756
|
+
document.head.removeChild(style);
|
|
1757
|
+
}
|
|
1758
|
+
|
|
1759
|
+
// remove random class
|
|
1760
|
+
els__value.classList.remove(random_class);
|
|
1761
|
+
|
|
1762
|
+
// resolve promise when last is finished
|
|
1763
|
+
toFinish--;
|
|
1764
|
+
if (toFinish <= 0) {
|
|
1765
|
+
window.requestAnimationFrame(() => {
|
|
1766
|
+
resolve();
|
|
1767
|
+
});
|
|
1768
|
+
}
|
|
1769
|
+
});
|
|
1770
|
+
|
|
1771
|
+
// safeguard
|
|
1772
|
+
// in some edge cases, transitionend does not fire
|
|
1773
|
+
setTimeout(() => {
|
|
1774
|
+
if (fired === false) {
|
|
1775
|
+
if (document.head.contains(style)) {
|
|
1776
|
+
document.head.removeChild(style);
|
|
1777
|
+
}
|
|
1778
|
+
els__value.classList.remove(random_class);
|
|
1779
|
+
toFinish--;
|
|
1780
|
+
if (toFinish <= 0) {
|
|
1781
|
+
resolve();
|
|
1782
|
+
}
|
|
1783
|
+
}
|
|
1784
|
+
}, duration * 1.5);
|
|
1785
|
+
} else {
|
|
1786
|
+
if (document.head.contains(style)) {
|
|
1787
|
+
document.head.removeChild(style);
|
|
1788
|
+
}
|
|
1789
|
+
els__value.classList.remove(random_class);
|
|
1790
|
+
toFinish--;
|
|
1791
|
+
if (toFinish <= 0) {
|
|
1792
|
+
resolve();
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
});
|
|
1796
|
+
});
|
|
1797
|
+
});
|
|
1798
|
+
});
|
|
1799
|
+
});
|
|
1800
|
+
}
|
|
1801
|
+
|
|
1802
|
+
static addEventListenerOnce(target, type, listener, addOptions, removeOptions) {
|
|
1803
|
+
target.addEventListener(type, function fn(event) {
|
|
1804
|
+
let result = listener.apply(this, arguments, addOptions);
|
|
1805
|
+
if (result !== false) {
|
|
1806
|
+
target.removeEventListener(type, fn, removeOptions);
|
|
1807
|
+
}
|
|
1808
|
+
});
|
|
1809
|
+
}
|
|
1810
|
+
|
|
1811
|
+
static htmlDecode(value) {
|
|
1812
|
+
let tmp = document.createElement('textarea');
|
|
1813
|
+
tmp.innerHTML = value;
|
|
1814
|
+
return tmp.value;
|
|
1815
|
+
}
|
|
1816
|
+
|
|
1817
|
+
static htmlEncode(value) {
|
|
1818
|
+
return value
|
|
1819
|
+
.replace(/&/g, '&')
|
|
1820
|
+
.replace(/</g, '<')
|
|
1821
|
+
.replace(/>/g, '>')
|
|
1822
|
+
.replace(/"/g, '"')
|
|
1823
|
+
.replace(/'/g, ''')
|
|
1824
|
+
.replace(/`/g, '`');
|
|
1825
|
+
}
|
|
1826
|
+
|
|
1827
|
+
static nl2br(str) {
|
|
1828
|
+
if (typeof str === 'undefined' || str === null) {
|
|
1829
|
+
return '';
|
|
1830
|
+
}
|
|
1831
|
+
let breakTag = '<br/>',
|
|
1832
|
+
replaceStr = '$1' + breakTag;
|
|
1833
|
+
return (str + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, replaceStr);
|
|
1834
|
+
}
|
|
1835
|
+
|
|
1836
|
+
static br2nl(str) {
|
|
1837
|
+
if (typeof str === 'undefined' || str === null) {
|
|
1838
|
+
return '';
|
|
1839
|
+
}
|
|
1840
|
+
let replaceStr = '\n';
|
|
1841
|
+
return str.replace(/<\s*\/?br\s*[\/]?>/gi, replaceStr);
|
|
1842
|
+
}
|
|
1843
|
+
|
|
1844
|
+
static closest(el, selector) {
|
|
1845
|
+
if (!document.documentElement.contains(el)) {
|
|
1846
|
+
return null;
|
|
1847
|
+
}
|
|
1848
|
+
do {
|
|
1849
|
+
if (this.matches(el, selector)) {
|
|
1850
|
+
return el;
|
|
1851
|
+
}
|
|
1852
|
+
el = el.parentElement || el.parentNode;
|
|
1853
|
+
} while (el !== null && el.nodeType === 1);
|
|
1854
|
+
return null;
|
|
1855
|
+
}
|
|
1856
|
+
|
|
1857
|
+
static matches(el, selector) {
|
|
1858
|
+
let node = el,
|
|
1859
|
+
nodes = (node.parentNode || node.document).querySelectorAll(selector),
|
|
1860
|
+
i = -1;
|
|
1861
|
+
while (nodes[++i] && nodes[i] != node);
|
|
1862
|
+
return !!nodes[i];
|
|
1863
|
+
}
|
|
1864
|
+
|
|
1865
|
+
static wrap(el, html) {
|
|
1866
|
+
if (el === null) {
|
|
1867
|
+
return;
|
|
1868
|
+
}
|
|
1869
|
+
let wrapper = new DOMParser().parseFromString(html, 'text/html').body.childNodes[0];
|
|
1870
|
+
el.parentNode.insertBefore(wrapper, el.nextSibling);
|
|
1871
|
+
wrapper.appendChild(el);
|
|
1872
|
+
}
|
|
1873
|
+
|
|
1874
|
+
static wrapTextNodes(el, tag) {
|
|
1875
|
+
if (el === null) {
|
|
1876
|
+
return;
|
|
1877
|
+
}
|
|
1878
|
+
Array.from(el.childNodes)
|
|
1879
|
+
.filter((node) => node.nodeType === 3 && node.textContent.trim().length > 1)
|
|
1880
|
+
.forEach((node) => {
|
|
1881
|
+
const wrapper = document.createElement(tag);
|
|
1882
|
+
node.after(wrapper);
|
|
1883
|
+
wrapper.appendChild(node);
|
|
1884
|
+
});
|
|
1885
|
+
}
|
|
1886
|
+
|
|
1887
|
+
static html2dom(html) {
|
|
1888
|
+
let template = document.createElement('template');
|
|
1889
|
+
html = html.trim();
|
|
1890
|
+
template.innerHTML = html;
|
|
1891
|
+
if (template.content === undefined) {
|
|
1892
|
+
return this.html2domLegacy(html);
|
|
1893
|
+
}
|
|
1894
|
+
return template.content.firstChild;
|
|
1895
|
+
}
|
|
1896
|
+
|
|
1897
|
+
static html2domLegacy(html) {
|
|
1898
|
+
/* source: https://gist.github.com/Munawwar/6e6362dbdf77c7865a99 */
|
|
1899
|
+
var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
|
|
1900
|
+
rtagName = /<([\w:]+)/,
|
|
1901
|
+
rhtml = /<|&#?\w+;/,
|
|
1902
|
+
wrapMap = {
|
|
1903
|
+
option: [1, "<select multiple='multiple'>", '</select>'],
|
|
1904
|
+
thead: [1, '<table>', '</table>'],
|
|
1905
|
+
col: [2, '<table><colgroup>', '</colgroup></table>'],
|
|
1906
|
+
tr: [2, '<table><tbody>', '</tbody></table>'],
|
|
1907
|
+
td: [3, '<table><tbody><tr>', '</tr></tbody></table>'],
|
|
1908
|
+
_default: [0, '', ''],
|
|
1909
|
+
},
|
|
1910
|
+
context = document;
|
|
1911
|
+
var tmp,
|
|
1912
|
+
tag,
|
|
1913
|
+
wrap,
|
|
1914
|
+
j,
|
|
1915
|
+
fragment = context.createDocumentFragment();
|
|
1916
|
+
if (!rhtml.test(html)) {
|
|
1917
|
+
fragment.appendChild(context.createTextNode(html));
|
|
1918
|
+
} else {
|
|
1919
|
+
tmp = fragment.appendChild(context.createElement('div'));
|
|
1920
|
+
tag = (rtagName.exec(html) || ['', ''])[1].toLowerCase();
|
|
1921
|
+
wrap = wrapMap[tag] || wrapMap._default;
|
|
1922
|
+
tmp.innerHTML = wrap[1] + html.replace(rxhtmlTag, '<$1></$2>') + wrap[2];
|
|
1923
|
+
j = wrap[0];
|
|
1924
|
+
while (j--) {
|
|
1925
|
+
tmp = tmp.lastChild;
|
|
1926
|
+
}
|
|
1927
|
+
fragment.removeChild(fragment.firstChild);
|
|
1928
|
+
while (tmp.firstChild) {
|
|
1929
|
+
fragment.appendChild(tmp.firstChild);
|
|
1930
|
+
}
|
|
1931
|
+
}
|
|
1932
|
+
return fragment.querySelector('*');
|
|
1933
|
+
}
|
|
1934
|
+
|
|
1935
|
+
static prev(elem, filter) {
|
|
1936
|
+
let prev = elem.previousElementSibling;
|
|
1937
|
+
if (prev === null) {
|
|
1938
|
+
return null;
|
|
1939
|
+
}
|
|
1940
|
+
if (filter === undefined || this.matches(prev, filter)) {
|
|
1941
|
+
return prev;
|
|
1942
|
+
}
|
|
1943
|
+
return null;
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
static next(elem, filter) {
|
|
1947
|
+
let next = elem.nextElementSibling;
|
|
1948
|
+
if (next === null) {
|
|
1949
|
+
return null;
|
|
1950
|
+
}
|
|
1951
|
+
if (filter === undefined || this.matches(next, filter)) {
|
|
1952
|
+
return next;
|
|
1953
|
+
}
|
|
1954
|
+
return null;
|
|
1955
|
+
}
|
|
1956
|
+
|
|
1957
|
+
static prevAll(elem, filter) {
|
|
1958
|
+
let sibs = [];
|
|
1959
|
+
while ((elem = elem.previousElementSibling)) {
|
|
1960
|
+
if (filter === undefined || this.matches(elem, filter)) {
|
|
1961
|
+
sibs.push(elem);
|
|
1962
|
+
}
|
|
1963
|
+
}
|
|
1964
|
+
return sibs;
|
|
1965
|
+
}
|
|
1966
|
+
|
|
1967
|
+
static nextAll(elem, filter) {
|
|
1968
|
+
let sibs = [];
|
|
1969
|
+
while ((elem = elem.nextElementSibling)) {
|
|
1970
|
+
if (filter === undefined || this.matches(elem, filter)) {
|
|
1971
|
+
sibs.push(elem);
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
return sibs;
|
|
1975
|
+
}
|
|
1976
|
+
|
|
1977
|
+
static prevUntil(elem, filter) {
|
|
1978
|
+
let sibs = [];
|
|
1979
|
+
while ((elem = elem.previousElementSibling)) {
|
|
1980
|
+
if (!this.matches(elem, filter)) {
|
|
1981
|
+
sibs.push(elem);
|
|
1982
|
+
} else {
|
|
1983
|
+
break;
|
|
1984
|
+
}
|
|
1985
|
+
}
|
|
1986
|
+
return sibs;
|
|
1987
|
+
}
|
|
1988
|
+
|
|
1989
|
+
static nextUntil(elem, filter) {
|
|
1990
|
+
let sibs = [];
|
|
1991
|
+
while ((elem = elem.nextElementSibling)) {
|
|
1992
|
+
if (!this.matches(elem, filter)) {
|
|
1993
|
+
sibs.push(elem);
|
|
1994
|
+
} else {
|
|
1995
|
+
break;
|
|
1996
|
+
}
|
|
1997
|
+
}
|
|
1998
|
+
return sibs;
|
|
1999
|
+
}
|
|
2000
|
+
|
|
2001
|
+
static siblings(elem, filter) {
|
|
2002
|
+
let sibs = [];
|
|
2003
|
+
let self = elem;
|
|
2004
|
+
elem = elem.parentNode.firstChild;
|
|
2005
|
+
while ((elem = elem.nextElementSibling)) {
|
|
2006
|
+
if (filter === undefined || this.matches(elem, filter)) {
|
|
2007
|
+
if (self !== elem) {
|
|
2008
|
+
sibs.push(elem);
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
return sibs;
|
|
2013
|
+
}
|
|
2014
|
+
|
|
2015
|
+
static parents(elem, selector) {
|
|
2016
|
+
let elements = [];
|
|
2017
|
+
let ishaveselector = selector !== undefined;
|
|
2018
|
+
while ((elem = elem.parentElement) !== null) {
|
|
2019
|
+
if (elem.nodeType !== Node.ELEMENT_NODE) {
|
|
2020
|
+
continue;
|
|
2021
|
+
}
|
|
2022
|
+
if (!ishaveselector || this.matches(elem, selector)) {
|
|
2023
|
+
elements.push(elem);
|
|
2024
|
+
}
|
|
2025
|
+
}
|
|
2026
|
+
return elements;
|
|
2027
|
+
}
|
|
2028
|
+
|
|
2029
|
+
static css(el) {
|
|
2030
|
+
let sheets = document.styleSheets,
|
|
2031
|
+
o = {};
|
|
2032
|
+
for (let sheets__key in sheets) {
|
|
2033
|
+
try {
|
|
2034
|
+
let rules = sheets[sheets__key].rules || sheets[sheets__key].cssRules;
|
|
2035
|
+
for (let rules__key in rules) {
|
|
2036
|
+
if (this.matches(el, rules[rules__key].selectorText)) {
|
|
2037
|
+
o = Object.assign(
|
|
2038
|
+
o,
|
|
2039
|
+
this.css2json(rules[rules__key].style),
|
|
2040
|
+
this.css2json(el.getAttribute('style')),
|
|
2041
|
+
);
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
} catch (e) {}
|
|
2045
|
+
}
|
|
2046
|
+
return o;
|
|
2047
|
+
}
|
|
2048
|
+
|
|
2049
|
+
static css2json(css) {
|
|
2050
|
+
let obj = {};
|
|
2051
|
+
if (!css) {
|
|
2052
|
+
return obj;
|
|
2053
|
+
}
|
|
2054
|
+
if (css instanceof CSSStyleDeclaration) {
|
|
2055
|
+
for (let css__key in css) {
|
|
2056
|
+
if (css[css__key].toLowerCase && css[css[css__key]] !== undefined) {
|
|
2057
|
+
obj[css[css__key].toLowerCase()] = css[css[css__key]];
|
|
2058
|
+
}
|
|
2059
|
+
}
|
|
2060
|
+
} else if (typeof css == 'string') {
|
|
2061
|
+
css = css.split(';');
|
|
2062
|
+
for (let css__key in css) {
|
|
2063
|
+
if (css[css__key].indexOf(':') > -1) {
|
|
2064
|
+
let val = css[css__key].split(':');
|
|
2065
|
+
obj[val[0].toLowerCase().trim()] = val[1].trim();
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
}
|
|
2069
|
+
return obj;
|
|
2070
|
+
}
|
|
2071
|
+
|
|
2072
|
+
static compareDates(d1, d2) {
|
|
2073
|
+
// safari has problems in parsing "2019-01-01 00:00:00"
|
|
2074
|
+
if (typeof d1 === 'string') {
|
|
2075
|
+
d1 = d1.split(' ').join('T');
|
|
2076
|
+
}
|
|
2077
|
+
if (typeof d2 === 'string') {
|
|
2078
|
+
d2 = d2.split(' ').join('T');
|
|
2079
|
+
}
|
|
2080
|
+
d1 = new Date(d1);
|
|
2081
|
+
d2 = new Date(d2);
|
|
2082
|
+
d1.setHours(0);
|
|
2083
|
+
d1.setMinutes(0);
|
|
2084
|
+
d1.setSeconds(0);
|
|
2085
|
+
d1.setMilliseconds(0);
|
|
2086
|
+
d2.setHours(0);
|
|
2087
|
+
d2.setMinutes(0);
|
|
2088
|
+
d2.setSeconds(0);
|
|
2089
|
+
d2.setMilliseconds(0);
|
|
2090
|
+
if (d1.getFullYear() === d2.getFullYear() && d1.getMonth() === d2.getMonth() && d1.getDate() === d2.getDate()) {
|
|
2091
|
+
return 0;
|
|
2092
|
+
}
|
|
2093
|
+
if (d1 < d2) {
|
|
2094
|
+
return -1;
|
|
2095
|
+
}
|
|
2096
|
+
return 1;
|
|
2097
|
+
}
|
|
2098
|
+
|
|
2099
|
+
static spaceship(val1, val2) {
|
|
2100
|
+
if (val1 === null || val2 === null || typeof val1 != typeof val2) {
|
|
2101
|
+
return null;
|
|
2102
|
+
}
|
|
2103
|
+
if (typeof val1 === 'string') {
|
|
2104
|
+
return val1.localeCompare(val2);
|
|
2105
|
+
} else {
|
|
2106
|
+
if (val1 > val2) {
|
|
2107
|
+
return 1;
|
|
2108
|
+
} else if (val1 < val2) {
|
|
2109
|
+
return -1;
|
|
2110
|
+
}
|
|
2111
|
+
return 0;
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
static querySelectorAllShadowDom(selector) {
|
|
2116
|
+
let traverse = function ($parent) {
|
|
2117
|
+
$els = [];
|
|
2118
|
+
if ($parent.querySelector('*') !== null) {
|
|
2119
|
+
$parent.querySelectorAll('*').forEach(($el) => {
|
|
2120
|
+
$els.push($el);
|
|
2121
|
+
if ($el.shadowRoot !== undefined && $el.shadowRoot !== null) {
|
|
2122
|
+
$els = $els.concat(traverse($el.shadowRoot));
|
|
2123
|
+
}
|
|
2124
|
+
});
|
|
2125
|
+
}
|
|
2126
|
+
return $els;
|
|
2127
|
+
};
|
|
2128
|
+
let fragment = document.createDocumentFragment();
|
|
2129
|
+
$els = traverse(document);
|
|
2130
|
+
$els.forEach(($el) => {
|
|
2131
|
+
if ($el.matches(selector)) {
|
|
2132
|
+
fragment.appendChild($el.cloneNode());
|
|
2133
|
+
}
|
|
2134
|
+
});
|
|
2135
|
+
return fragment.childNodes;
|
|
2136
|
+
}
|
|
2137
|
+
|
|
2138
|
+
static focus(selector) {
|
|
2139
|
+
hlp.unfocus();
|
|
2140
|
+
let el = null;
|
|
2141
|
+
if (typeof selector === 'string' || selector instanceof String) {
|
|
2142
|
+
el = document.querySelector(selector);
|
|
2143
|
+
} else {
|
|
2144
|
+
el = selector;
|
|
2145
|
+
}
|
|
2146
|
+
if (el !== null) {
|
|
2147
|
+
let mask = document.createElement('div');
|
|
2148
|
+
mask.classList.add('hlp-focus-mask');
|
|
2149
|
+
mask.style.position = 'fixed';
|
|
2150
|
+
mask.style.top = 0;
|
|
2151
|
+
mask.style.bottom = 0;
|
|
2152
|
+
mask.style.left = 0;
|
|
2153
|
+
mask.style.right = 0;
|
|
2154
|
+
mask.style.backgroundColor = 'rgba(0,0,0,0.8)';
|
|
2155
|
+
mask.style.zIndex = 2147483646;
|
|
2156
|
+
el.before(mask);
|
|
2157
|
+
el.setAttribute('data-focussed', 1);
|
|
2158
|
+
el.setAttribute('data-focussed-orig-z-index', el.style.zIndex);
|
|
2159
|
+
el.setAttribute('data-focussed-orig-position', el.style.position);
|
|
2160
|
+
el.setAttribute('data-focussed-orig-background-color', el.style.backgroundColor);
|
|
2161
|
+
el.setAttribute('data-focussed-orig-box-shadow', el.style.boxShadow);
|
|
2162
|
+
el.style.zIndex = 2147483647;
|
|
2163
|
+
el.style.position = 'relative';
|
|
2164
|
+
el.style.backgroundColor = '#ffffff';
|
|
2165
|
+
el.style.boxShadow = '0px 0px 0px 20px #fff';
|
|
2166
|
+
}
|
|
2167
|
+
}
|
|
2168
|
+
|
|
2169
|
+
static unfocus() {
|
|
2170
|
+
if (document.querySelector('.hlp-focus-mask') !== null) {
|
|
2171
|
+
document.querySelectorAll('.hlp-focus-mask').forEach((el) => {
|
|
2172
|
+
hlp.remove(el);
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
if (document.querySelector('[data-focussed]') !== null) {
|
|
2176
|
+
document.querySelectorAll('[data-focussed]').forEach((el) => {
|
|
2177
|
+
el.style.zIndex = el.getAttribute('data-focussed-orig-z-index');
|
|
2178
|
+
el.style.position = el.getAttribute('data-focussed-orig-position');
|
|
2179
|
+
el.style.backgroundColor = el.getAttribute('data-focussed-orig-background-color');
|
|
2180
|
+
el.style.boxShadow = el.getAttribute('data-focussed-orig-box-shadow');
|
|
2181
|
+
el.removeAttribute('data-focussed');
|
|
2182
|
+
el.removeAttribute('data-focussed-orig-z-index');
|
|
2183
|
+
el.removeAttribute('data-focussed-orig-position');
|
|
2184
|
+
el.removeAttribute('data-focussed-orig-background-color');
|
|
2185
|
+
el.removeAttribute('data-focussed-orig-box-shadow');
|
|
2186
|
+
});
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
|
|
2190
|
+
static remove(el) {
|
|
2191
|
+
if (el !== null) {
|
|
2192
|
+
el.parentNode.removeChild(el);
|
|
2193
|
+
}
|
|
2194
|
+
}
|
|
2195
|
+
|
|
2196
|
+
static on(event, selector, scope, callback = null) {
|
|
2197
|
+
if (callback === null) {
|
|
2198
|
+
callback = scope;
|
|
2199
|
+
scope = document;
|
|
2200
|
+
} else {
|
|
2201
|
+
scope = document.querySelector(scope);
|
|
2202
|
+
}
|
|
2203
|
+
scope.addEventListener(
|
|
2204
|
+
event,
|
|
2205
|
+
(e) => {
|
|
2206
|
+
var el = hlp.closest(e.target, selector);
|
|
2207
|
+
if (el) {
|
|
2208
|
+
callback(e, el);
|
|
2209
|
+
}
|
|
2210
|
+
},
|
|
2211
|
+
false,
|
|
2212
|
+
);
|
|
2213
|
+
}
|
|
2214
|
+
|
|
2215
|
+
static url() {
|
|
2216
|
+
return window.location.protocol + '//' + window.location.host + window.location.pathname;
|
|
2217
|
+
}
|
|
2218
|
+
|
|
2219
|
+
static urlWithHash() {
|
|
2220
|
+
return window.location.protocol + '//' + window.location.host + window.location.pathname + window.location.hash;
|
|
2221
|
+
}
|
|
2222
|
+
|
|
2223
|
+
static fullUrl() {
|
|
2224
|
+
return window.location.href;
|
|
2225
|
+
}
|
|
2226
|
+
|
|
2227
|
+
static urlWithArgs() {
|
|
2228
|
+
return window.location.href.split('#')[0];
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
static baseUrl() {
|
|
2232
|
+
return window.location.protocol + '//' + window.location.host;
|
|
2233
|
+
}
|
|
2234
|
+
|
|
2235
|
+
static urlProtocol() {
|
|
2236
|
+
return window.location.protocol + '//';
|
|
2237
|
+
}
|
|
2238
|
+
|
|
2239
|
+
static urlHost() {
|
|
2240
|
+
return window.location.host;
|
|
2241
|
+
}
|
|
2242
|
+
|
|
2243
|
+
static urlHostTopLevel() {
|
|
2244
|
+
let host = window.location.host;
|
|
2245
|
+
// ipv4
|
|
2246
|
+
if (host.match(/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$/)) {
|
|
2247
|
+
return host;
|
|
2248
|
+
}
|
|
2249
|
+
host = host.split('.');
|
|
2250
|
+
while (host.length > 2) {
|
|
2251
|
+
host.shift();
|
|
2252
|
+
}
|
|
2253
|
+
host = host.join('.');
|
|
2254
|
+
return host;
|
|
2255
|
+
}
|
|
2256
|
+
|
|
2257
|
+
static urlPath() {
|
|
2258
|
+
return window.location.pathname;
|
|
2259
|
+
}
|
|
2260
|
+
|
|
2261
|
+
static urlHash() {
|
|
2262
|
+
return window.location.hash;
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
static urlArgs() {
|
|
2266
|
+
return window.location.search;
|
|
2267
|
+
}
|
|
2268
|
+
|
|
2269
|
+
static urlOfScript() {
|
|
2270
|
+
if (document.currentScript) {
|
|
2271
|
+
return document.currentScript.src;
|
|
2272
|
+
} else {
|
|
2273
|
+
let scripts = document.getElementsByTagName('script');
|
|
2274
|
+
return scripts[scripts.length - 1].src;
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
static pathOfScript() {
|
|
2279
|
+
let script = this.urlOfScript(),
|
|
2280
|
+
path = script.substring(0, script.lastIndexOf('/'));
|
|
2281
|
+
return path;
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
static waitUntil(selector, css_option = null, css_value = null) {
|
|
2285
|
+
return new Promise((resolve, reject) => {
|
|
2286
|
+
let timeout = setInterval(() => {
|
|
2287
|
+
if (
|
|
2288
|
+
document.querySelector(selector) !== null &&
|
|
2289
|
+
(css_option === null ||
|
|
2290
|
+
(css_value === null &&
|
|
2291
|
+
window.getComputedStyle(document.querySelector(selector))[css_option] !== undefined &&
|
|
2292
|
+
window.getComputedStyle(document.querySelector(selector))[css_option] != '') ||
|
|
2293
|
+
(css_value !== null &&
|
|
2294
|
+
window.getComputedStyle(document.querySelector(selector))[css_option] === css_value))
|
|
2295
|
+
) {
|
|
2296
|
+
window.clearInterval(timeout);
|
|
2297
|
+
resolve();
|
|
2298
|
+
}
|
|
2299
|
+
}, 30);
|
|
2300
|
+
});
|
|
2301
|
+
}
|
|
2302
|
+
|
|
2303
|
+
static waitUntilEach(selector, callback) {
|
|
2304
|
+
let observer = new MutationObserver(() => {
|
|
2305
|
+
let elements = document.querySelectorAll(selector);
|
|
2306
|
+
if (elements.length > 0) {
|
|
2307
|
+
elements.forEach((element) => {
|
|
2308
|
+
if (!element.__processed) {
|
|
2309
|
+
element.__processed = true;
|
|
2310
|
+
callback(element);
|
|
2311
|
+
}
|
|
2312
|
+
});
|
|
2313
|
+
}
|
|
2314
|
+
});
|
|
2315
|
+
observer.observe(document.body, {
|
|
2316
|
+
childList: true,
|
|
2317
|
+
subtree: true,
|
|
2318
|
+
});
|
|
2319
|
+
let initialElements = document.querySelectorAll(selector);
|
|
2320
|
+
if (initialElements.length > 0) {
|
|
2321
|
+
initialElements.forEach((element) => {
|
|
2322
|
+
if (!element.__processed) {
|
|
2323
|
+
element.__processed = true;
|
|
2324
|
+
callback(element);
|
|
2325
|
+
}
|
|
2326
|
+
});
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
|
|
2330
|
+
static waitUntilVar(arg1 = null, arg2 = null, value = null) {
|
|
2331
|
+
let varName = null,
|
|
2332
|
+
parentContainer = null;
|
|
2333
|
+
if (arg2 === null) {
|
|
2334
|
+
varName = arg1;
|
|
2335
|
+
parentContainer = window;
|
|
2336
|
+
} else {
|
|
2337
|
+
varName = arg2;
|
|
2338
|
+
parentContainer = arg1;
|
|
2339
|
+
}
|
|
2340
|
+
return new Promise((resolve, reject) => {
|
|
2341
|
+
let timeout = setInterval(() => {
|
|
2342
|
+
if (parentContainer[varName] !== undefined && parentContainer[varName] !== null) {
|
|
2343
|
+
if (value === null || parentContainer[varName] === value) {
|
|
2344
|
+
window.clearInterval(timeout);
|
|
2345
|
+
resolve();
|
|
2346
|
+
}
|
|
2347
|
+
}
|
|
2348
|
+
}, 30);
|
|
2349
|
+
});
|
|
2350
|
+
}
|
|
2351
|
+
|
|
2352
|
+
static ready() {
|
|
2353
|
+
return new Promise((resolve) => {
|
|
2354
|
+
if (document.readyState !== 'loading') {
|
|
2355
|
+
return resolve();
|
|
2356
|
+
} else {
|
|
2357
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
2358
|
+
return resolve();
|
|
2359
|
+
});
|
|
2360
|
+
}
|
|
2361
|
+
});
|
|
2362
|
+
}
|
|
2363
|
+
|
|
2364
|
+
static load() {
|
|
2365
|
+
return new Promise((resolve) => {
|
|
2366
|
+
if (document.readyState === 'complete') {
|
|
2367
|
+
return resolve();
|
|
2368
|
+
} else {
|
|
2369
|
+
window.addEventListener('load', () => {
|
|
2370
|
+
return resolve();
|
|
2371
|
+
});
|
|
2372
|
+
}
|
|
2373
|
+
});
|
|
2374
|
+
}
|
|
2375
|
+
|
|
2376
|
+
static runForEl(selector, callback) {
|
|
2377
|
+
hlp.ready().then(() => {
|
|
2378
|
+
// add unique id
|
|
2379
|
+
let id = hlp.pushId();
|
|
2380
|
+
|
|
2381
|
+
// also run for existing
|
|
2382
|
+
if (document.querySelector(selector) !== null) {
|
|
2383
|
+
document.querySelectorAll(selector).forEach((el) => {
|
|
2384
|
+
if (el.runForEl === undefined) {
|
|
2385
|
+
el.runForEl = [];
|
|
2386
|
+
}
|
|
2387
|
+
if (!el.runForEl.includes(id)) {
|
|
2388
|
+
el.runForEl.push(id);
|
|
2389
|
+
callback(el);
|
|
2390
|
+
}
|
|
2391
|
+
});
|
|
2392
|
+
}
|
|
2393
|
+
// setup queue
|
|
2394
|
+
if (window.runForEl_queue === undefined) {
|
|
2395
|
+
window.runForEl_queue = [];
|
|
2396
|
+
}
|
|
2397
|
+
// setup observer
|
|
2398
|
+
if (window.runForEl_observer === undefined) {
|
|
2399
|
+
window.runForEl_observer = new MutationObserver((mutations) => {
|
|
2400
|
+
mutations.forEach((mutations__value) => {
|
|
2401
|
+
if (!mutations__value.addedNodes) {
|
|
2402
|
+
return;
|
|
2403
|
+
}
|
|
2404
|
+
for (let i = 0; i < mutations__value.addedNodes.length; i++) {
|
|
2405
|
+
let node = mutations__value.addedNodes[i];
|
|
2406
|
+
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
2407
|
+
window.runForEl_queue.forEach((queue__value) => {
|
|
2408
|
+
if (node.matches(queue__value.selector)) {
|
|
2409
|
+
if (node.runForEl === undefined) {
|
|
2410
|
+
node.runForEl = [];
|
|
2411
|
+
}
|
|
2412
|
+
if (!node.runForEl.includes(queue__value.id)) {
|
|
2413
|
+
node.runForEl.push(queue__value.id);
|
|
2414
|
+
queue__value.callback(node);
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
// if you modify lots of html (e.g. with innerHTML), also check childs
|
|
2418
|
+
if (node.querySelector(queue__value.selector) !== null) {
|
|
2419
|
+
node.querySelectorAll(queue__value.selector).forEach((nodes__value) => {
|
|
2420
|
+
if (nodes__value.runForEl === undefined) {
|
|
2421
|
+
nodes__value.runForEl = [];
|
|
2422
|
+
}
|
|
2423
|
+
if (!nodes__value.runForEl.includes(queue__value.id)) {
|
|
2424
|
+
nodes__value.runForEl.push(queue__value.id);
|
|
2425
|
+
queue__value.callback(nodes__value);
|
|
2426
|
+
}
|
|
2427
|
+
});
|
|
2428
|
+
}
|
|
2429
|
+
});
|
|
2430
|
+
}
|
|
2431
|
+
}
|
|
2432
|
+
});
|
|
2433
|
+
}).observe(document.body, {
|
|
2434
|
+
attributes: false,
|
|
2435
|
+
childList: true,
|
|
2436
|
+
characterData: false,
|
|
2437
|
+
subtree: true,
|
|
2438
|
+
attributeOldValue: false,
|
|
2439
|
+
characterDataOldValue: false,
|
|
2440
|
+
});
|
|
2441
|
+
}
|
|
2442
|
+
// push to queue
|
|
2443
|
+
window.runForEl_queue.push({
|
|
2444
|
+
id: id,
|
|
2445
|
+
selector: selector,
|
|
2446
|
+
callback: callback,
|
|
2447
|
+
});
|
|
2448
|
+
});
|
|
2449
|
+
}
|
|
2450
|
+
|
|
2451
|
+
static fmath(op, x, y, precision = 8) {
|
|
2452
|
+
let n = {
|
|
2453
|
+
'*': x * y,
|
|
2454
|
+
'-': x - y,
|
|
2455
|
+
'+': x + y,
|
|
2456
|
+
'/': x / y,
|
|
2457
|
+
}[op];
|
|
2458
|
+
return Math.round(n * 10 * Math.pow(10, precision)) / (10 * Math.pow(10, precision));
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
static trim(str, charlist) {
|
|
2462
|
+
let whitespace = [
|
|
2463
|
+
' ',
|
|
2464
|
+
'\n',
|
|
2465
|
+
'\r',
|
|
2466
|
+
'\t',
|
|
2467
|
+
'\f',
|
|
2468
|
+
'\x0b',
|
|
2469
|
+
'\xa0',
|
|
2470
|
+
'\u2000',
|
|
2471
|
+
'\u2001',
|
|
2472
|
+
'\u2002',
|
|
2473
|
+
'\u2003',
|
|
2474
|
+
'\u2004',
|
|
2475
|
+
'\u2005',
|
|
2476
|
+
'\u2006',
|
|
2477
|
+
'\u2007',
|
|
2478
|
+
'\u2008',
|
|
2479
|
+
'\u2009',
|
|
2480
|
+
'\u200a',
|
|
2481
|
+
'\u200b',
|
|
2482
|
+
'\u2028',
|
|
2483
|
+
'\u2029',
|
|
2484
|
+
'\u3000',
|
|
2485
|
+
].join('');
|
|
2486
|
+
let l = 0;
|
|
2487
|
+
let i = 0;
|
|
2488
|
+
str += '';
|
|
2489
|
+
if (charlist) {
|
|
2490
|
+
whitespace = (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '$1');
|
|
2491
|
+
}
|
|
2492
|
+
l = str.length;
|
|
2493
|
+
for (i = 0; i < l; i++) {
|
|
2494
|
+
if (whitespace.indexOf(str.charAt(i)) === -1) {
|
|
2495
|
+
str = str.substring(i);
|
|
2496
|
+
break;
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
l = str.length;
|
|
2500
|
+
for (i = l - 1; i >= 0; i--) {
|
|
2501
|
+
if (whitespace.indexOf(str.charAt(i)) === -1) {
|
|
2502
|
+
str = str.substring(0, i + 1);
|
|
2503
|
+
break;
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
return whitespace.indexOf(str.charAt(0)) === -1 ? str : '';
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
static ltrim(str, charlist) {
|
|
2510
|
+
charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '$1');
|
|
2511
|
+
const re = new RegExp('^[' + charlist + ']+', 'g');
|
|
2512
|
+
return (str + '').replace(re, '');
|
|
2513
|
+
}
|
|
2514
|
+
|
|
2515
|
+
static rtrim(str, charlist) {
|
|
2516
|
+
charlist = !charlist ? ' \\s\u00A0' : (charlist + '').replace(/([[\]().?/*{}+$^:])/g, '\\$1');
|
|
2517
|
+
const re = new RegExp('[' + charlist + ']+$', 'g');
|
|
2518
|
+
return (str + '').replace(re, '');
|
|
2519
|
+
}
|
|
2520
|
+
|
|
2521
|
+
static truncate_string(str, len = 50, chars = '...') {
|
|
2522
|
+
if (this.nx(str) || !(typeof str === 'string' || str instanceof String)) {
|
|
2523
|
+
return str;
|
|
2524
|
+
}
|
|
2525
|
+
if (str.indexOf(' ') === -1) {
|
|
2526
|
+
if (str.length > len) {
|
|
2527
|
+
str = str.substring(0, len);
|
|
2528
|
+
str = hlp.rtrim(str);
|
|
2529
|
+
str += ' ' + chars;
|
|
2530
|
+
}
|
|
2531
|
+
} else {
|
|
2532
|
+
if (str.length > len) {
|
|
2533
|
+
str = hlp.rtrim(str);
|
|
2534
|
+
// cut of whole word
|
|
2535
|
+
while (str.length > len && str.lastIndexOf(' ') > -1 && str.substring(len - 1, len) != ' ') {
|
|
2536
|
+
str = str.substring(0, str.lastIndexOf(' '));
|
|
2537
|
+
str = hlp.rtrim(str);
|
|
2538
|
+
}
|
|
2539
|
+
str = str.substring(0, len);
|
|
2540
|
+
str = hlp.rtrim(str);
|
|
2541
|
+
str += ' ' + chars;
|
|
2542
|
+
}
|
|
2543
|
+
}
|
|
2544
|
+
return str;
|
|
2545
|
+
}
|
|
2546
|
+
|
|
2547
|
+
static emojiRegex(global = true) {
|
|
2548
|
+
return new RegExp(hlp.emojiRegexPattern(), (global === true ? 'g' : '') + 'u');
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
static emojiRegexPattern() {
|
|
2552
|
+
return String.raw`\p{RI}\p{RI}|\p{Extended_Pictographic}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?(\u200D(\p{RI}\p{RI}|\p{Extended_Pictographic}(\p{EMod}|\uFE0F\u20E3?|[\u{E0020}-\u{E007E}]+\u{E007F})?))*`;
|
|
2553
|
+
}
|
|
2554
|
+
|
|
2555
|
+
static emojiSplit(str) {
|
|
2556
|
+
if (!(typeof str === 'string' || str instanceof String)) {
|
|
2557
|
+
return str;
|
|
2558
|
+
}
|
|
2559
|
+
return [...new Intl.Segmenter().segment(str)].map((x) => x.segment);
|
|
2560
|
+
}
|
|
2561
|
+
|
|
2562
|
+
static serialize(mixedValue) {
|
|
2563
|
+
let val, key, okey;
|
|
2564
|
+
let ktype = '';
|
|
2565
|
+
let vals = '';
|
|
2566
|
+
let count = 0;
|
|
2567
|
+
const _utf8Size = function (str) {
|
|
2568
|
+
return ~-encodeURI(str).split(/%..|./).length;
|
|
2569
|
+
};
|
|
2570
|
+
const _getType = function (inp) {
|
|
2571
|
+
let match;
|
|
2572
|
+
let key;
|
|
2573
|
+
let cons;
|
|
2574
|
+
let types;
|
|
2575
|
+
let type = typeof inp;
|
|
2576
|
+
if (type === 'object' && !inp) {
|
|
2577
|
+
return 'null';
|
|
2578
|
+
}
|
|
2579
|
+
if (type === 'object') {
|
|
2580
|
+
if (!inp.constructor) {
|
|
2581
|
+
return 'object';
|
|
2582
|
+
}
|
|
2583
|
+
cons = inp.constructor.toString();
|
|
2584
|
+
match = cons.match(/(\w+)\(/);
|
|
2585
|
+
if (match) {
|
|
2586
|
+
cons = match[1].toLowerCase();
|
|
2587
|
+
}
|
|
2588
|
+
types = ['boolean', 'number', 'string', 'array'];
|
|
2589
|
+
for (key in types) {
|
|
2590
|
+
if (cons === types[key]) {
|
|
2591
|
+
type = types[key];
|
|
2592
|
+
break;
|
|
2593
|
+
}
|
|
2594
|
+
}
|
|
2595
|
+
}
|
|
2596
|
+
return type;
|
|
2597
|
+
};
|
|
2598
|
+
const type = _getType(mixedValue);
|
|
2599
|
+
switch (type) {
|
|
2600
|
+
case 'function':
|
|
2601
|
+
val = '';
|
|
2602
|
+
break;
|
|
2603
|
+
case 'boolean':
|
|
2604
|
+
val = 'b:' + (mixedValue ? '1' : '0');
|
|
2605
|
+
break;
|
|
2606
|
+
case 'number':
|
|
2607
|
+
val = (Math.round(mixedValue) === mixedValue ? 'i' : 'd') + ':' + mixedValue;
|
|
2608
|
+
break;
|
|
2609
|
+
case 'string':
|
|
2610
|
+
val = 's:' + _utf8Size(mixedValue) + ':"' + mixedValue + '"';
|
|
2611
|
+
break;
|
|
2612
|
+
case 'array':
|
|
2613
|
+
case 'object':
|
|
2614
|
+
val = 'a';
|
|
2615
|
+
for (key in mixedValue) {
|
|
2616
|
+
if (mixedValue.hasOwnProperty(key)) {
|
|
2617
|
+
ktype = _getType(mixedValue[key]);
|
|
2618
|
+
if (ktype === 'function') {
|
|
2619
|
+
continue;
|
|
2620
|
+
}
|
|
2621
|
+
okey = key.match(/^[0-9]+$/) ? parseInt(key, 10) : key;
|
|
2622
|
+
vals += this.serialize(okey) + this.serialize(mixedValue[key]);
|
|
2623
|
+
count++;
|
|
2624
|
+
}
|
|
2625
|
+
}
|
|
2626
|
+
val += ':' + count + ':{' + vals + '}';
|
|
2627
|
+
break;
|
|
2628
|
+
case 'undefined':
|
|
2629
|
+
default:
|
|
2630
|
+
val = 'N';
|
|
2631
|
+
break;
|
|
2632
|
+
}
|
|
2633
|
+
if (type !== 'object' && type !== 'array') {
|
|
2634
|
+
val += ';';
|
|
2635
|
+
}
|
|
2636
|
+
return val;
|
|
2637
|
+
}
|
|
2638
|
+
|
|
2639
|
+
static unserialize(str) {
|
|
2640
|
+
try {
|
|
2641
|
+
if (typeof str !== 'string') {
|
|
2642
|
+
return false;
|
|
2643
|
+
}
|
|
2644
|
+
|
|
2645
|
+
const store = [];
|
|
2646
|
+
const cache = (value) => {
|
|
2647
|
+
store.push(value[0]);
|
|
2648
|
+
return value;
|
|
2649
|
+
};
|
|
2650
|
+
cache.get = (index) => {
|
|
2651
|
+
if (index >= store.length) {
|
|
2652
|
+
throw RangeError(`Can't resolve reference ${index + 1}`);
|
|
2653
|
+
}
|
|
2654
|
+
return store[index];
|
|
2655
|
+
};
|
|
2656
|
+
|
|
2657
|
+
const expectType = (s) => {
|
|
2658
|
+
const types = /^(?:N(?=;)|[bidsSaOCrR](?=:)|[^:]+(?=:))/g;
|
|
2659
|
+
const type = (types.exec(s) || [])[0];
|
|
2660
|
+
if (!type) throw SyntaxError('Invalid input: ' + s);
|
|
2661
|
+
|
|
2662
|
+
switch (type) {
|
|
2663
|
+
case 'N':
|
|
2664
|
+
return cache([null, 2]);
|
|
2665
|
+
case 'b':
|
|
2666
|
+
return cache(expectBool(s));
|
|
2667
|
+
case 'i':
|
|
2668
|
+
return cache(expectInt(s));
|
|
2669
|
+
case 'd':
|
|
2670
|
+
return cache(expectFloat(s));
|
|
2671
|
+
case 's':
|
|
2672
|
+
return cache(expectString(s));
|
|
2673
|
+
case 'S':
|
|
2674
|
+
return cache(expectEscapedString(s));
|
|
2675
|
+
case 'a':
|
|
2676
|
+
return expectArray(s);
|
|
2677
|
+
case 'O':
|
|
2678
|
+
return expectObject(s);
|
|
2679
|
+
case 'C':
|
|
2680
|
+
throw Error('Not yet implemented');
|
|
2681
|
+
case 'r':
|
|
2682
|
+
case 'R':
|
|
2683
|
+
return expectReference(s);
|
|
2684
|
+
default:
|
|
2685
|
+
throw SyntaxError(`Invalid or unsupported data type: ${type}`);
|
|
2686
|
+
}
|
|
2687
|
+
};
|
|
2688
|
+
|
|
2689
|
+
const expectBool = (s) => {
|
|
2690
|
+
const reBool = /^b:([01]);/;
|
|
2691
|
+
const [match, boolMatch] = reBool.exec(s) || [];
|
|
2692
|
+
if (!boolMatch) throw SyntaxError('Invalid bool value, expected 0 or 1');
|
|
2693
|
+
return [boolMatch === '1', match.length];
|
|
2694
|
+
};
|
|
2695
|
+
|
|
2696
|
+
const expectInt = (s) => {
|
|
2697
|
+
const reInt = /^i:([+-]?\d+);/;
|
|
2698
|
+
const [match, intMatch] = reInt.exec(s) || [];
|
|
2699
|
+
if (!intMatch) throw SyntaxError('Expected an integer value');
|
|
2700
|
+
return [parseInt(intMatch, 10), match.length];
|
|
2701
|
+
};
|
|
2702
|
+
|
|
2703
|
+
const expectFloat = (s) => {
|
|
2704
|
+
const reFloat = /^d:(NAN|-?INF|(?:\d+\.\d*|\d*\.\d+|\d+)(?:[eE][+-]\d+)?);/;
|
|
2705
|
+
const [match, floatMatch] = reFloat.exec(s) || [];
|
|
2706
|
+
if (!floatMatch) throw SyntaxError('Expected a float value');
|
|
2707
|
+
return [
|
|
2708
|
+
floatMatch === 'NAN'
|
|
2709
|
+
? Number.NaN
|
|
2710
|
+
: floatMatch === '-INF'
|
|
2711
|
+
? Number.NEGATIVE_INFINITY
|
|
2712
|
+
: floatMatch === 'INF'
|
|
2713
|
+
? Number.POSITIVE_INFINITY
|
|
2714
|
+
: parseFloat(floatMatch),
|
|
2715
|
+
match.length,
|
|
2716
|
+
];
|
|
2717
|
+
};
|
|
2718
|
+
|
|
2719
|
+
const expectString = (s) => {
|
|
2720
|
+
const reStrLength = /^s:(\d+):"/g;
|
|
2721
|
+
const [match, byteLenMatch] = reStrLength.exec(s) || [];
|
|
2722
|
+
if (!match) throw SyntaxError('Expected a string value');
|
|
2723
|
+
const len = parseInt(byteLenMatch, 10);
|
|
2724
|
+
s = s.substr(match.length);
|
|
2725
|
+
const strMatch = s.substr(0, len);
|
|
2726
|
+
s = s.substr(len);
|
|
2727
|
+
if (!s.startsWith('";')) throw SyntaxError('Expected ";');
|
|
2728
|
+
return [strMatch, match.length + len + 2];
|
|
2729
|
+
};
|
|
2730
|
+
|
|
2731
|
+
const expectEscapedString = (s) => {
|
|
2732
|
+
const reStrLength = /^S:(\d+):"/g;
|
|
2733
|
+
const [match, strLenMatch] = reStrLength.exec(s) || [];
|
|
2734
|
+
if (!match) throw SyntaxError('Expected an escaped string value');
|
|
2735
|
+
const len = parseInt(strLenMatch, 10);
|
|
2736
|
+
s = s.substr(match.length);
|
|
2737
|
+
const strMatch = s.substr(0, len);
|
|
2738
|
+
s = s.substr(len);
|
|
2739
|
+
if (!s.startsWith('";')) throw SyntaxError('Expected ";');
|
|
2740
|
+
return [strMatch, match.length + len + 2];
|
|
2741
|
+
};
|
|
2742
|
+
|
|
2743
|
+
const expectReference = (s) => {
|
|
2744
|
+
const reRef = /^[rR]:(\d+);/;
|
|
2745
|
+
const [match, refIndex] = reRef.exec(s) || [];
|
|
2746
|
+
if (!match) throw SyntaxError('Expected reference value');
|
|
2747
|
+
return [cache.get(parseInt(refIndex, 10) - 1), match.length];
|
|
2748
|
+
};
|
|
2749
|
+
|
|
2750
|
+
const expectArray = (s) => {
|
|
2751
|
+
const reArrayLength = /^a:(\d+):\{/;
|
|
2752
|
+
const [arrayLiteralBeginMatch, arrayLengthMatch] = reArrayLength.exec(s) || [];
|
|
2753
|
+
if (!arrayLengthMatch) throw SyntaxError('Expected array length annotation');
|
|
2754
|
+
s = s.substr(arrayLiteralBeginMatch.length);
|
|
2755
|
+
const items = {};
|
|
2756
|
+
cache([items]);
|
|
2757
|
+
for (let i = 0; i < parseInt(arrayLengthMatch, 10); i++) {
|
|
2758
|
+
const key = expectType(s);
|
|
2759
|
+
s = s.substr(key[1]);
|
|
2760
|
+
const value = expectType(s);
|
|
2761
|
+
s = s.substr(value[1]);
|
|
2762
|
+
items[key[0]] = value[0];
|
|
2763
|
+
}
|
|
2764
|
+
if (s.charAt(0) !== '}') throw SyntaxError('Expected }');
|
|
2765
|
+
return [items, arrayLiteralBeginMatch.length + 1];
|
|
2766
|
+
};
|
|
2767
|
+
|
|
2768
|
+
const expectObject = (s) => {
|
|
2769
|
+
const reObjectLiteral = /^O:(\d+):"([^\"]+)":(\d+):\{/;
|
|
2770
|
+
const [match, , className, propCountMatch] = reObjectLiteral.exec(s) || [];
|
|
2771
|
+
if (!match) throw SyntaxError('Invalid input');
|
|
2772
|
+
if (className !== 'stdClass') throw SyntaxError(`Unsupported object type: ${className}`);
|
|
2773
|
+
let obj = {};
|
|
2774
|
+
cache([obj]);
|
|
2775
|
+
s = s.substr(match.length);
|
|
2776
|
+
for (let i = 0; i < parseInt(propCountMatch, 10); i++) {
|
|
2777
|
+
const prop = expectType(s);
|
|
2778
|
+
s = s.substr(prop[1]);
|
|
2779
|
+
const value = expectType(s);
|
|
2780
|
+
s = s.substr(value[1]);
|
|
2781
|
+
obj[prop[0]] = value[0];
|
|
2782
|
+
}
|
|
2783
|
+
if (s.charAt(0) !== '}') throw SyntaxError('Expected }');
|
|
2784
|
+
return [obj, match.length + 1];
|
|
2785
|
+
};
|
|
2786
|
+
|
|
2787
|
+
return expectType(str)[0];
|
|
2788
|
+
} catch (err) {
|
|
2789
|
+
console.error(err);
|
|
2790
|
+
return false;
|
|
2791
|
+
}
|
|
2792
|
+
}
|
|
2793
|
+
|
|
2794
|
+
static pushId() {
|
|
2795
|
+
/* source https://gist.github.com/mikelehen/3596a30bd69384624c11 */
|
|
2796
|
+
let pushIdData = null;
|
|
2797
|
+
// browser
|
|
2798
|
+
if (window !== undefined) {
|
|
2799
|
+
if (window.pushIdDataGlobal === undefined) {
|
|
2800
|
+
window.pushIdDataGlobal = {};
|
|
2801
|
+
}
|
|
2802
|
+
pushIdData = window.pushIdDataGlobal;
|
|
2803
|
+
}
|
|
2804
|
+
// node.js
|
|
2805
|
+
if (typeof global !== 'undefined') {
|
|
2806
|
+
if (global.pushIdDataGlobal === undefined) {
|
|
2807
|
+
global.pushIdDataGlobal = {};
|
|
2808
|
+
}
|
|
2809
|
+
pushIdData = global.pushIdDataGlobal;
|
|
2810
|
+
}
|
|
2811
|
+
// first run
|
|
2812
|
+
if (hlp.objectsAreEqual(pushIdData, {})) {
|
|
2813
|
+
pushIdData.lastPushTime = 0;
|
|
2814
|
+
pushIdData.lastRandChars = [];
|
|
2815
|
+
pushIdData.PUSH_CHARS = '-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz';
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
let now = new Date().getTime(),
|
|
2819
|
+
duplicateTime = now === pushIdData.lastPushTime;
|
|
2820
|
+
pushIdData.lastPushTime = now;
|
|
2821
|
+
|
|
2822
|
+
let timeStampChars = new Array(8);
|
|
2823
|
+
for (var i = 7; i >= 0; i--) {
|
|
2824
|
+
timeStampChars[i] = pushIdData.PUSH_CHARS.charAt(now % 64);
|
|
2825
|
+
now = Math.floor(now / 64);
|
|
2826
|
+
}
|
|
2827
|
+
if (now !== 0) {
|
|
2828
|
+
throw new Error();
|
|
2829
|
+
}
|
|
2830
|
+
let id = timeStampChars.join('');
|
|
2831
|
+
if (!duplicateTime) {
|
|
2832
|
+
for (i = 0; i < 12; i++) {
|
|
2833
|
+
pushIdData.lastRandChars[i] = Math.floor(Math.random() * 64);
|
|
2834
|
+
}
|
|
2835
|
+
} else {
|
|
2836
|
+
for (i = 11; i >= 0 && pushIdData.lastRandChars[i] === 63; i--) {
|
|
2837
|
+
pushIdData.lastRandChars[i] = 0;
|
|
2838
|
+
}
|
|
2839
|
+
pushIdData.lastRandChars[i]++;
|
|
2840
|
+
}
|
|
2841
|
+
for (i = 0; i < 12; i++) {
|
|
2842
|
+
id += pushIdData.PUSH_CHARS.charAt(pushIdData.lastRandChars[i]);
|
|
2843
|
+
}
|
|
2844
|
+
if (id.length != 20) {
|
|
2845
|
+
throw new Error();
|
|
2846
|
+
}
|
|
2847
|
+
return id;
|
|
2848
|
+
}
|
|
2849
|
+
|
|
2850
|
+
static getProp(obj, desc) {
|
|
2851
|
+
let arr = desc.split('.');
|
|
2852
|
+
while (arr.length && (obj = obj[arr.shift()]));
|
|
2853
|
+
return obj;
|
|
2854
|
+
}
|
|
2855
|
+
|
|
2856
|
+
static base64toblob(base64, contentType = '') {
|
|
2857
|
+
let sliceSize = 512,
|
|
2858
|
+
byteCharacters = atob(base64),
|
|
2859
|
+
byteArrays = [];
|
|
2860
|
+
|
|
2861
|
+
for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {
|
|
2862
|
+
let slice = byteCharacters.slice(offset, offset + sliceSize),
|
|
2863
|
+
byteNumbers = new Array(slice.length);
|
|
2864
|
+
for (let i = 0; i < slice.length; i++) {
|
|
2865
|
+
byteNumbers[i] = slice.charCodeAt(i);
|
|
2866
|
+
}
|
|
2867
|
+
let byteArray = new Uint8Array(byteNumbers);
|
|
2868
|
+
byteArrays.push(byteArray);
|
|
2869
|
+
}
|
|
2870
|
+
|
|
2871
|
+
let blob = new Blob(byteArrays, { type: contentType });
|
|
2872
|
+
return blob;
|
|
2873
|
+
}
|
|
2874
|
+
|
|
2875
|
+
static blobtobase64(blob) {
|
|
2876
|
+
return new Promise((resolve) => {
|
|
2877
|
+
let reader = new FileReader();
|
|
2878
|
+
reader.onload = () => {
|
|
2879
|
+
var dataUrl = reader.result;
|
|
2880
|
+
var base64 = dataUrl.split(',')[1];
|
|
2881
|
+
resolve(base64);
|
|
2882
|
+
};
|
|
2883
|
+
reader.readAsDataURL(blob);
|
|
2884
|
+
});
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2887
|
+
static stringtoblob(string, contentType = '') {
|
|
2888
|
+
let blob = new Blob([string], { type: contentType });
|
|
2889
|
+
return blob;
|
|
2890
|
+
}
|
|
2891
|
+
|
|
2892
|
+
static blobtostring(blob) {
|
|
2893
|
+
return new Promise((resolve) => {
|
|
2894
|
+
let reader = new FileReader();
|
|
2895
|
+
reader.onload = () => {
|
|
2896
|
+
resolve(reader.result);
|
|
2897
|
+
};
|
|
2898
|
+
reader.readAsText(blob);
|
|
2899
|
+
});
|
|
2900
|
+
}
|
|
2901
|
+
|
|
2902
|
+
static filetobase64(file) {
|
|
2903
|
+
return new Promise((resolve, reject) => {
|
|
2904
|
+
const reader = new FileReader();
|
|
2905
|
+
reader.readAsDataURL(file);
|
|
2906
|
+
reader.onload = () => resolve(reader.result.split(',')[1]);
|
|
2907
|
+
reader.onerror = (error) => reject(error);
|
|
2908
|
+
});
|
|
2909
|
+
}
|
|
2910
|
+
|
|
2911
|
+
static blobtofile(blob, filename = 'file.txt') {
|
|
2912
|
+
let file = null;
|
|
2913
|
+
try {
|
|
2914
|
+
file = new File([blob], filename);
|
|
2915
|
+
} catch {
|
|
2916
|
+
// ie 11
|
|
2917
|
+
file = new Blob([blob], filename);
|
|
2918
|
+
}
|
|
2919
|
+
return file;
|
|
2920
|
+
}
|
|
2921
|
+
|
|
2922
|
+
static filetoblob(file) {
|
|
2923
|
+
return new Blob([file]);
|
|
2924
|
+
}
|
|
2925
|
+
|
|
2926
|
+
static base64tofile(base64, contentType = '', filename = 'file.txt') {
|
|
2927
|
+
return this.blobtofile(this.base64toblob(base64, contentType), filename);
|
|
2928
|
+
}
|
|
2929
|
+
|
|
2930
|
+
static blobtourl(blob) {
|
|
2931
|
+
return URL.createObjectURL(blob, { type: 'text/plain' });
|
|
2932
|
+
}
|
|
2933
|
+
|
|
2934
|
+
static stringtourl(string) {
|
|
2935
|
+
return this.blobtourl(this.stringtoblob(string));
|
|
2936
|
+
}
|
|
2937
|
+
|
|
2938
|
+
static base64tostring(base64) {
|
|
2939
|
+
return atob(base64);
|
|
2940
|
+
}
|
|
2941
|
+
|
|
2942
|
+
static stringtobase64(string) {
|
|
2943
|
+
return btoa(string);
|
|
2944
|
+
}
|
|
2945
|
+
|
|
2946
|
+
static base64tourl(base64) {
|
|
2947
|
+
return this.blobtourl(this.base64toblob(base64));
|
|
2948
|
+
}
|
|
2949
|
+
|
|
2950
|
+
static filetourl(file) {
|
|
2951
|
+
return this.blobtourl(this.filetoblob(file));
|
|
2952
|
+
}
|
|
2953
|
+
|
|
2954
|
+
static getImageOrientation(base64) {
|
|
2955
|
+
return new Promise((resolve, reject) => {
|
|
2956
|
+
base64 = base64.replace('data:image/jpeg;base64,', '');
|
|
2957
|
+
let file = this.base64tofile(base64),
|
|
2958
|
+
reader = new FileReader();
|
|
2959
|
+
reader.onload = (e) => {
|
|
2960
|
+
var view = new DataView(e.target.result);
|
|
2961
|
+
if (view.getUint16(0, false) != 0xffd8) {
|
|
2962
|
+
resolve(-2);
|
|
2963
|
+
return;
|
|
2964
|
+
}
|
|
2965
|
+
var length = view.byteLength,
|
|
2966
|
+
offset = 2;
|
|
2967
|
+
while (offset < length) {
|
|
2968
|
+
if (view.getUint16(offset + 2, false) <= 8) {
|
|
2969
|
+
resolve(-1);
|
|
2970
|
+
return;
|
|
2971
|
+
}
|
|
2972
|
+
var marker = view.getUint16(offset, false);
|
|
2973
|
+
offset += 2;
|
|
2974
|
+
if (marker == 0xffe1) {
|
|
2975
|
+
if (view.getUint32((offset += 2), false) != 0x45786966) {
|
|
2976
|
+
resolve(-1);
|
|
2977
|
+
return;
|
|
2978
|
+
}
|
|
2979
|
+
var little = view.getUint16((offset += 6), false) == 0x4949;
|
|
2980
|
+
offset += view.getUint32(offset + 4, little);
|
|
2981
|
+
var tags = view.getUint16(offset, little);
|
|
2982
|
+
offset += 2;
|
|
2983
|
+
for (var i = 0; i < tags; i++) {
|
|
2984
|
+
if (view.getUint16(offset + i * 12, little) == 0x0112) {
|
|
2985
|
+
resolve(view.getUint16(offset + i * 12 + 8, little));
|
|
2986
|
+
return;
|
|
2987
|
+
}
|
|
2988
|
+
}
|
|
2989
|
+
} else if ((marker & 0xff00) != 0xff00) {
|
|
2990
|
+
break;
|
|
2991
|
+
} else {
|
|
2992
|
+
offset += view.getUint16(offset, false);
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
resolve(-1);
|
|
2996
|
+
return;
|
|
2997
|
+
};
|
|
2998
|
+
reader.readAsArrayBuffer(file);
|
|
2999
|
+
});
|
|
3000
|
+
}
|
|
3001
|
+
|
|
3002
|
+
static resetImageOrientation(srcBase64, srcOrientation) {
|
|
3003
|
+
return new Promise((resolve, reject) => {
|
|
3004
|
+
var img = new Image();
|
|
3005
|
+
img.onload = () => {
|
|
3006
|
+
var width = img.width,
|
|
3007
|
+
height = img.height,
|
|
3008
|
+
canvas = document.createElement('canvas'),
|
|
3009
|
+
ctx = canvas.getContext('2d');
|
|
3010
|
+
if (4 < srcOrientation && srcOrientation < 9) {
|
|
3011
|
+
canvas.width = height;
|
|
3012
|
+
canvas.height = width;
|
|
3013
|
+
} else {
|
|
3014
|
+
canvas.width = width;
|
|
3015
|
+
canvas.height = height;
|
|
3016
|
+
}
|
|
3017
|
+
switch (srcOrientation) {
|
|
3018
|
+
case 2:
|
|
3019
|
+
ctx.transform(-1, 0, 0, 1, width, 0);
|
|
3020
|
+
break;
|
|
3021
|
+
case 3:
|
|
3022
|
+
ctx.transform(-1, 0, 0, -1, width, height);
|
|
3023
|
+
break;
|
|
3024
|
+
case 4:
|
|
3025
|
+
ctx.transform(1, 0, 0, -1, 0, height);
|
|
3026
|
+
break;
|
|
3027
|
+
case 5:
|
|
3028
|
+
ctx.transform(0, 1, 1, 0, 0, 0);
|
|
3029
|
+
break;
|
|
3030
|
+
case 6:
|
|
3031
|
+
ctx.transform(0, 1, -1, 0, height, 0);
|
|
3032
|
+
break;
|
|
3033
|
+
case 7:
|
|
3034
|
+
ctx.transform(0, -1, -1, 0, height, width);
|
|
3035
|
+
break;
|
|
3036
|
+
case 8:
|
|
3037
|
+
ctx.transform(0, -1, 1, 0, 0, width);
|
|
3038
|
+
break;
|
|
3039
|
+
default:
|
|
3040
|
+
break;
|
|
3041
|
+
}
|
|
3042
|
+
ctx.drawImage(img, 0, 0);
|
|
3043
|
+
let base64 = canvas.toDataURL();
|
|
3044
|
+
base64 = 'data:image/jpeg;base64,' + base64.split(',')[1];
|
|
3045
|
+
resolve(base64);
|
|
3046
|
+
return;
|
|
3047
|
+
};
|
|
3048
|
+
img.src = srcBase64;
|
|
3049
|
+
});
|
|
3050
|
+
}
|
|
3051
|
+
|
|
3052
|
+
static fixImageOrientation(base64) {
|
|
3053
|
+
return new Promise((resolve, reject) => {
|
|
3054
|
+
if (base64.indexOf('data:') === -1) {
|
|
3055
|
+
resolve(base64);
|
|
3056
|
+
return;
|
|
3057
|
+
}
|
|
3058
|
+
if (base64.indexOf('data:image/jpeg;base64,') === 0) {
|
|
3059
|
+
base64 = base64.replace('data:image/jpeg;base64,', '');
|
|
3060
|
+
}
|
|
3061
|
+
this.getImageOrientation(base64).then((orientation) => {
|
|
3062
|
+
base64 = 'data:image/jpeg;base64,' + base64;
|
|
3063
|
+
if (orientation <= 1) {
|
|
3064
|
+
resolve(base64);
|
|
3065
|
+
return;
|
|
3066
|
+
} else {
|
|
3067
|
+
this.resetImageOrientation(base64, orientation).then((base64_new) => {
|
|
3068
|
+
resolve(base64_new);
|
|
3069
|
+
return;
|
|
3070
|
+
});
|
|
3071
|
+
}
|
|
3072
|
+
});
|
|
3073
|
+
});
|
|
3074
|
+
}
|
|
3075
|
+
|
|
3076
|
+
static debounce(func, wait, immediate) {
|
|
3077
|
+
var timeout;
|
|
3078
|
+
return function () {
|
|
3079
|
+
var context = this,
|
|
3080
|
+
args = arguments;
|
|
3081
|
+
var later = function () {
|
|
3082
|
+
timeout = null;
|
|
3083
|
+
if (!immediate) func.apply(context, args);
|
|
3084
|
+
};
|
|
3085
|
+
var callNow = immediate && !timeout;
|
|
3086
|
+
clearTimeout(timeout);
|
|
3087
|
+
timeout = setTimeout(later, wait);
|
|
3088
|
+
if (callNow) func.apply(context, args);
|
|
3089
|
+
};
|
|
3090
|
+
}
|
|
3091
|
+
|
|
3092
|
+
static throttle(func, wait, options) {
|
|
3093
|
+
var context, args, result;
|
|
3094
|
+
var timeout = null;
|
|
3095
|
+
var previous = 0;
|
|
3096
|
+
if (!options) options = {};
|
|
3097
|
+
var later = function () {
|
|
3098
|
+
previous = options.leading === false ? 0 : Date.now();
|
|
3099
|
+
timeout = null;
|
|
3100
|
+
result = func.apply(context, args);
|
|
3101
|
+
if (!timeout) context = args = null;
|
|
3102
|
+
};
|
|
3103
|
+
return function () {
|
|
3104
|
+
var now = Date.now();
|
|
3105
|
+
if (!previous && options.leading === false) previous = now;
|
|
3106
|
+
var remaining = wait - (now - previous);
|
|
3107
|
+
context = this;
|
|
3108
|
+
args = arguments;
|
|
3109
|
+
if (remaining <= 0 || remaining > wait) {
|
|
3110
|
+
if (timeout) {
|
|
3111
|
+
clearTimeout(timeout);
|
|
3112
|
+
timeout = null;
|
|
3113
|
+
}
|
|
3114
|
+
previous = now;
|
|
3115
|
+
result = func.apply(context, args);
|
|
3116
|
+
if (!timeout) context = args = null;
|
|
3117
|
+
} else if (!timeout && options.trailing !== false) {
|
|
3118
|
+
timeout = setTimeout(later, remaining);
|
|
3119
|
+
}
|
|
3120
|
+
return result;
|
|
3121
|
+
};
|
|
3122
|
+
}
|
|
3123
|
+
|
|
3124
|
+
static shuffle(array) {
|
|
3125
|
+
let currentIndex = array.length,
|
|
3126
|
+
temporaryValue,
|
|
3127
|
+
randomIndex;
|
|
3128
|
+
while (0 !== currentIndex) {
|
|
3129
|
+
randomIndex = Math.floor(Math.random() * currentIndex);
|
|
3130
|
+
currentIndex -= 1;
|
|
3131
|
+
temporaryValue = array[currentIndex];
|
|
3132
|
+
array[currentIndex] = array[randomIndex];
|
|
3133
|
+
array[randomIndex] = temporaryValue;
|
|
3134
|
+
}
|
|
3135
|
+
return array;
|
|
3136
|
+
}
|
|
3137
|
+
|
|
3138
|
+
static findRecursiveInObject(object, key = null, value = null, path = '', paths = []) {
|
|
3139
|
+
if (object !== null && typeof object === 'object') {
|
|
3140
|
+
for (const [object__key, object__value] of Object.entries(object)) {
|
|
3141
|
+
if (object__value !== null && typeof object__value === 'object') {
|
|
3142
|
+
this.findRecursiveInObject(
|
|
3143
|
+
object__value,
|
|
3144
|
+
key,
|
|
3145
|
+
value,
|
|
3146
|
+
(path === '' ? '' : path + '.') + object__key,
|
|
3147
|
+
paths,
|
|
3148
|
+
);
|
|
3149
|
+
} else if ((key === null || object__key === key) && (value === null || object__value === value)) {
|
|
3150
|
+
paths.push(path);
|
|
3151
|
+
break; // only take first
|
|
3152
|
+
}
|
|
3153
|
+
}
|
|
3154
|
+
}
|
|
3155
|
+
return paths;
|
|
3156
|
+
}
|
|
3157
|
+
}
|
|
3158
|
+
|
|
3159
|
+
/* expose all functions to window */
|
|
3160
|
+
if (typeof window !== 'undefined') {
|
|
3161
|
+
window.hlp = {};
|
|
3162
|
+
Object.getOwnPropertyNames(hlp).forEach((value, key) => {
|
|
3163
|
+
if (
|
|
3164
|
+
value === 'length' ||
|
|
3165
|
+
value === 'name' ||
|
|
3166
|
+
value === 'prototype' ||
|
|
3167
|
+
value === 'caller' ||
|
|
3168
|
+
value === 'arguments'
|
|
3169
|
+
) {
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
window.hlp[value] = hlp[value];
|
|
3173
|
+
});
|
|
3174
|
+
}
|