@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.
Files changed (46) hide show
  1. package/.editorconfig +16 -0
  2. package/.eslintignore +3 -0
  3. package/.eslintrc.json +94 -0
  4. package/.github/FUNDING.yml +3 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.md +41 -0
  6. package/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
  7. package/.github/stale.yml +21 -0
  8. package/.github/workflows/greetings.yml +13 -0
  9. package/.husky/pre-commit +3 -0
  10. package/.lando.yml +10 -0
  11. package/.prettierignore +3 -0
  12. package/.prettierrc.json +30 -0
  13. package/CHANGELOG.md +259 -0
  14. package/CONTRIBUTING.md +29 -0
  15. package/LICENSE.md +21 -0
  16. package/README.md +714 -2
  17. package/bower.json +29 -0
  18. package/development/build.js +44 -0
  19. package/development/jscompiler.js +90 -0
  20. package/development/notifications.js +15 -0
  21. package/development/package.js +116 -0
  22. package/development/postcss.js +63 -0
  23. package/development/watcher.js +105 -0
  24. package/dist/css/glightbox.css +939 -0
  25. package/dist/css/glightbox.min.css +1 -0
  26. package/dist/js/glightbox.js +3109 -0
  27. package/dist/js/glightbox.min.js +1 -0
  28. package/index.d.ts +586 -0
  29. package/package.json +60 -4
  30. package/src/js/.jshintrc +6 -0
  31. package/src/js/core/drag.js +203 -0
  32. package/src/js/core/keyboard-navigation.js +101 -0
  33. package/src/js/core/slide-parser.js +236 -0
  34. package/src/js/core/slide.js +251 -0
  35. package/src/js/core/touch-events.js +378 -0
  36. package/src/js/core/touch-navigation.js +291 -0
  37. package/src/js/core/zoom.js +156 -0
  38. package/src/js/glightbox.js +1351 -0
  39. package/src/js/slides/iframe.js +24 -0
  40. package/src/js/slides/image.js +56 -0
  41. package/src/js/slides/inline.js +71 -0
  42. package/src/js/slides/video.js +108 -0
  43. package/src/js/utils/helpers.js +541 -0
  44. package/src/postcss/glightbox.css +725 -0
  45. package/tests/slide.test.mjs +130 -0
  46. 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
+ }