@tomasvn/glightbox 0.0.0-stage → 3.3.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/.editorconfig +16 -0
- package/.eslintignore +3 -0
- package/.eslintrc.json +94 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
- package/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- package/.github/stale.yml +21 -0
- package/.github/workflows/greetings.yml +13 -0
- package/.husky/pre-commit +3 -0
- package/.lando.yml +10 -0
- package/.prettierignore +3 -0
- package/.prettierrc.json +30 -0
- package/CHANGELOG.md +259 -0
- package/CONTRIBUTING.md +29 -0
- package/LICENSE.md +21 -0
- package/README.md +714 -2
- package/bower.json +29 -0
- package/development/build.js +44 -0
- package/development/jscompiler.js +90 -0
- package/development/notifications.js +15 -0
- package/development/package.js +116 -0
- package/development/postcss.js +63 -0
- package/development/watcher.js +105 -0
- package/dist/css/glightbox.css +939 -0
- package/dist/css/glightbox.min.css +1 -0
- package/dist/js/glightbox.js +3109 -0
- package/dist/js/glightbox.min.js +1 -0
- package/index.d.ts +586 -0
- package/package.json +60 -4
- package/src/js/.jshintrc +6 -0
- package/src/js/core/drag.js +203 -0
- package/src/js/core/keyboard-navigation.js +101 -0
- package/src/js/core/slide-parser.js +236 -0
- package/src/js/core/slide.js +251 -0
- package/src/js/core/touch-events.js +378 -0
- package/src/js/core/touch-navigation.js +291 -0
- package/src/js/core/zoom.js +156 -0
- package/src/js/glightbox.js +1351 -0
- package/src/js/slides/iframe.js +24 -0
- package/src/js/slides/image.js +56 -0
- package/src/js/slides/inline.js +71 -0
- package/src/js/slides/video.js +108 -0
- package/src/js/utils/helpers.js +541 -0
- package/src/postcss/glightbox.css +725 -0
- package/tests/slide.test.mjs +130 -0
- package/tests/touch-navigation.test.mjs +13 -0
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
const uid = Date.now();
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Merge two or more objects
|
|
5
|
+
*/
|
|
6
|
+
export function extend() {
|
|
7
|
+
let extended = {};
|
|
8
|
+
let deep = true;
|
|
9
|
+
let i = 0;
|
|
10
|
+
let length = arguments.length;
|
|
11
|
+
if (Object.prototype.toString.call(arguments[0]) === '[object Boolean]') {
|
|
12
|
+
deep = arguments[0];
|
|
13
|
+
i++;
|
|
14
|
+
}
|
|
15
|
+
let merge = (obj) => {
|
|
16
|
+
for (let prop in obj) {
|
|
17
|
+
if (Object.prototype.hasOwnProperty.call(obj, prop)) {
|
|
18
|
+
if (deep && Object.prototype.toString.call(obj[prop]) === '[object Object]') {
|
|
19
|
+
extended[prop] = extend(true, extended[prop], obj[prop]);
|
|
20
|
+
} else {
|
|
21
|
+
extended[prop] = obj[prop];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
for (; i < length; i++) {
|
|
27
|
+
let obj = arguments[i];
|
|
28
|
+
merge(obj);
|
|
29
|
+
}
|
|
30
|
+
return extended;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Each
|
|
35
|
+
*
|
|
36
|
+
* @param {mixed} node list, array, object
|
|
37
|
+
* @param {function} callback
|
|
38
|
+
*/
|
|
39
|
+
export function each(collection, callback) {
|
|
40
|
+
if (isNode(collection) || collection === window || collection === document) {
|
|
41
|
+
collection = [collection];
|
|
42
|
+
}
|
|
43
|
+
if (!isArrayLike(collection) && !isObject(collection)) {
|
|
44
|
+
collection = [collection];
|
|
45
|
+
}
|
|
46
|
+
if (size(collection) == 0) {
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (isArrayLike(collection) && !isObject(collection)) {
|
|
51
|
+
let l = collection.length,
|
|
52
|
+
i = 0;
|
|
53
|
+
for (; i < l; i++) {
|
|
54
|
+
if (callback.call(collection[i], collection[i], i, collection) === false) {
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} else if (isObject(collection)) {
|
|
59
|
+
for (let key in collection) {
|
|
60
|
+
if (has(collection, key)) {
|
|
61
|
+
if (callback.call(collection[key], collection[key], key, collection) === false) {
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Get nde events
|
|
71
|
+
* return node events and optionally
|
|
72
|
+
* check if the node has already a specific event
|
|
73
|
+
* to avoid duplicated callbacks
|
|
74
|
+
*
|
|
75
|
+
* @param {node} node
|
|
76
|
+
* @param {string} name event name
|
|
77
|
+
* @param {object} fn callback
|
|
78
|
+
* @returns {object}
|
|
79
|
+
*/
|
|
80
|
+
export function getNodeEvents(node, name = null, fn = null) {
|
|
81
|
+
const cache = (node[uid] = node[uid] || []);
|
|
82
|
+
const data = { all: cache, evt: null, found: null };
|
|
83
|
+
if (name && fn && size(cache) > 0) {
|
|
84
|
+
each(cache, (cl, i) => {
|
|
85
|
+
if (cl.eventName == name && cl.fn.toString() == fn.toString()) {
|
|
86
|
+
data.found = true;
|
|
87
|
+
data.evt = i;
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
return data;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Add Event
|
|
97
|
+
* Add an event listener
|
|
98
|
+
*
|
|
99
|
+
* @param {string} eventName
|
|
100
|
+
* @param {object} detials
|
|
101
|
+
*/
|
|
102
|
+
export function addEvent(eventName, { onElement, withCallback, avoidDuplicate = true, once = false, useCapture = false } = {}, thisArg) {
|
|
103
|
+
let element = onElement || [];
|
|
104
|
+
if (isString(element)) {
|
|
105
|
+
element = document.querySelectorAll(element);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function handler(event) {
|
|
109
|
+
if (isFunction(withCallback)) {
|
|
110
|
+
withCallback.call(thisArg, event, this);
|
|
111
|
+
}
|
|
112
|
+
if (once) {
|
|
113
|
+
handler.destroy();
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
handler.destroy = function () {
|
|
117
|
+
each(element, (el) => {
|
|
118
|
+
const events = getNodeEvents(el, eventName, handler);
|
|
119
|
+
if (events.found) {
|
|
120
|
+
events.all.splice(events.evt, 1);
|
|
121
|
+
}
|
|
122
|
+
if (el.removeEventListener) {
|
|
123
|
+
el.removeEventListener(eventName, handler, useCapture);
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
};
|
|
127
|
+
each(element, (el) => {
|
|
128
|
+
const events = getNodeEvents(el, eventName, handler);
|
|
129
|
+
if ((el.addEventListener && avoidDuplicate && !events.found) || !avoidDuplicate) {
|
|
130
|
+
el.addEventListener(eventName, handler, useCapture);
|
|
131
|
+
events.all.push({ eventName: eventName, fn: handler });
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
return handler;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Add element class
|
|
139
|
+
*
|
|
140
|
+
* @param {node} element
|
|
141
|
+
* @param {string} class name
|
|
142
|
+
*/
|
|
143
|
+
export function addClass(node, name) {
|
|
144
|
+
each(name.split(' '), (cl) => node.classList.add(cl));
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Remove element class
|
|
149
|
+
*
|
|
150
|
+
* @param {node} element
|
|
151
|
+
* @param {string} class name
|
|
152
|
+
*/
|
|
153
|
+
export function removeClass(node, name) {
|
|
154
|
+
each(name.split(' '), (cl) => node.classList.remove(cl));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Has class
|
|
159
|
+
*
|
|
160
|
+
* @param {node} element
|
|
161
|
+
* @param {string} class name
|
|
162
|
+
*/
|
|
163
|
+
export function hasClass(node, name) {
|
|
164
|
+
return node.classList.contains(name);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Get the closestElement
|
|
169
|
+
*
|
|
170
|
+
* @param {node} element
|
|
171
|
+
* @param {string} class name
|
|
172
|
+
*/
|
|
173
|
+
export function closest(elem, selector) {
|
|
174
|
+
while (elem !== document.body) {
|
|
175
|
+
elem = elem.parentElement;
|
|
176
|
+
if (!elem) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
const matches = typeof elem.matches == 'function' ? elem.matches(selector) : elem.msMatchesSelector(selector);
|
|
180
|
+
|
|
181
|
+
if (matches) {
|
|
182
|
+
return elem;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* CSS Animations
|
|
189
|
+
*
|
|
190
|
+
* @param {node} element
|
|
191
|
+
* @param {string} animation name
|
|
192
|
+
* @param {function} callback
|
|
193
|
+
*/
|
|
194
|
+
export function animateElement(element, animation = '', callback = false) {
|
|
195
|
+
if (!element || animation === '') {
|
|
196
|
+
return false;
|
|
197
|
+
}
|
|
198
|
+
if (animation === 'none') {
|
|
199
|
+
if (isFunction(callback)) {
|
|
200
|
+
callback();
|
|
201
|
+
}
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
const animationEnd = whichAnimationEvent();
|
|
205
|
+
const animationNames = animation.split(' ');
|
|
206
|
+
each(animationNames, (name) => {
|
|
207
|
+
addClass(element, 'g' + name);
|
|
208
|
+
});
|
|
209
|
+
addEvent(animationEnd, {
|
|
210
|
+
onElement: element,
|
|
211
|
+
avoidDuplicate: false,
|
|
212
|
+
once: true,
|
|
213
|
+
withCallback: (event, target) => {
|
|
214
|
+
each(animationNames, (name) => {
|
|
215
|
+
removeClass(target, 'g' + name);
|
|
216
|
+
});
|
|
217
|
+
if (isFunction(callback)) {
|
|
218
|
+
callback();
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function cssTransform(node, translate = '') {
|
|
225
|
+
if (translate === '') {
|
|
226
|
+
node.style.webkitTransform = '';
|
|
227
|
+
node.style.MozTransform = '';
|
|
228
|
+
node.style.msTransform = '';
|
|
229
|
+
node.style.OTransform = '';
|
|
230
|
+
node.style.transform = '';
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
node.style.webkitTransform = translate;
|
|
234
|
+
node.style.MozTransform = translate;
|
|
235
|
+
node.style.msTransform = translate;
|
|
236
|
+
node.style.OTransform = translate;
|
|
237
|
+
node.style.transform = translate;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Show element
|
|
242
|
+
*
|
|
243
|
+
* @param {node} element
|
|
244
|
+
*/
|
|
245
|
+
export function show(element) {
|
|
246
|
+
element.style.display = 'block';
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* Hide element
|
|
251
|
+
*/
|
|
252
|
+
export function hide(element) {
|
|
253
|
+
element.style.display = 'none';
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/**
|
|
257
|
+
* Create a document fragment
|
|
258
|
+
*
|
|
259
|
+
* @param {string} html code
|
|
260
|
+
*/
|
|
261
|
+
export function createHTML(htmlStr) {
|
|
262
|
+
let frag = document.createDocumentFragment(),
|
|
263
|
+
temp = document.createElement('div');
|
|
264
|
+
temp.innerHTML = htmlStr;
|
|
265
|
+
while (temp.firstChild) {
|
|
266
|
+
frag.appendChild(temp.firstChild);
|
|
267
|
+
}
|
|
268
|
+
return frag;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* Return screen size
|
|
273
|
+
* return the current screen dimensions
|
|
274
|
+
*
|
|
275
|
+
* @returns {object}
|
|
276
|
+
*/
|
|
277
|
+
export function windowSize() {
|
|
278
|
+
return {
|
|
279
|
+
width: window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
|
|
280
|
+
height: window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Determine animation events
|
|
286
|
+
*/
|
|
287
|
+
export function whichAnimationEvent() {
|
|
288
|
+
let t,
|
|
289
|
+
el = document.createElement('fakeelement');
|
|
290
|
+
let animations = {
|
|
291
|
+
animation: 'animationend',
|
|
292
|
+
OAnimation: 'oAnimationEnd',
|
|
293
|
+
MozAnimation: 'animationend',
|
|
294
|
+
WebkitAnimation: 'webkitAnimationEnd'
|
|
295
|
+
};
|
|
296
|
+
for (t in animations) {
|
|
297
|
+
if (el.style[t] !== undefined) {
|
|
298
|
+
return animations[t];
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
/**
|
|
304
|
+
* Determine transition events
|
|
305
|
+
*/
|
|
306
|
+
export function whichTransitionEvent() {
|
|
307
|
+
let t,
|
|
308
|
+
el = document.createElement('fakeelement');
|
|
309
|
+
|
|
310
|
+
const transitions = {
|
|
311
|
+
transition: 'transitionend',
|
|
312
|
+
OTransition: 'oTransitionEnd',
|
|
313
|
+
MozTransition: 'transitionend',
|
|
314
|
+
WebkitTransition: 'webkitTransitionEnd'
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
for (t in transitions) {
|
|
318
|
+
if (el.style[t] !== undefined) {
|
|
319
|
+
return transitions[t];
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Create an iframe element
|
|
326
|
+
*
|
|
327
|
+
* @param {string} url
|
|
328
|
+
* @param {numeric} width
|
|
329
|
+
* @param {numeric} height
|
|
330
|
+
* @param {function} callback
|
|
331
|
+
*/
|
|
332
|
+
export function createIframe(config) {
|
|
333
|
+
let { url, allow, callback, appendTo } = config;
|
|
334
|
+
let iframe = document.createElement('iframe');
|
|
335
|
+
iframe.className = 'vimeo-video gvideo';
|
|
336
|
+
iframe.src = url;
|
|
337
|
+
iframe.style.width = '100%';
|
|
338
|
+
iframe.style.height = '100%';
|
|
339
|
+
|
|
340
|
+
if (allow) {
|
|
341
|
+
iframe.setAttribute('allow', allow);
|
|
342
|
+
}
|
|
343
|
+
iframe.onload = function () {
|
|
344
|
+
iframe.onload = null;
|
|
345
|
+
addClass(iframe, 'node-ready');
|
|
346
|
+
if (isFunction(callback)) {
|
|
347
|
+
callback();
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
|
|
351
|
+
if (appendTo) {
|
|
352
|
+
appendTo.appendChild(iframe);
|
|
353
|
+
}
|
|
354
|
+
return iframe;
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Wait until
|
|
359
|
+
* wait until all the validations
|
|
360
|
+
* are passed
|
|
361
|
+
*
|
|
362
|
+
* @param {function} check
|
|
363
|
+
* @param {function} onComplete
|
|
364
|
+
* @param {numeric} delay
|
|
365
|
+
* @param {numeric} timeout
|
|
366
|
+
*/
|
|
367
|
+
export function waitUntil(check, onComplete, delay, timeout) {
|
|
368
|
+
if (check()) {
|
|
369
|
+
onComplete();
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
if (!delay) {
|
|
374
|
+
delay = 100;
|
|
375
|
+
}
|
|
376
|
+
let timeoutPointer;
|
|
377
|
+
let intervalPointer = setInterval(() => {
|
|
378
|
+
if (!check()) {
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
clearInterval(intervalPointer);
|
|
382
|
+
if (timeoutPointer) {
|
|
383
|
+
clearTimeout(timeoutPointer);
|
|
384
|
+
}
|
|
385
|
+
onComplete();
|
|
386
|
+
}, delay);
|
|
387
|
+
if (timeout) {
|
|
388
|
+
timeoutPointer = setTimeout(() => {
|
|
389
|
+
clearInterval(intervalPointer);
|
|
390
|
+
}, timeout);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
/**
|
|
395
|
+
* Inject videos api
|
|
396
|
+
* used for video player
|
|
397
|
+
*
|
|
398
|
+
* @param {string} url
|
|
399
|
+
* @param {function} callback
|
|
400
|
+
*/
|
|
401
|
+
export function injectAssets(url, waitFor, callback) {
|
|
402
|
+
if (isNil(url)) {
|
|
403
|
+
console.error('Inject assets error');
|
|
404
|
+
return;
|
|
405
|
+
}
|
|
406
|
+
if (isFunction(waitFor)) {
|
|
407
|
+
callback = waitFor;
|
|
408
|
+
waitFor = false;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
if (isString(waitFor) && waitFor in window) {
|
|
412
|
+
if (isFunction(callback)) {
|
|
413
|
+
callback();
|
|
414
|
+
}
|
|
415
|
+
return;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
let found;
|
|
419
|
+
|
|
420
|
+
if (url.indexOf('.css') !== -1) {
|
|
421
|
+
found = document.querySelectorAll('link[href="' + url + '"]');
|
|
422
|
+
if (found && found.length > 0) {
|
|
423
|
+
if (isFunction(callback)) {
|
|
424
|
+
callback();
|
|
425
|
+
}
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const head = document.getElementsByTagName('head')[0];
|
|
430
|
+
const headStyles = head.querySelectorAll('link[rel="stylesheet"]');
|
|
431
|
+
const link = document.createElement('link');
|
|
432
|
+
|
|
433
|
+
link.rel = 'stylesheet';
|
|
434
|
+
link.type = 'text/css';
|
|
435
|
+
link.href = url;
|
|
436
|
+
link.media = 'all';
|
|
437
|
+
|
|
438
|
+
if (headStyles) {
|
|
439
|
+
head.insertBefore(link, headStyles[0]);
|
|
440
|
+
} else {
|
|
441
|
+
head.appendChild(link);
|
|
442
|
+
}
|
|
443
|
+
if (isFunction(callback)) {
|
|
444
|
+
callback();
|
|
445
|
+
}
|
|
446
|
+
return;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
found = document.querySelectorAll('script[src="' + url + '"]');
|
|
450
|
+
if (found && found.length > 0) {
|
|
451
|
+
if (isFunction(callback)) {
|
|
452
|
+
if (isString(waitFor)) {
|
|
453
|
+
waitUntil(
|
|
454
|
+
() => {
|
|
455
|
+
return typeof window[waitFor] !== 'undefined';
|
|
456
|
+
},
|
|
457
|
+
() => {
|
|
458
|
+
callback();
|
|
459
|
+
}
|
|
460
|
+
);
|
|
461
|
+
return false;
|
|
462
|
+
}
|
|
463
|
+
callback();
|
|
464
|
+
}
|
|
465
|
+
return;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
let script = document.createElement('script');
|
|
469
|
+
script.type = 'text/javascript';
|
|
470
|
+
script.src = url;
|
|
471
|
+
script.onload = () => {
|
|
472
|
+
if (isFunction(callback)) {
|
|
473
|
+
if (isString(waitFor)) {
|
|
474
|
+
waitUntil(
|
|
475
|
+
() => {
|
|
476
|
+
return typeof window[waitFor] !== 'undefined';
|
|
477
|
+
},
|
|
478
|
+
() => {
|
|
479
|
+
callback();
|
|
480
|
+
}
|
|
481
|
+
);
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
484
|
+
callback();
|
|
485
|
+
}
|
|
486
|
+
};
|
|
487
|
+
document.body.appendChild(script);
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
export function isMobile() {
|
|
491
|
+
return 'navigator' in window && window.navigator.userAgent.match(/(iPad)|(iPhone)|(iPod)|(Android)|(PlayBook)|(BB10)|(BlackBerry)|(Opera Mini)|(IEMobile)|(webOS)|(MeeGo)/i);
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
export function isTouch() {
|
|
495
|
+
return isMobile() !== null || document.createTouch !== undefined || 'ontouchstart' in window || 'onmsgesturechange' in window || navigator.msMaxTouchPoints;
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
export function isFunction(f) {
|
|
499
|
+
return typeof f === 'function';
|
|
500
|
+
}
|
|
501
|
+
export function isString(s) {
|
|
502
|
+
return typeof s === 'string';
|
|
503
|
+
}
|
|
504
|
+
export function isNode(el) {
|
|
505
|
+
return !!(el && el.nodeType && el.nodeType == 1);
|
|
506
|
+
}
|
|
507
|
+
export function isArray(ar) {
|
|
508
|
+
return Array.isArray(ar);
|
|
509
|
+
}
|
|
510
|
+
export function isArrayLike(ar) {
|
|
511
|
+
return ar && ar.length && isFinite(ar.length);
|
|
512
|
+
}
|
|
513
|
+
export function isObject(o) {
|
|
514
|
+
let type = typeof o;
|
|
515
|
+
return type === 'object' && o != null && !isFunction(o) && !isArray(o);
|
|
516
|
+
}
|
|
517
|
+
export function isNil(o) {
|
|
518
|
+
return o == null;
|
|
519
|
+
}
|
|
520
|
+
export function has(obj, key) {
|
|
521
|
+
return obj !== null && hasOwnProperty.call(obj, key);
|
|
522
|
+
}
|
|
523
|
+
export function size(o) {
|
|
524
|
+
if (isObject(o)) {
|
|
525
|
+
if (o.keys) {
|
|
526
|
+
return o.keys().length;
|
|
527
|
+
}
|
|
528
|
+
let l = 0;
|
|
529
|
+
for (let k in o) {
|
|
530
|
+
if (has(o, k)) {
|
|
531
|
+
l++;
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
return l;
|
|
535
|
+
} else {
|
|
536
|
+
return o.length;
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
export function isNumber(n) {
|
|
540
|
+
return !isNaN(parseFloat(n)) && isFinite(n);
|
|
541
|
+
}
|