GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

third-party/uikit/uikit-2.27.4/js/uikit.js   F
last analyzed

Complexity

Total Complexity 761
Complexity/F 2.11

Size

Lines of Code 3915
Function Count 361

Duplication

Duplicated Lines 3860
Ratio 98.6 %

Importance

Changes 0
Metric Value
eloc 2047
dl 3860
loc 3915
rs 0.8
c 0
b 0
f 0
wmc 761
mnd 400
bc 400
fnc 361
bpm 1.108
cpm 2.108
noi 40

10 Functions

Rating   Name   Duplication   Size   Complexity  
F uikit.js ➔ justify 25 25 187
F uikit.js ➔ swipeDirection 3 3 181
A uikit.js ➔ isPrimaryTouch 3 3 1
F uikit.js ➔ coreAnimation 52 52 95
A uikit.js ➔ cancelLongTap 4 4 2
F uikit.js ➔ scrollToElement 21 21 110
A uikit.js ➔ cancelAll 8 8 5
A uikit.js ➔ longTap 7 7 3
F uikit.js ➔ setContent 25 25 104
F uikit.js ➔ getHeight 21 21 30

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like third-party/uikit/uikit-2.27.4/js/uikit.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*! UIkit 2.27.4 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
2
(function(core) {
3
4
    var uikit;
5
6
    if (!window.jQuery) {
7
        throw new Error('UIkit 2.x requires jQuery');
8
    } else {
9
        uikit = core(window.jQuery);
10
    }
11
12
    if (typeof define == 'function' && define.amd) { // AMD
13
14
        define('uikit', function(){
15
16
            uikit.load = function(res, req, onload, config) {
17
18
                var resources = res.split(','), load = [], i, base = (config.config && config.config.uikit && config.config.uikit.base ? config.config.uikit.base : '').replace(/\/+$/g, '');
19
20
                if (!base) {
21
                    throw new Error('Please define base path to UIkit in the requirejs config.');
22
                }
23
24
                for (i = 0; i < resources.length; i += 1) {
25
                    var resource = resources[i].replace(/\./g, '/');
26
                    load.push(base+'/components/'+resource);
27
                }
28
29
                req(load, function() {
30
                    onload(uikit);
31
                });
32
            };
33
34
            return uikit;
35
        });
36
    }
37
38 View Code Duplication
})(function($) {
39
40
    "use strict";
41
42
    if (window.UIkit2) {
43
        return window.UIkit2;
44
    }
45
46
    var UI = {}, _UI = window.UIkit || undefined;
47
48
    UI.version = '2.27.4';
49
50
    UI.noConflict = function() {
51
        // restore UIkit version
52
        if (_UI) {
53
            window.UIkit = _UI;
54
            $.UIkit      = _UI;
55
            $.fn.uk      = _UI.fn;
56
        }
57
58
        return UI;
59
    };
60
61
    window.UIkit2 = UI;
62
63
    if (!_UI) {
64
        window.UIkit = UI;
65
    }
66
67
    // cache jQuery
68
    UI.$ = $;
69
70
    UI.$doc  = UI.$(document);
71
    UI.$win  = UI.$(window);
72
    UI.$html = UI.$('html');
73
74
    UI.support = {};
75
    UI.support.transition = (function() {
76
77
        var transitionEnd = (function() {
78
79
            var element = document.body || document.documentElement,
80
                transEndEventNames = {
81
                    WebkitTransition : 'webkitTransitionEnd',
82
                    MozTransition    : 'transitionend',
83
                    OTransition      : 'oTransitionEnd otransitionend',
84
                    transition       : 'transitionend'
85
                }, name;
86
87
            for (name in transEndEventNames) {
88
                if (element.style[name] !== undefined) return transEndEventNames[name];
89
            }
90
        }());
91
92
        return transitionEnd && { end: transitionEnd };
93
    })();
94
95
    UI.support.animation = (function() {
96
97
        var animationEnd = (function() {
98
99
            var element = document.body || document.documentElement,
100
                animEndEventNames = {
101
                    WebkitAnimation : 'webkitAnimationEnd',
102
                    MozAnimation    : 'animationend',
103
                    OAnimation      : 'oAnimationEnd oanimationend',
104
                    animation       : 'animationend'
105
                }, name;
106
107
            for (name in animEndEventNames) {
108
                if (element.style[name] !== undefined) return animEndEventNames[name];
109
            }
110
        }());
111
112
        return animationEnd && { end: animationEnd };
113
    })();
114
115
    // requestAnimationFrame polyfill
116
    //https://github.com/darius/requestAnimationFrame
117
    (function() {
118
119
        Date.now = Date.now || function() { return new Date().getTime(); };
0 ignored issues
show
Compatibility Best Practice introduced by
You are extending the built-in type Date. This may have unintended consequences on other objects using this built-in type. Consider subclassing instead.
Loading history...
120
121
        var vendors = ['webkit', 'moz'];
122
        for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
123
            var vp = vendors[i];
124
            window.requestAnimationFrame = window[vp+'RequestAnimationFrame'];
125
            window.cancelAnimationFrame = (window[vp+'CancelAnimationFrame']
126
                                       || window[vp+'CancelRequestAnimationFrame']);
127
        }
128
        if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) // iOS6 is buggy
129
            || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
130
            var lastTime = 0;
131
            window.requestAnimationFrame = function(callback) {
132
                var now = Date.now();
133
                var nextTime = Math.max(lastTime + 16, now);
134
                return setTimeout(function() { callback(lastTime = nextTime); },
135
                                  nextTime - now);
136
            };
137
            window.cancelAnimationFrame = clearTimeout;
138
        }
139
    }());
140
141
    UI.support.touch = (
142
        ('ontouchstart' in document) ||
143
        (window.DocumentTouch && document instanceof window.DocumentTouch)  ||
144
        (window.navigator.msPointerEnabled && window.navigator.msMaxTouchPoints > 0) || //IE 10
145
        (window.navigator.pointerEnabled && window.navigator.maxTouchPoints > 0) || //IE >=11
146
        false
147
    );
148
149
    UI.support.mutationobserver = (window.MutationObserver || window.WebKitMutationObserver || null);
150
151
    UI.Utils = {};
152
153
    UI.Utils.isFullscreen = function() {
154
        return document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement || document.fullscreenElement || false;
155
    };
156
157
    UI.Utils.str2json = function(str, notevil) {
158
        try {
159
            if (notevil) {
160
                return JSON.parse(str
161
                    // wrap keys without quote with valid double quote
162
                    .replace(/([\$\w]+)\s*:/g, function(_, $1){return '"'+$1+'":';})
163
                    // replacing single quote wrapped ones to double quote
164
                    .replace(/'([^']+)'/g, function(_, $1){return '"'+$1+'"';})
165
                );
166
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
167
                return (new Function('', 'var json = ' + str + '; return JSON.parse(JSON.stringify(json));'))();
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
168
            }
169
        } catch(e) { return false; }
170
    };
171
172
    UI.Utils.debounce = function(func, wait, immediate) {
173
        var timeout;
174
        return function() {
175
            var context = this, args = arguments;
176
            var later = function() {
177
                timeout = null;
178
                if (!immediate) func.apply(context, args);
179
            };
180
            var callNow = immediate && !timeout;
181
            clearTimeout(timeout);
0 ignored issues
show
Bug introduced by
The variable timeout seems to not be initialized for all possible execution paths. Are you sure clearTimeout handles undefined variables?
Loading history...
182
            timeout = setTimeout(later, wait);
183
            if (callNow) func.apply(context, args);
184
        };
185
    };
186
187
    UI.Utils.throttle = function (func, limit) {
188
        var wait = false;
189
        return function () {
190
            if (!wait) {
191
                func.call();
192
                wait = true;
193
                setTimeout(function () {
194
                    wait = false;
195
                }, limit);
196
            }
197
        }
198
    };
199
200
    UI.Utils.removeCssRules = function(selectorRegEx) {
201
        var idx, idxs, stylesheet, _i, _j, _k, _len, _len1, _len2, _ref;
202
203
        if(!selectorRegEx) return;
204
205
        setTimeout(function(){
206
            try {
207
              _ref = document.styleSheets;
208
              for (_i = 0, _len = _ref.length; _i < _len; _i++) {
0 ignored issues
show
Bug introduced by
The variable _i is changed as part of the for loop for example by _i++ on line 208. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
209
                stylesheet = _ref[_i];
210
                idxs = [];
211
                stylesheet.cssRules = stylesheet.cssRules;
0 ignored issues
show
Bug introduced by
The variable stylesheet is changed as part of the for loop for example by _ref._i on line 209. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
212
                for (idx = _j = 0, _len1 = stylesheet.cssRules.length; _j < _len1; idx = ++_j) {
0 ignored issues
show
Bug introduced by
The variable _j is changed as part of the for loop for example by ++_j on line 212. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
213
                  if (stylesheet.cssRules[idx].type === CSSRule.STYLE_RULE && selectorRegEx.test(stylesheet.cssRules[idx].selectorText)) {
0 ignored issues
show
Bug introduced by
The variable idx is changed as part of the for loop for example by ++_j on line 212. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
214
                    idxs.unshift(idx);
215
                  }
216
                }
217
                for (_k = 0, _len2 = idxs.length; _k < _len2; _k++) {
0 ignored issues
show
Bug introduced by
The variable _k is changed as part of the for loop for example by _k++ on line 217. Only the value of the last iteration will be visible in this function if it is called after the loop.
Loading history...
218
                  stylesheet.deleteRule(idxs[_k]);
219
                }
220
              }
221
            } catch (_error) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
222
        }, 0);
223
    };
224
225
    UI.Utils.isInView = function(element, options) {
226
227
        var $element = $(element);
228
229
        if (!$element.is(':visible')) {
230
            return false;
231
        }
232
233
        var window_left = UI.$win.scrollLeft(), window_top = UI.$win.scrollTop(), offset = $element.offset(), left = offset.left, top = offset.top;
234
235
        options = $.extend({topoffset:0, leftoffset:0}, options);
236
237
        if (top + $element.height() >= window_top && top - options.topoffset <= window_top + UI.$win.height() &&
238
            left + $element.width() >= window_left && left - options.leftoffset <= window_left + UI.$win.width()) {
239
          return true;
240
        } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
241
          return false;
242
        }
243
    };
244
245
    UI.Utils.checkDisplay = function(context, initanimation) {
246
247
        var elements = UI.$('[data-uk-margin], [data-uk-grid-match], [data-uk-grid-margin], [data-uk-check-display]', context || document), animated;
0 ignored issues
show
Unused Code introduced by
The variable animated seems to be never used. Consider removing it.
Loading history...
248
249
        if (context && !elements.length) {
250
            elements = $(context);
251
        }
252
253
        elements.trigger('display.uk.check');
254
255
        // fix firefox / IE animations
256
        if (initanimation) {
257
258
            if (typeof(initanimation)!='string') {
259
                initanimation = '[class*="uk-animation-"]';
260
            }
261
262
            elements.find(initanimation).each(function(){
263
264
                var ele  = UI.$(this),
265
                    cls  = ele.attr('class'),
266
                    anim = cls.match(/uk-animation-(.+)/);
267
268
                ele.removeClass(anim[0]).width();
269
270
                ele.addClass(anim[0]);
271
            });
272
        }
273
274
        return elements;
275
    };
276
277
    UI.Utils.options = function(string) {
278
279
        if ($.type(string)!='string') return string;
280
281
        if (string.indexOf(':') != -1 && string.trim().substr(-1) != '}') {
282
            string = '{'+string+'}';
283
        }
284
285
        var start = (string ? string.indexOf("{") : -1), options = {};
286
287
        if (start != -1) {
288
            try {
289
                options = UI.Utils.str2json(string.substr(start));
290
            } catch (e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
291
        }
292
293
        return options;
294
    };
295
296
    UI.Utils.animate = function(element, cls) {
297
298
        var d = $.Deferred();
299
300
        element = UI.$(element);
301
302
        element.css('display', 'none').addClass(cls).one(UI.support.animation.end, function() {
303
            element.removeClass(cls);
304
            d.resolve();
305
        });
306
307
        element.css('display', '');
308
309
        return d.promise();
310
    };
311
312
    UI.Utils.uid = function(prefix) {
313
        return (prefix || 'id') + (new Date().getTime())+"RAND"+(Math.ceil(Math.random() * 100000));
314
    };
315
316
    UI.Utils.template = function(str, data) {
317
318
        var tokens = str.replace(/\n/g, '\\n').replace(/\{\{\{\s*(.+?)\s*\}\}\}/g, "{{!$1}}").split(/(\{\{\s*(.+?)\s*\}\})/g),
319
            i=0, toc, cmd, prop, val, fn, output = [], openblocks = 0;
0 ignored issues
show
Unused Code introduced by
The variable val seems to be never used. Consider removing it.
Loading history...
320
321
        while(i < tokens.length) {
322
323
            toc = tokens[i];
324
325
            if(toc.match(/\{\{\s*(.+?)\s*\}\}/)) {
326
                i = i + 1;
327
                toc  = tokens[i];
328
                cmd  = toc[0];
329
                prop = toc.substring(toc.match(/^(\^|\#|\!|\~|\:)/) ? 1:0);
330
331
                switch(cmd) {
332
                    case '~':
333
                        output.push('for(var $i=0;$i<'+prop+'.length;$i++) { var $item = '+prop+'[$i];');
334
                        openblocks++;
335
                        break;
336
                    case ':':
337
                        output.push('for(var $key in '+prop+') { var $val = '+prop+'[$key];');
338
                        openblocks++;
339
                        break;
340
                    case '#':
341
                        output.push('if('+prop+') {');
342
                        openblocks++;
343
                        break;
344
                    case '^':
345
                        output.push('if(!'+prop+') {');
346
                        openblocks++;
347
                        break;
348
                    case '/':
349
                        output.push('}');
350
                        openblocks--;
351
                        break;
352
                    case '!':
353
                        output.push('__ret.push('+prop+');');
354
                        break;
355
                    default:
356
                        output.push('__ret.push(escape('+prop+'));');
357
                        break;
358
                }
359
            } else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
360
                output.push("__ret.push('"+toc.replace(/\'/g, "\\'")+"');");
361
            }
362
            i = i + 1;
363
        }
364
365
        fn  = new Function('$data', [
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
366
            'var __ret = [];',
367
            'try {',
368
            'with($data){', (!openblocks ? output.join('') : '__ret = ["Not all blocks are closed correctly."]'), '};',
369
            '}catch(e){__ret = [e.message];}',
370
            'return __ret.join("").replace(/\\n\\n/g, "\\n");',
371
            "function escape(html) { return String(html).replace(/&/g, '&amp;').replace(/\"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');}"
372
        ].join("\n"));
373
374
        return data ? fn(data) : fn;
375
    };
376
377
    UI.Utils.focus = function(element, extra) {
378
379
        element = $(element);
380
381
        if (!element.length) {
382
            return element;
383
        }
384
385
        var autofocus = element.find('[autofocus]:first'), tabidx;
386
387
        if (autofocus.length) {
388
            return autofocus.focus();
389
        }
390
391
        autofocus = element.find(':input'+(extra && (','+extra) || '')).first();
392
393
        if (autofocus.length) {
394
            return autofocus.focus();
395
        }
396
397
        if (!element.attr('tabindex')) {
398
            tabidx = 1000;
399
            element.attr('tabindex', tabidx);
400
        }
401
402
        element[0].focus();
403
404
        if (tabidx) {
405
            element.attr('tabindex', '');
406
        }
407
408
        return element;
409
    }
410
411
    UI.Utils.events       = {};
412
    UI.Utils.events.click = UI.support.touch ? 'tap' : 'click';
413
414
    // deprecated
415
416
    UI.fn = function(command, options) {
417
418
        var args = arguments, cmd = command.match(/^([a-z\-]+)(?:\.([a-z]+))?/i), component = cmd[1], method = cmd[2];
419
420
        if (!UI[component]) {
421
            $.error('UIkit component [' + component + '] does not exist.');
422
            return this;
423
        }
424
425
        return this.each(function() {
426
            var $this = $(this), data = $this.data(component);
427
            if (!data) $this.data(component, (data = UI[component](this, method ? undefined : options)));
428
            if (method) data[method].apply(data, Array.prototype.slice.call(args, 1));
429
        });
430
    };
431
432
    $.UIkit          = UI;
433
    $.fn.uk          = UI.fn;
434
435
    UI.langdirection = UI.$html.attr("dir") == "rtl" ? "right" : "left";
436
437
    UI.components    = {};
438
439
    UI.component = function(name, def, override) {
440
441
        if (UI.components[name] && !override) {
442
            return UI.components[name];
443
        }
444
445
        var fn = function(element, options) {
446
447
            var $this = this;
448
449
            this.UIkit   = UI;
450
            this.element = element ? UI.$(element) : null;
451
            this.options = $.extend(true, {}, this.defaults, options);
452
            this.plugins = {};
453
454
            if (this.element) {
455
                this.element.data(name, this);
456
            }
457
458
            this.init();
459
460
            (this.options.plugins.length ? this.options.plugins : Object.keys(fn.plugins)).forEach(function(plugin) {
461
462
                if (fn.plugins[plugin].init) {
463
                    fn.plugins[plugin].init($this);
464
                    $this.plugins[plugin] = true;
465
                }
466
467
            });
468
469
            this.trigger('init.uk.component', [name, this]);
470
471
            return this;
472
        };
473
474
        fn.plugins = {};
475
476
        $.extend(true, fn.prototype, {
477
478
            defaults : {plugins: []},
479
480
            boot: function(){},
481
            init: function(){},
482
483
            on: function(a1,a2,a3){
484
                return UI.$(this.element || this).on(a1,a2,a3);
485
            },
486
487
            one: function(a1,a2,a3){
488
                return UI.$(this.element || this).one(a1,a2,a3);
489
            },
490
491
            off: function(evt){
492
                return UI.$(this.element || this).off(evt);
493
            },
494
495
            trigger: function(evt, params) {
496
                return UI.$(this.element || this).trigger(evt, params);
497
            },
498
499
            find: function(selector) {
500
                return UI.$(this.element ? this.element: []).find(selector);
501
            },
502
503
            proxy: function(obj, methods) {
504
505
                var $this = this;
506
507
                methods.split(' ').forEach(function(method) {
508
                    if (!$this[method]) $this[method] = function() { return obj[method].apply(obj, arguments); };
509
                });
510
            },
511
512
            mixin: function(obj, methods) {
513
514
                var $this = this;
515
516
                methods.split(' ').forEach(function(method) {
517
                    if (!$this[method]) $this[method] = obj[method].bind($this);
518
                });
519
            },
520
521
            option: function() {
522
523
                if (arguments.length == 1) {
524
                    return this.options[arguments[0]] || undefined;
525
                } else if (arguments.length == 2) {
526
                    this.options[arguments[0]] = arguments[1];
527
                }
528
            }
529
530
        }, def);
531
532
        this.components[name] = fn;
533
534
        this[name] = function() {
535
536
            var element, options;
537
538
            if (arguments.length) {
539
540
                switch(arguments.length) {
541
                    case 1:
542
543
                        if (typeof arguments[0] === 'string' || arguments[0].nodeType || arguments[0] instanceof jQuery) {
544
                            element = $(arguments[0]);
545
                        } else {
546
                            options = arguments[0];
547
                        }
548
549
                        break;
550
                    case 2:
551
552
                        element = $(arguments[0]);
553
                        options = arguments[1];
554
                        break;
555
                }
556
            }
557
558
            if (element && element.data(name)) {
559
                return element.data(name);
560
            }
561
562
            return (new UI.components[name](element, options));
563
        };
564
565
        if (UI.domready) {
566
            UI.component.boot(name);
567
        }
568
569
        return fn;
570
    };
571
572
    UI.plugin = function(component, name, def) {
573
        this.components[component].plugins[name] = def;
574
    };
575
576
    UI.component.boot = function(name) {
577
578
        if (UI.components[name].prototype && UI.components[name].prototype.boot && !UI.components[name].booted) {
579
            UI.components[name].prototype.boot.apply(UI, []);
580
            UI.components[name].booted = true;
581
        }
582
    };
583
584
    UI.component.bootComponents = function() {
585
586
        for (var component in UI.components) {
0 ignored issues
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
587
            UI.component.boot(component);
588
        }
589
    };
590
591
592
    // DOM mutation save ready helper function
593
594
    UI.domObservers = [];
595
    UI.domready     = false;
596
597
    UI.ready = function(fn) {
598
599
        UI.domObservers.push(fn);
600
601
        if (UI.domready) {
602
            fn(document);
603
        }
604
    };
605
606
    UI.on = function(a1,a2,a3){
607
608
        if (a1 && a1.indexOf('ready.uk.dom') > -1 && UI.domready) {
609
            a2.apply(UI.$doc);
610
        }
611
612
        return UI.$doc.on(a1,a2,a3);
613
    };
614
615
    UI.one = function(a1,a2,a3){
616
617
        if (a1 && a1.indexOf('ready.uk.dom') > -1 && UI.domready) {
618
            a2.apply(UI.$doc);
619
            return UI.$doc;
620
        }
621
622
        return UI.$doc.one(a1,a2,a3);
623
    };
624
625
    UI.trigger = function(evt, params) {
626
        return UI.$doc.trigger(evt, params);
627
    };
628
629
    UI.domObserve = function(selector, fn) {
630
631
        if(!UI.support.mutationobserver) return;
632
633
        fn = fn || function() {};
634
635
        UI.$(selector).each(function() {
636
637
            var element  = this,
638
                $element = UI.$(element);
639
640
            if ($element.data('observer')) {
641
                return;
642
            }
643
644
            try {
645
646
                var observer = new UI.support.mutationobserver(UI.Utils.debounce(function(mutations) {
647
                    fn.apply(element, [$element]);
648
                    $element.trigger('changed.uk.dom');
649
                }, 50), {childList: true, subtree: true});
650
651
                // pass in the target node, as well as the observer options
652
                observer.observe(element, { childList: true, subtree: true });
653
654
                $element.data('observer', observer);
655
656
            } catch(e) {}
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
657
        });
658
    };
659
660
    UI.init = function(root) {
661
662
        root = root || document;
663
664
        UI.domObservers.forEach(function(fn){
665
            fn(root);
666
        });
667
    };
668
669
    UI.on('domready.uk.dom', function(){
670
671
        UI.init();
672
673
        if (UI.domready) UI.Utils.checkDisplay();
674
    });
675
676
    document.addEventListener('DOMContentLoaded', function(){
677
678
        var domReady = function() {
679
680
            UI.$body = UI.$('body');
681
682
            UI.trigger('beforeready.uk.dom');
683
684
            UI.component.bootComponents();
685
686
            // custom scroll observer
687
            var rafToken = requestAnimationFrame((function(){
688
689
                var memory = {dir: {x:0, y:0}, x: window.pageXOffset, y:window.pageYOffset};
690
691
                var fn = function(){
692
                    // reading this (window.page[X|Y]Offset) causes a full page recalc of the layout in Chrome,
693
                    // so we only want to do this once
694
                    var wpxo = window.pageXOffset;
695
                    var wpyo = window.pageYOffset;
696
697
                    // Did the scroll position change since the last time we were here?
698
                    if (memory.x != wpxo || memory.y != wpyo) {
699
700
                        // Set the direction of the scroll and store the new position
701
                        if (wpxo != memory.x) {memory.dir.x = wpxo > memory.x ? 1:-1; } else { memory.dir.x = 0; }
702
                        if (wpyo != memory.y) {memory.dir.y = wpyo > memory.y ? 1:-1; } else { memory.dir.y = 0; }
703
704
                        memory.x = wpxo;
705
                        memory.y = wpyo;
706
707
                        // Trigger the scroll event, this could probably be sent using memory.clone() but this is
708
                        // more explicit and easier to see exactly what is being sent in the event.
709
                        UI.$doc.trigger('scrolling.uk.document', [{
710
                            dir: {x: memory.dir.x, y: memory.dir.y}, x: wpxo, y: wpyo
711
                        }]);
712
                    }
713
714
                    cancelAnimationFrame(rafToken);
715
                    rafToken = requestAnimationFrame(fn);
716
                };
717
718
                if (UI.support.touch) {
719
                    UI.$html.on('touchmove touchend MSPointerMove MSPointerUp pointermove pointerup', fn);
720
                }
721
722
                if (memory.x || memory.y) fn();
723
724
                return fn;
725
726
            })());
727
728
            // run component init functions on dom
729
            UI.trigger('domready.uk.dom');
730
731
            if (UI.support.touch) {
732
733
                // remove css hover rules for touch devices
734
                // UI.Utils.removeCssRules(/\.uk-(?!navbar).*:hover/);
735
736
                // viewport unit fix for uk-height-viewport - should be fixed in iOS 8
737
                if (navigator.userAgent.match(/(iPad|iPhone|iPod)/g)) {
738
739
                    UI.$win.on('load orientationchange resize', UI.Utils.debounce((function(){
740
741
                        var fn = function() {
742
                            $('.uk-height-viewport').css('height', window.innerHeight);
743
                            return fn;
744
                        };
745
746
                        return fn();
747
748
                    })(), 100));
749
                }
750
            }
751
752
            UI.trigger('afterready.uk.dom');
753
754
            // mark that domready is left behind
755
            UI.domready = true;
756
757
            // auto init js components
758
            if (UI.support.mutationobserver) {
759
760
                var initFn = UI.Utils.debounce(function(){
761
                    requestAnimationFrame(function(){ UI.init(document.body);});
762
                }, 10);
763
764
                (new UI.support.mutationobserver(function(mutations) {
765
766
                    var init = false;
767
768
                    mutations.every(function(mutation){
769
770
                        if (mutation.type != 'childList') return true;
771
772
                        for (var i = 0, node; i < mutation.addedNodes.length; ++i) {
773
774
                            node = mutation.addedNodes[i];
775
776
                            if (node.outerHTML && node.outerHTML.indexOf('data-uk-') !== -1) {
777
                                return (init = true) && false;
778
                            }
779
                        }
780
                        return true;
781
                    });
782
783
                    if (init) initFn();
784
785
                })).observe(document.body, {childList: true, subtree: true});
786
            }
787
        };
788
789
        if (document.readyState == 'complete' || document.readyState == 'interactive') {
790
            setTimeout(domReady);
791
        }
792
793
        return domReady;
794
795
    }());
796
797
    // add touch identifier class
798
    UI.$html.addClass(UI.support.touch ? 'uk-touch' : 'uk-notouch');
799
800
    // add uk-hover class on tap to support overlays on touch devices
801
    if (UI.support.touch) {
802
803
        var hoverset = false,
804
            exclude,
805
            hovercls = 'uk-hover',
806
            selector = '.uk-overlay, .uk-overlay-hover, .uk-overlay-toggle, .uk-animation-hover, .uk-has-hover';
807
808
        UI.$html.on('mouseenter touchstart MSPointerDown pointerdown', selector, function() {
809
810
            if (hoverset) $('.'+hovercls).removeClass(hovercls);
811
812
            hoverset = $(this).addClass(hovercls);
813
814
        }).on('mouseleave touchend MSPointerUp pointerup', function(e) {
815
816
            exclude = $(e.target).parents(selector);
817
818
            if (hoverset) {
819
                hoverset.not(exclude).removeClass(hovercls);
820
            }
821
        });
822
    }
823
824
    return UI;
825
});
826
827
//  Based on Zeptos touch.js
828
//  https://raw.github.com/madrobby/zepto/master/src/touch.js
829
//  Zepto.js may be freely distributed under the MIT license.
830
831 View Code Duplication
;(function($){
832
833
  if ($.fn.swipeLeft) {
834
    return;
835
  }
836
837
838
  var touch = {}, touchTimeout, tapTimeout, swipeTimeout, longTapTimeout, longTapDelay = 750, gesture;
839
  var hasTouchEvents = 'ontouchstart' in window,
840
      hasPointerEvents = window.PointerEvent,
841
      hasTouch = hasTouchEvents
842
      || window.DocumentTouch && document instanceof DocumentTouch
843
      || navigator.msPointerEnabled && navigator.msMaxTouchPoints > 0 // IE 10
844
      || navigator.pointerEnabled && navigator.maxTouchPoints > 0; // IE >=11
845
846
  function swipeDirection(x1, x2, y1, y2) {
847
    return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down');
848
  }
849
850
  function longTap() {
851
    longTapTimeout = null;
852
    if (touch.last) {
853
      if ( touch.el !== undefined ) touch.el.trigger('longTap');
854
      touch = {};
855
    }
856
  }
857
858
  function cancelLongTap() {
859
    if (longTapTimeout) clearTimeout(longTapTimeout);
860
    longTapTimeout = null;
861
  }
862
863
  function cancelAll() {
864
    if (touchTimeout)   clearTimeout(touchTimeout);
865
    if (tapTimeout)     clearTimeout(tapTimeout);
866
    if (swipeTimeout)   clearTimeout(swipeTimeout);
867
    if (longTapTimeout) clearTimeout(longTapTimeout);
868
    touchTimeout = tapTimeout = swipeTimeout = longTapTimeout = null;
869
    touch = {};
870
  }
871
872
  function isPrimaryTouch(event){
873
    return event.pointerType == event.MSPOINTER_TYPE_TOUCH && event.isPrimary;
874
  }
875
876
  $(function(){
877
    var now, delta, deltaX = 0, deltaY = 0, firstTouch;
878
879
    if ('MSGesture' in window) {
880
      gesture = new MSGesture();
881
      gesture.target = document.body;
882
    }
883
884
    $(document)
885
      .on('MSGestureEnd gestureend', function(e){
886
887
        var swipeDirectionFromVelocity = e.originalEvent.velocityX > 1 ? 'Right' : e.originalEvent.velocityX < -1 ? 'Left' : e.originalEvent.velocityY > 1 ? 'Down' : e.originalEvent.velocityY < -1 ? 'Up' : null;
888
889
        if (swipeDirectionFromVelocity && touch.el !== undefined) {
890
          touch.el.trigger('swipe');
891
          touch.el.trigger('swipe'+ swipeDirectionFromVelocity);
892
        }
893
      })
894
      // MSPointerDown: for IE10
895
      // pointerdown: for IE11
896
      .on('touchstart MSPointerDown pointerdown', function(e){
897
898
        if(e.type == 'MSPointerDown' && !isPrimaryTouch(e.originalEvent)) return;
899
900
        firstTouch = (e.type == 'MSPointerDown' || e.type == 'pointerdown') ? e : e.originalEvent.touches[0];
901
902
        now      = Date.now();
903
        delta    = now - (touch.last || now);
904
        touch.el = $('tagName' in firstTouch.target ? firstTouch.target : firstTouch.target.parentNode);
905
906
        if(touchTimeout) clearTimeout(touchTimeout);
907
908
        touch.x1 = firstTouch.pageX;
909
        touch.y1 = firstTouch.pageY;
910
911
        if (delta > 0 && delta <= 250) touch.isDoubleTap = true;
912
913
        touch.last = now;
914
        longTapTimeout = setTimeout(longTap, longTapDelay);
915
916
        // adds the current touch contact for IE gesture recognition
917
        if (e.originalEvent && e.originalEvent.pointerId && gesture && ( e.type == 'MSPointerDown' || e.type == 'pointerdown' || e.type == 'touchstart' ) ) {
918
          gesture.addPointer(e.originalEvent.pointerId);
919
        }
920
921
      })
922
      // MSPointerMove: for IE10
923
      // pointermove: for IE11
924
      .on('touchmove MSPointerMove pointermove', function(e){
925
926
        if (e.type == 'MSPointerMove' && !isPrimaryTouch(e.originalEvent)) return;
927
928
        firstTouch = (e.type == 'MSPointerMove' || e.type == 'pointermove') ? e : e.originalEvent.touches[0];
929
930
        cancelLongTap();
931
        touch.x2 = firstTouch.pageX;
932
        touch.y2 = firstTouch.pageY;
933
934
        deltaX += Math.abs(touch.x1 - touch.x2);
935
        deltaY += Math.abs(touch.y1 - touch.y2);
936
      })
937
      // MSPointerUp: for IE10
938
      // pointerup: for IE11
939
      .on('touchend MSPointerUp pointerup', function(e){
940
941
        if (e.type == 'MSPointerUp' && !isPrimaryTouch(e.originalEvent)) return;
942
943
        cancelLongTap();
944
945
        // swipe
946
        if ((touch.x2 && Math.abs(touch.x1 - touch.x2) > 30) || (touch.y2 && Math.abs(touch.y1 - touch.y2) > 30)){
947
948
          swipeTimeout = setTimeout(function() {
949
            if ( touch.el !== undefined ) {
950
              touch.el.trigger('swipe');
951
              touch.el.trigger('swipe' + (swipeDirection(touch.x1, touch.x2, touch.y1, touch.y2)));
952
            }
953
            touch = {};
954
          }, 0);
955
956
        // normal tap
957
        } else if ('last' in touch) {
958
959
          // don't fire tap when delta position changed by more than 30 pixels,
960
          // for instance when moving to a point and back to origin
961
          if (isNaN(deltaX) || (deltaX < 30 && deltaY < 30)) {
962
            // delay by one tick so we can cancel the 'tap' event if 'scroll' fires
963
            // ('tap' fires before 'scroll')
964
            tapTimeout = setTimeout(function() {
965
966
              // trigger universal 'tap' with the option to cancelTouch()
967
              // (cancelTouch cancels processing of single vs double taps for faster 'tap' response)
968
              var event = $.Event('tap');
969
              event.cancelTouch = cancelAll;
970
              if ( touch.el !== undefined ) touch.el.trigger(event);
971
972
              // trigger double tap immediately
973
              if (touch.isDoubleTap) {
974
                if ( touch.el !== undefined ) touch.el.trigger('doubleTap');
975
                touch = {};
976
              }
977
978
              // trigger single tap after 250ms of inactivity
979
              else {
980
                touchTimeout = setTimeout(function(){
981
                  touchTimeout = null;
982
                  if ( touch.el !== undefined ) touch.el.trigger('singleTap');
983
                  touch = {};
984
                }, 250);
985
              }
986
            }, 0);
987
          } else {
988
            touch = {};
989
          }
990
          deltaX = deltaY = 0;
991
        }
992
      })
993
      // when the browser window loses focus,
994
      // for example when a modal dialog is shown,
995
      // cancel all ongoing events
996
      .on('touchcancel MSPointerCancel pointercancel', function(e){
997
998
        // Ignore pointercancel if the event supports touch events, to prevent pointercancel in swipe gesture
999
        if ((e.type == 'touchcancel' && hasTouchEvents && hasTouch) || (!hasTouchEvents && e.type == 'pointercancel' && hasPointerEvents)) {
1000
          cancelAll();
1001
        }
1002
1003
    });
1004
1005
    // scrolling the window indicates intention of the user
1006
    // to scroll, not tap or swipe, so cancel all ongoing events
1007
    $(window).on('scroll', cancelAll);
1008
  });
1009
1010
  ['swipe', 'swipeLeft', 'swipeRight', 'swipeUp', 'swipeDown', 'doubleTap', 'tap', 'singleTap', 'longTap'].forEach(function(eventName){
1011
    $.fn[eventName] = function(callback){ return $(this).on(eventName, callback); };
1012
  });
1013
})(jQuery);
1014
1015 View Code Duplication
(function(UI) {
1016
1017
    "use strict";
1018
1019
    var stacks = [];
1020
1021
    UI.component('stackMargin', {
1022
1023
        defaults: {
1024
            cls: 'uk-margin-small-top',
1025
            rowfirst: false,
1026
            observe: false
1027
        },
1028
1029
        boot: function() {
1030
1031
            // init code
1032
            UI.ready(function(context) {
1033
1034
                UI.$('[data-uk-margin]', context).each(function() {
1035
1036
                    var ele = UI.$(this);
1037
1038
                    if (!ele.data('stackMargin')) {
1039
                        UI.stackMargin(ele, UI.Utils.options(ele.attr('data-uk-margin')));
1040
                    }
1041
                });
1042
            });
1043
        },
1044
1045
        init: function() {
1046
1047
            var $this = this;
1048
1049
            UI.$win.on('resize orientationchange', (function() {
1050
1051
                var fn = function() {
1052
                    $this.process();
1053
                };
1054
1055
                UI.$(function() {
1056
                    fn();
1057
                    UI.$win.on('load', fn);
1058
                });
1059
1060
                return UI.Utils.debounce(fn, 20);
1061
            })());
1062
1063
            this.on('display.uk.check', function(e) {
1064
                if (this.element.is(':visible')) this.process();
1065
            }.bind(this));
1066
1067
            if (this.options.observe) {
1068
1069
                UI.domObserve(this.element, function(e) {
1070
                    if ($this.element.is(':visible')) $this.process();
1071
                });
1072
            }
1073
1074
            stacks.push(this);
1075
        },
1076
1077
        process: function() {
1078
1079
            var $this = this, columns = this.element.children();
0 ignored issues
show
Unused Code introduced by
The variable $this seems to be never used. Consider removing it.
Loading history...
1080
1081
            UI.Utils.stackMargin(columns, this.options);
1082
1083
            if (!this.options.rowfirst || !columns.length) {
1084
                return this;
1085
            }
1086
1087
            // Mark first column elements
1088
            var group = {}, minleft = false;
1089
1090
            columns.removeClass(this.options.rowfirst).each(function(offset, $ele){
1091
1092
                $ele = UI.$(this);
1093
1094
                if (this.style.display != 'none') {
1095
                    offset = $ele.offset().left;
1096
                    ((group[offset] = group[offset] || []) && group[offset]).push(this);
1097
                    minleft = minleft === false ? offset : Math.min(minleft, offset);
1098
                }
1099
            });
1100
1101
            UI.$(group[minleft]).addClass(this.options.rowfirst);
1102
1103
            return this;
1104
        }
1105
1106
    });
1107
1108
1109
    // responsive element e.g. iframes
1110
1111
    (function(){
1112
1113
        var elements = [], check = function(ele) {
1114
1115
            if (!ele.is(':visible')) return;
1116
1117
            var width  = ele.parent().width(),
1118
                iwidth = ele.data('width'),
1119
                ratio  = (width / iwidth),
1120
                height = Math.floor(ratio * ele.data('height'));
1121
1122
            ele.css({height: (width < iwidth) ? height : ele.data('height')});
1123
        };
1124
1125
        UI.component('responsiveElement', {
1126
1127
            defaults: {},
1128
1129
            boot: function() {
1130
1131
                // init code
1132
                UI.ready(function(context) {
1133
1134
                    UI.$('iframe.uk-responsive-width, [data-uk-responsive]', context).each(function() {
1135
1136
                        var ele = UI.$(this), obj;
1137
1138
                        if (!ele.data('responsiveElement')) {
1139
                            obj = UI.responsiveElement(ele, {});
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
1140
                        }
1141
                    });
1142
                });
1143
            },
1144
1145
            init: function() {
1146
1147
                var ele = this.element;
1148
1149
                if (ele.attr('width') && ele.attr('height')) {
1150
1151
                    ele.data({
1152
                        width : ele.attr('width'),
1153
                        height: ele.attr('height')
1154
                    }).on('display.uk.check', function(){
1155
                        check(ele);
1156
                    });
1157
1158
                    check(ele);
1159
1160
                    elements.push(ele);
1161
                }
1162
            }
1163
        });
1164
1165
        UI.$win.on('resize load', UI.Utils.debounce(function(){
1166
1167
            elements.forEach(function(ele){
1168
                check(ele);
1169
            });
1170
1171
        }, 15));
1172
1173
    })();
1174
1175
1176
    // helper
1177
1178
    UI.Utils.stackMargin = function(elements, options) {
1179
1180
        options = UI.$.extend({
1181
            cls: 'uk-margin-small-top'
1182
        }, options);
1183
1184
        elements = UI.$(elements).removeClass(options.cls);
1185
1186
        var min = false;
1187
1188
        elements.each(function(offset, height, pos, $ele){
1189
1190
            $ele   = UI.$(this);
1191
1192
            if ($ele.css('display') != 'none') {
1193
1194
                offset = $ele.offset();
1195
                height = $ele.outerHeight();
1196
                pos    = offset.top + height;
1197
1198
                $ele.data({
1199
                    ukMarginPos: pos,
1200
                    ukMarginTop: offset.top
1201
                });
1202
1203
                if (min === false || (offset.top < min.top) ) {
1204
1205
                    min = {
1206
                        top  : offset.top,
1207
                        left : offset.left,
1208
                        pos  : pos
1209
                    };
1210
                }
1211
            }
1212
1213
        }).each(function($ele) {
1214
1215
            $ele   = UI.$(this);
1216
1217
            if ($ele.css('display') != 'none' && $ele.data('ukMarginTop') > min.top && $ele.data('ukMarginPos') > min.pos) {
1218
                $ele.addClass(options.cls);
1219
            }
1220
        });
1221
    };
1222
1223
    UI.Utils.matchHeights = function(elements, options) {
1224
1225
        elements = UI.$(elements).css('min-height', '');
1226
        options  = UI.$.extend({ row : true }, options);
1227
1228
        var matchHeights = function(group){
1229
1230
            if (group.length < 2) return;
1231
1232
            var max = 0;
1233
1234
            group.each(function() {
1235
                max = Math.max(max, UI.$(this).outerHeight());
1236
            }).each(function() {
1237
1238
                var element = UI.$(this),
1239
                    height  = max - (element.css('box-sizing') == 'border-box' ? 0 : (element.outerHeight() - element.height()));
1240
1241
                element.css('min-height', height + 'px');
1242
            });
1243
        };
1244
1245
        if (options.row) {
1246
1247
            elements.first().width(); // force redraw
1248
1249
            setTimeout(function(){
1250
1251
                var lastoffset = false, group = [];
1252
1253
                elements.each(function() {
1254
1255
                    var ele = UI.$(this), offset = ele.offset().top;
1256
1257
                    if (offset != lastoffset && group.length) {
1258
1259
                        matchHeights(UI.$(group));
1260
                        group  = [];
1261
                        offset = ele.offset().top;
1262
                    }
1263
1264
                    group.push(ele);
1265
                    lastoffset = offset;
1266
                });
1267
1268
                if (group.length) {
1269
                    matchHeights(UI.$(group));
1270
                }
1271
1272
            }, 0);
1273
1274
        } else {
1275
            matchHeights(elements);
1276
        }
1277
    };
1278
1279
    (function(cacheSvgs){
1280
1281
        UI.Utils.inlineSvg = function(selector, root) {
1282
1283
            var images = UI.$(selector || 'img[src$=".svg"]', root || document).each(function(){
0 ignored issues
show
Unused Code introduced by
The variable images seems to be never used. Consider removing it.
Loading history...
1284
1285
                var img = UI.$(this),
1286
                    src = img.attr('src');
1287
1288
                if (!cacheSvgs[src]) {
1289
1290
                    var d = UI.$.Deferred();
1291
1292
                    UI.$.get(src, {nc: Math.random()}, function(data){
1293
                        d.resolve(UI.$(data).find('svg'));
1294
                    });
1295
1296
                    cacheSvgs[src] = d.promise();
1297
                }
1298
1299
                cacheSvgs[src].then(function(svg) {
1300
1301
                    var $svg = UI.$(svg).clone();
1302
1303
                    if (img.attr('id')) $svg.attr('id', img.attr('id'));
1304
                    if (img.attr('class')) $svg.attr('class', img.attr('class'));
1305
                    if (img.attr('style')) $svg.attr('style', img.attr('style'));
1306
1307
                    if (img.attr('width')) {
1308
                        $svg.attr('width', img.attr('width'));
1309
                        if (!img.attr('height'))  $svg.removeAttr('height');
1310
                    }
1311
1312
                    if (img.attr('height')){
1313
                        $svg.attr('height', img.attr('height'));
1314
                        if (!img.attr('width')) $svg.removeAttr('width');
1315
                    }
1316
1317
                    img.replaceWith($svg);
1318
                });
1319
            });
1320
        };
1321
1322
        // init code
1323
        UI.ready(function(context) {
1324
            UI.Utils.inlineSvg('[data-uk-svg]', context);
1325
        });
1326
1327
    })({});
1328
1329
    UI.Utils.getCssVar = function(name) {
1330
1331
        /* usage in css:  .var-name:before { content:"xyz" } */
1332
1333
        var val, doc = document.documentElement, element = doc.appendChild(document.createElement('div'));
1334
1335
        element.classList.add('var-'+name);
1336
1337
        try {
1338
            val = JSON.parse(val = getComputedStyle(element, ':before').content.replace(/^["'](.*)["']$/, '$1'));
1339
        } catch (e) {
1340
            val = undefined;
1341
        }
1342
1343
        doc.removeChild(element);
1344
1345
        return val;
1346
    }
1347
1348
})(UIkit2);
1349
1350 View Code Duplication
(function(UI) {
1351
1352
    "use strict";
1353
1354
    UI.component('smoothScroll', {
1355
1356
        boot: function() {
1357
1358
            // init code
1359
            UI.$html.on('click.smooth-scroll.uikit', '[data-uk-smooth-scroll]', function(e) {
1360
                var ele = UI.$(this);
1361
1362
                if (!ele.data('smoothScroll')) {
1363
                    var obj = UI.smoothScroll(ele, UI.Utils.options(ele.attr('data-uk-smooth-scroll')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
1364
                    ele.trigger('click');
1365
                }
1366
1367
                return false;
1368
            });
1369
        },
1370
1371
        init: function() {
1372
1373
            var $this = this;
1374
1375
            this.on('click', function(e) {
1376
                e.preventDefault();
1377
                scrollToElement(UI.$(this.hash).length ? UI.$(this.hash) : UI.$('body'), $this.options);
1378
            });
1379
        }
1380
    });
1381
1382
    function scrollToElement(ele, options) {
1383
1384
        options = UI.$.extend({
1385
            duration: 1000,
1386
            transition: 'easeOutExpo',
1387
            offset: 0,
1388
            complete: function(){}
1389
        }, options);
1390
1391
        // get / set parameters
1392
        var target    = ele.offset().top - options.offset,
1393
            docheight = UI.$doc.height(),
1394
            winheight = window.innerHeight;
1395
1396
        if ((target + winheight) > docheight) {
1397
            target = docheight - winheight;
1398
        }
1399
1400
        // animate to target, fire callback when done
1401
        UI.$('html,body').stop().animate({scrollTop: target}, options.duration, options.transition).promise().done(options.complete);
1402
    }
1403
1404
    UI.Utils.scrollToElement = scrollToElement;
1405
1406
    if (!UI.$.easing.easeOutExpo) {
1407
        UI.$.easing.easeOutExpo = function(x, t, b, c, d) { return (t == d) ? b + c : c * (-Math.pow(2, -10 * t / d) + 1) + b; };
1408
    }
1409
1410
})(UIkit2);
1411
1412 View Code Duplication
(function(UI) {
1413
1414
    "use strict";
1415
1416
    var $win           = UI.$win,
1417
        $doc           = UI.$doc,
1418
        scrollspies    = [],
1419
        checkScrollSpy = function() {
1420
            for(var i=0; i < scrollspies.length; i++) {
1421
                window.requestAnimationFrame.apply(window, [scrollspies[i].check]);
1422
            }
1423
        };
1424
1425
    UI.component('scrollspy', {
1426
1427
        defaults: {
1428
            target     : false,
1429
            cls        : 'uk-scrollspy-inview',
1430
            initcls    : 'uk-scrollspy-init-inview',
1431
            topoffset  : 0,
1432
            leftoffset : 0,
1433
            repeat     : false,
1434
            delay      : 0
1435
        },
1436
1437
        boot: function() {
1438
1439
            // listen to scroll and resize
1440
            $doc.on('scrolling.uk.document', checkScrollSpy);
1441
            $win.on('load resize orientationchange', UI.Utils.debounce(checkScrollSpy, 50));
1442
1443
            // init code
1444
            UI.ready(function(context) {
1445
1446
                UI.$('[data-uk-scrollspy]', context).each(function() {
1447
1448
                    var element = UI.$(this);
1449
1450
                    if (!element.data('scrollspy')) {
1451
                        var obj = UI.scrollspy(element, UI.Utils.options(element.attr('data-uk-scrollspy')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
1452
                    }
1453
                });
1454
            });
1455
        },
1456
1457
        init: function() {
1458
1459
            var $this = this, inviewstate, initinview, togglecls = this.options.cls.split(/,/), fn = function(){
0 ignored issues
show
Unused Code introduced by
The variable inviewstate seems to be never used. Consider removing it.
Loading history...
1460
1461
                var elements     = $this.options.target ? $this.element.find($this.options.target) : $this.element,
1462
                    delayIdx     = elements.length === 1 ? 1 : 0,
1463
                    toggleclsIdx = 0;
1464
1465
                elements.each(function(idx){
1466
1467
                    var element     = UI.$(this),
1468
                        inviewstate = element.data('inviewstate'),
1469
                        inview      = UI.Utils.isInView(element, $this.options),
1470
                        toggle      = element.attr('data-uk-scrollspy-cls') || togglecls[toggleclsIdx].trim();
1471
1472
                    if (inview && !inviewstate && !element.data('scrollspy-idle')) {
1473
1474
                        if (!initinview) {
1475
                            element.addClass($this.options.initcls);
1476
                            $this.offset = element.offset();
1477
                            initinview = true;
1478
1479
                            element.trigger('init.uk.scrollspy');
1480
                        }
1481
1482
                        element.data('scrollspy-idle', setTimeout(function(){
1483
1484
                            element.addClass('uk-scrollspy-inview').toggleClass(toggle).width();
1485
                            element.trigger('inview.uk.scrollspy');
1486
1487
                            element.data('scrollspy-idle', false);
1488
                            element.data('inviewstate', true);
1489
1490
                        }, $this.options.delay * delayIdx));
1491
1492
                        delayIdx++;
1493
                    }
1494
1495
                    if (!inview && inviewstate && $this.options.repeat) {
1496
1497
                        if (element.data('scrollspy-idle')) {
1498
                            clearTimeout(element.data('scrollspy-idle'));
1499
                            element.data('scrollspy-idle', false);
1500
                        }
1501
1502
                        element.removeClass('uk-scrollspy-inview').toggleClass(toggle);
1503
                        element.data('inviewstate', false);
1504
1505
                        element.trigger('outview.uk.scrollspy');
1506
                    }
1507
1508
                    toggleclsIdx = togglecls[toggleclsIdx + 1] ? (toggleclsIdx + 1) : 0;
1509
1510
                });
1511
            };
1512
1513
            fn();
1514
1515
            this.check = fn;
1516
1517
            scrollspies.push(this);
1518
        }
1519
    });
1520
1521
1522
    var scrollspynavs = [],
1523
        checkScrollSpyNavs = function() {
1524
            for(var i=0; i < scrollspynavs.length; i++) {
1525
                window.requestAnimationFrame.apply(window, [scrollspynavs[i].check]);
1526
            }
1527
        };
1528
1529
    UI.component('scrollspynav', {
1530
1531
        defaults: {
1532
            cls          : 'uk-active',
1533
            closest      : false,
1534
            topoffset    : 0,
1535
            leftoffset   : 0,
1536
            smoothscroll : false
1537
        },
1538
1539
        boot: function() {
1540
1541
            // listen to scroll and resize
1542
            $doc.on('scrolling.uk.document', checkScrollSpyNavs);
1543
            $win.on('resize orientationchange', UI.Utils.debounce(checkScrollSpyNavs, 50));
1544
1545
            // init code
1546
            UI.ready(function(context) {
1547
1548
                UI.$('[data-uk-scrollspy-nav]', context).each(function() {
1549
1550
                    var element = UI.$(this);
1551
1552
                    if (!element.data('scrollspynav')) {
1553
                        var obj = UI.scrollspynav(element, UI.Utils.options(element.attr('data-uk-scrollspy-nav')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
1554
                    }
1555
                });
1556
            });
1557
        },
1558
1559
        init: function() {
1560
1561
            var ids     = [],
1562
                links   = this.find("a[href^='#']").each(function(){ if(this.getAttribute('href').trim()!=='#') ids.push(this.getAttribute('href')); }),
1563
                targets = UI.$(ids.join(",")),
1564
1565
                clsActive  = this.options.cls,
1566
                clsClosest = this.options.closest || this.options.closest;
1567
1568
            var $this = this, inviews, fn = function(){
1569
1570
                inviews = [];
1571
1572
                for (var i=0 ; i < targets.length ; i++) {
1573
                    if (UI.Utils.isInView(targets.eq(i), $this.options)) {
1574
                        inviews.push(targets.eq(i));
1575
                    }
1576
                }
1577
1578
                if (inviews.length) {
1579
1580
                    var navitems,
1581
                        scrollTop = $win.scrollTop(),
1582
                        target = (function(){
1583
                            for(var i=0; i< inviews.length;i++){
1584
                                if (inviews[i].offset().top - $this.options.topoffset >= scrollTop){
1585
                                    return inviews[i];
1586
                                }
1587
                            }
1588
                        })();
1589
1590
                    if (!target) return;
1591
1592
                    if ($this.options.closest) {
1593
                        links.blur().closest(clsClosest).removeClass(clsActive);
1594
                        navitems = links.filter("a[href='#"+target.attr('id')+"']").closest(clsClosest).addClass(clsActive);
1595
                    } else {
1596
                        navitems = links.removeClass(clsActive).filter("a[href='#"+target.attr("id")+"']").addClass(clsActive);
1597
                    }
1598
1599
                    $this.element.trigger('inview.uk.scrollspynav', [target, navitems]);
1600
                }
1601
            };
1602
1603
            if (this.options.smoothscroll && UI.smoothScroll) {
1604
                links.each(function(){
1605
                    UI.smoothScroll(this, $this.options.smoothscroll);
1606
                });
1607
            }
1608
1609
            fn();
1610
1611
            this.element.data('scrollspynav', this);
1612
1613
            this.check = fn;
1614
            scrollspynavs.push(this);
1615
1616
        }
1617
    });
1618
1619
})(UIkit2);
1620
1621 View Code Duplication
(function(UI){
1622
1623
    "use strict";
1624
1625
    var toggles = [];
1626
1627
    UI.component('toggle', {
1628
1629
        defaults: {
1630
            target    : false,
1631
            cls       : 'uk-hidden',
1632
            animation : false,
1633
            duration  : 200
1634
        },
1635
1636
        boot: function(){
1637
1638
            // init code
1639
            UI.ready(function(context) {
1640
1641
                UI.$('[data-uk-toggle]', context).each(function() {
1642
                    var ele = UI.$(this);
1643
1644
                    if (!ele.data('toggle')) {
1645
                        var obj = UI.toggle(ele, UI.Utils.options(ele.attr('data-uk-toggle')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
1646
                    }
1647
                });
1648
1649
                setTimeout(function(){
1650
1651
                    toggles.forEach(function(toggle){
1652
                        toggle.getToggles();
1653
                    });
1654
1655
                }, 0);
1656
            });
1657
        },
1658
1659
        init: function() {
1660
1661
            var $this = this;
1662
1663
            this.aria = (this.options.cls.indexOf('uk-hidden') !== -1);
1664
1665
            this.on('click', function(e) {
1666
1667
                if ($this.element.is('a[href="#"]')) {
1668
                    e.preventDefault();
1669
                }
1670
1671
                $this.toggle();
1672
            });
1673
1674
            toggles.push(this);
1675
        },
1676
1677
        toggle: function() {
1678
1679
            this.getToggles();
1680
1681
            if(!this.totoggle.length) return;
1682
1683
            if (this.options.animation && UI.support.animation) {
1684
1685
                var $this = this, animations = this.options.animation.split(',');
1686
1687
                if (animations.length == 1) {
1688
                    animations[1] = animations[0];
1689
                }
1690
1691
                animations[0] = animations[0].trim();
1692
                animations[1] = animations[1].trim();
1693
1694
                this.totoggle.css('animation-duration', this.options.duration+'ms');
1695
1696
                this.totoggle.each(function(){
1697
1698
                    var ele = UI.$(this);
1699
1700
                    if (ele.hasClass($this.options.cls)) {
1701
1702
                        ele.toggleClass($this.options.cls);
1703
1704
                        UI.Utils.animate(ele, animations[0]).then(function(){
1705
                            ele.css('animation-duration', '');
1706
                            UI.Utils.checkDisplay(ele);
1707
                        });
1708
1709
                    } else {
1710
1711
                        UI.Utils.animate(this, animations[1]+' uk-animation-reverse').then(function(){
1712
                            ele.toggleClass($this.options.cls).css('animation-duration', '');
1713
                            UI.Utils.checkDisplay(ele);
1714
                        });
1715
1716
                    }
1717
1718
                });
1719
1720
            } else {
1721
                this.totoggle.toggleClass(this.options.cls);
1722
                UI.Utils.checkDisplay(this.totoggle);
1723
            }
1724
1725
            this.updateAria();
1726
1727
        },
1728
1729
        getToggles: function() {
1730
            this.totoggle = this.options.target ? UI.$(this.options.target):[];
1731
            this.updateAria();
1732
        },
1733
1734
        updateAria: function() {
1735
            if (this.aria && this.totoggle.length) {
1736
                this.totoggle.not('[aria-hidden]').each(function(){
1737
                    UI.$(this).attr('aria-hidden', UI.$(this).hasClass('uk-hidden'));
1738
                });
1739
            }
1740
        }
1741
    });
1742
1743
})(UIkit2);
1744
1745 View Code Duplication
(function(UI) {
1746
1747
    "use strict";
1748
1749
    UI.component('alert', {
1750
1751
        defaults: {
1752
            fade: true,
1753
            duration: 200,
1754
            trigger: '.uk-alert-close'
1755
        },
1756
1757
        boot: function() {
1758
1759
            // init code
1760
            UI.$html.on('click.alert.uikit', '[data-uk-alert]', function(e) {
1761
1762
                var ele = UI.$(this);
1763
1764
                if (!ele.data('alert')) {
1765
1766
                    var alert = UI.alert(ele, UI.Utils.options(ele.attr('data-uk-alert')));
1767
1768
                    if (UI.$(e.target).is(alert.options.trigger)) {
1769
                        e.preventDefault();
1770
                        alert.close();
1771
                    }
1772
                }
1773
            });
1774
        },
1775
1776
        init: function() {
1777
1778
            var $this = this;
1779
1780
            this.on('click', this.options.trigger, function(e) {
1781
                e.preventDefault();
1782
                $this.close();
1783
            });
1784
        },
1785
1786
        close: function() {
1787
1788
            var element       = this.trigger('close.uk.alert'),
1789
                removeElement = function () {
1790
                    this.trigger('closed.uk.alert').remove();
1791
                }.bind(this);
1792
1793
            if (this.options.fade) {
1794
                element.css('overflow', 'hidden').css("max-height", element.height()).animate({
1795
                    height         : 0,
1796
                    opacity        : 0,
1797
                    paddingTop    : 0,
1798
                    paddingBottom : 0,
1799
                    marginTop     : 0,
1800
                    marginBottom  : 0
1801
                }, this.options.duration, removeElement);
1802
            } else {
1803
                removeElement();
1804
            }
1805
        }
1806
1807
    });
1808
1809
})(UIkit2);
1810
1811 View Code Duplication
(function(UI) {
1812
1813
    "use strict";
1814
1815
    UI.component('buttonRadio', {
1816
1817
        defaults: {
1818
            activeClass: 'uk-active',
1819
            target: '.uk-button'
1820
        },
1821
1822
        boot: function() {
1823
1824
            // init code
1825
            UI.$html.on('click.buttonradio.uikit', '[data-uk-button-radio]', function(e) {
1826
1827
                var ele = UI.$(this);
1828
1829
                if (!ele.data('buttonRadio')) {
1830
1831
                    var obj    = UI.buttonRadio(ele, UI.Utils.options(ele.attr('data-uk-button-radio'))),
1832
                        target = UI.$(e.target);
1833
1834
                    if (target.is(obj.options.target)) {
1835
                        target.trigger('click');
1836
                    }
1837
                }
1838
            });
1839
        },
1840
1841
        init: function() {
1842
1843
            var $this = this;
1844
1845
            // Init ARIA
1846
            this.find($this.options.target).attr('aria-checked', 'false').filter('.' + $this.options.activeClass).attr('aria-checked', 'true');
1847
1848
            this.on('click', this.options.target, function(e) {
1849
1850
                var ele = UI.$(this);
1851
1852
                if (ele.is('a[href="#"]')) e.preventDefault();
1853
1854
                $this.find($this.options.target).not(ele).removeClass($this.options.activeClass).blur();
1855
                ele.addClass($this.options.activeClass);
1856
1857
                // Update ARIA
1858
                $this.find($this.options.target).not(ele).attr('aria-checked', 'false');
1859
                ele.attr('aria-checked', 'true');
1860
1861
                $this.trigger('change.uk.button', [ele]);
1862
            });
1863
1864
        },
1865
1866
        getSelected: function() {
1867
            return this.find('.' + this.options.activeClass);
1868
        }
1869
    });
1870
1871
    UI.component('buttonCheckbox', {
1872
1873
        defaults: {
1874
            activeClass: 'uk-active',
1875
            target: '.uk-button'
1876
        },
1877
1878
        boot: function() {
1879
1880
            UI.$html.on('click.buttoncheckbox.uikit', '[data-uk-button-checkbox]', function(e) {
1881
                var ele = UI.$(this);
1882
1883
                if (!ele.data('buttonCheckbox')) {
1884
1885
                    var obj    = UI.buttonCheckbox(ele, UI.Utils.options(ele.attr('data-uk-button-checkbox'))),
1886
                        target = UI.$(e.target);
1887
1888
                    if (target.is(obj.options.target)) {
1889
                        target.trigger('click');
1890
                    }
1891
                }
1892
            });
1893
        },
1894
1895
        init: function() {
1896
1897
            var $this = this;
1898
1899
            // Init ARIA
1900
            this.find($this.options.target).attr('aria-checked', 'false').filter('.' + $this.options.activeClass).attr('aria-checked', 'true');
1901
1902
            this.on('click', this.options.target, function(e) {
1903
                var ele = UI.$(this);
1904
1905
                if (ele.is('a[href="#"]')) e.preventDefault();
1906
1907
                ele.toggleClass($this.options.activeClass).blur();
1908
1909
                // Update ARIA
1910
                ele.attr('aria-checked', ele.hasClass($this.options.activeClass));
1911
1912
                $this.trigger('change.uk.button', [ele]);
1913
            });
1914
1915
        },
1916
1917
        getSelected: function() {
1918
            return this.find('.' + this.options.activeClass);
1919
        }
1920
    });
1921
1922
1923
    UI.component('button', {
1924
1925
        defaults: {},
1926
1927
        boot: function() {
1928
1929
            UI.$html.on('click.button.uikit', '[data-uk-button]', function(e) {
1930
                var ele = UI.$(this);
1931
1932
                if (!ele.data('button')) {
1933
1934
                    var obj = UI.button(ele, UI.Utils.options(ele.attr('data-uk-button')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
1935
                    ele.trigger('click');
1936
                }
1937
            });
1938
        },
1939
1940
        init: function() {
1941
1942
            var $this = this;
1943
1944
            // Init ARIA
1945
            this.element.attr('aria-pressed', this.element.hasClass("uk-active"));
1946
1947
            this.on('click', function(e) {
1948
1949
                if ($this.element.is('a[href="#"]')) e.preventDefault();
1950
1951
                $this.toggle();
1952
                $this.trigger('change.uk.button', [$this.element.blur().hasClass('uk-active')]);
1953
            });
1954
1955
        },
1956
1957
        toggle: function() {
1958
            this.element.toggleClass('uk-active');
1959
1960
            // Update ARIA
1961
            this.element.attr('aria-pressed', this.element.hasClass('uk-active'));
1962
        }
1963
    });
1964
1965
})(UIkit2);
1966
1967 View Code Duplication
(function(UI) {
1968
1969
    "use strict";
1970
1971
    var active = false, hoverIdle, flips = {
1972
        x: {
1973
            'bottom-left'   : 'bottom-right',
1974
            'bottom-right'  : 'bottom-left',
1975
            'bottom-center' : 'bottom-center',
1976
            'top-left'      : 'top-right',
1977
            'top-right'     : 'top-left',
1978
            'top-center'    : 'top-center',
1979
            'left-top'      : 'right-top',
1980
            'left-bottom'   : 'right-bottom',
1981
            'left-center'   : 'right-center',
1982
            'right-top'     : 'left-top',
1983
            'right-bottom'  : 'left-bottom',
1984
            'right-center'  : 'left-center'
1985
        },
1986
        y: {
1987
            'bottom-left'   : 'top-left',
1988
            'bottom-right'  : 'top-right',
1989
            'bottom-center' : 'top-center',
1990
            'top-left'      : 'bottom-left',
1991
            'top-right'     : 'bottom-right',
1992
            'top-center'    : 'bottom-center',
1993
            'left-top'      : 'left-bottom',
1994
            'left-bottom'   : 'left-top',
1995
            'left-center'   : 'left-center',
1996
            'right-top'     : 'right-bottom',
1997
            'right-bottom'  : 'right-top',
1998
            'right-center'  : 'right-center'
1999
        },
2000
        xy: {
2001
            'bottom-left'   : 'top-right',
2002
            'bottom-right'  : 'top-left',
2003
            'bottom-center' : 'top-center',
2004
            'top-left'      : 'bottom-right',
2005
            'top-right'     : 'bottom-left',
2006
            'top-center'    : 'bottom-center',
2007
            'left-top'      : 'right-bottom',
2008
            'left-bottom'   : 'right-top',
2009
            'left-center'   : 'right-center',
2010
            'right-top'     : 'left-bottom',
2011
            'right-bottom'  : 'left-top',
2012
            'right-center'  : 'left-center'
2013
        }
2014
    };
2015
2016
    UI.component('dropdown', {
2017
2018
        defaults: {
2019
           mode            : 'hover',
2020
           pos             : 'bottom-left',
2021
           offset          : 0,
2022
           remaintime      : 800,
2023
           justify         : false,
2024
           boundary        : UI.$win,
2025
           delay           : 0,
2026
           dropdownSelector: '.uk-dropdown,.uk-dropdown-blank',
2027
           hoverDelayIdle  : 250,
2028
           preventflip     : false
2029
        },
2030
2031
        remainIdle: false,
2032
2033
        boot: function() {
2034
2035
            var triggerevent = UI.support.touch ? 'click' : 'mouseenter';
2036
2037
            // init code
2038
            UI.$html.on(triggerevent+'.dropdown.uikit focus pointerdown', '[data-uk-dropdown]', function(e) {
2039
2040
                var ele = UI.$(this);
2041
2042
                if (!ele.data('dropdown')) {
2043
2044
                    var dropdown = UI.dropdown(ele, UI.Utils.options(ele.attr('data-uk-dropdown')));
2045
2046
                    if (e.type=='click' || (e.type=='mouseenter' && dropdown.options.mode=='hover')) {
2047
                        dropdown.element.trigger(triggerevent);
2048
                    }
2049
2050
                    if (dropdown.dropdown.length) {
2051
                        e.preventDefault();
2052
                    }
2053
                }
2054
            });
2055
        },
2056
2057
        init: function() {
2058
2059
            var $this = this;
2060
2061
            this.dropdown     = this.find(this.options.dropdownSelector);
2062
            this.offsetParent = this.dropdown.parents().filter(function() {
2063
                return UI.$.inArray(UI.$(this).css('position'), ['relative', 'fixed', 'absolute']) !== -1;
2064
            }).slice(0,1);
2065
2066
            if (!this.offsetParent.length) {
2067
                this.offsetParent = this.element;
2068
            }
2069
2070
            this.centered  = this.dropdown.hasClass('uk-dropdown-center');
2071
            this.justified = this.options.justify ? UI.$(this.options.justify) : false;
2072
2073
            this.boundary  = UI.$(this.options.boundary);
2074
2075
            if (!this.boundary.length) {
2076
                this.boundary = UI.$win;
2077
            }
2078
2079
            // legacy DEPRECATED!
2080
            if (this.dropdown.hasClass('uk-dropdown-up')) {
2081
                this.options.pos = 'top-left';
2082
            }
2083
            if (this.dropdown.hasClass('uk-dropdown-flip')) {
2084
                this.options.pos = this.options.pos.replace('left','right');
2085
            }
2086
            if (this.dropdown.hasClass('uk-dropdown-center')) {
2087
                this.options.pos = this.options.pos.replace(/(left|right)/,'center');
2088
            }
2089
            //-- end legacy
2090
2091
            // Init ARIA
2092
            this.element.attr('aria-haspopup', 'true');
2093
            this.element.attr('aria-expanded', this.element.hasClass('uk-open'));
2094
            this.dropdown.attr('aria-hidden', 'true');
2095
2096
            if (this.options.mode == 'click' || UI.support.touch) {
2097
2098
                this.on('click.uk.dropdown', function(e) {
2099
2100
                    var $target = UI.$(e.target);
2101
2102
                    if (!$target.parents($this.options.dropdownSelector).length) {
2103
2104
                        if ($target.is("a[href='#']") || $target.parent().is("a[href='#']") || ($this.dropdown.length && !$this.dropdown.is(':visible')) ){
2105
                            e.preventDefault();
2106
                        }
2107
2108
                        $target.blur();
2109
                    }
2110
2111
                    if (!$this.element.hasClass('uk-open')) {
2112
2113
                        $this.show();
2114
2115
                    } else {
2116
2117
                        if (!$this.dropdown.find(e.target).length || $target.is('.uk-dropdown-close') || $target.parents('.uk-dropdown-close').length) {
2118
                            $this.hide();
2119
                        }
2120
                    }
2121
                });
2122
2123
            } else {
2124
2125
                this.on('mouseenter', function(e) {
2126
2127
                    $this.trigger('pointerenter.uk.dropdown', [$this]);
2128
2129
                    if ($this.remainIdle) {
2130
                        clearTimeout($this.remainIdle);
2131
                    }
2132
2133
                    if (hoverIdle) {
2134
                        clearTimeout(hoverIdle);
2135
                    }
2136
2137
                    if (active && active == $this) {
2138
                        return;
2139
                    }
2140
2141
                    // pseudo manuAim
2142
                    if (active && active != $this) {
2143
2144
                        hoverIdle = setTimeout(function() {
2145
                            hoverIdle = setTimeout($this.show.bind($this), $this.options.delay);
2146
                        }, $this.options.hoverDelayIdle);
2147
2148
                    } else {
2149
2150
                        hoverIdle = setTimeout($this.show.bind($this), $this.options.delay);
2151
                    }
2152
2153
                }).on('mouseleave', function() {
2154
2155
                    if (hoverIdle) {
2156
                        clearTimeout(hoverIdle);
2157
                    }
2158
2159
                    $this.remainIdle = setTimeout(function() {
2160
                        if (active && active == $this) $this.hide();
2161
                    }, $this.options.remaintime);
2162
2163
                    $this.trigger('pointerleave.uk.dropdown', [$this]);
2164
2165
                }).on('click', function(e){
2166
2167
                    var $target = UI.$(e.target);
2168
2169
                    if ($this.remainIdle) {
2170
                        clearTimeout($this.remainIdle);
2171
                    }
2172
2173
                    if (active && active == $this) {
2174
                        if (!$this.dropdown.find(e.target).length || $target.is('.uk-dropdown-close') || $target.parents('.uk-dropdown-close').length) {
2175
                            $this.hide();
2176
                        }
2177
                        return;
2178
                    }
2179
2180
                    if ($target.is("a[href='#']") || $target.parent().is("a[href='#']")){
2181
                        e.preventDefault();
2182
                    }
2183
2184
                    $this.show();
2185
                });
2186
            }
2187
        },
2188
2189
        show: function(){
2190
2191
            UI.$html.off('click.outer.dropdown');
2192
2193
            if (active && active != this) {
2194
                active.hide(true);
2195
            }
2196
2197
            if (hoverIdle) {
2198
                clearTimeout(hoverIdle);
2199
            }
2200
2201
            this.trigger('beforeshow.uk.dropdown', [this]);
2202
2203
            this.checkDimensions();
2204
            this.element.addClass('uk-open');
2205
2206
            // Update ARIA
2207
            this.element.attr('aria-expanded', 'true');
2208
            this.dropdown.attr('aria-hidden', 'false');
2209
2210
            this.trigger('show.uk.dropdown', [this]);
2211
2212
            UI.Utils.checkDisplay(this.dropdown, true);
2213
            UI.Utils.focus(this.dropdown);
2214
            active = this;
2215
2216
            this.registerOuterClick();
2217
        },
2218
2219
        hide: function(force) {
2220
2221
            this.trigger('beforehide.uk.dropdown', [this, force]);
2222
2223
            this.element.removeClass('uk-open');
2224
2225
            if (this.remainIdle) {
2226
                clearTimeout(this.remainIdle);
2227
            }
2228
2229
            this.remainIdle = false;
2230
2231
            // Update ARIA
2232
            this.element.attr('aria-expanded', 'false');
2233
            this.dropdown.attr('aria-hidden', 'true');
2234
2235
            this.trigger('hide.uk.dropdown', [this, force]);
2236
2237
            if (active == this) active = false;
2238
        },
2239
2240
        registerOuterClick: function(){
2241
2242
            var $this = this;
2243
2244
            UI.$html.off('click.outer.dropdown');
2245
2246
            setTimeout(function() {
2247
2248
                UI.$html.on('click.outer.dropdown', function(e) {
2249
2250
                    if (hoverIdle) {
2251
                        clearTimeout(hoverIdle);
2252
                    }
2253
2254
                    var $target = UI.$(e.target);
0 ignored issues
show
Unused Code introduced by
The variable $target seems to be never used. Consider removing it.
Loading history...
2255
2256
                    if (active == $this && !$this.element.find(e.target).length) {
2257
                        $this.hide(true);
2258
                        UI.$html.off('click.outer.dropdown');
2259
                    }
2260
                });
2261
            }, 10);
2262
        },
2263
2264
        checkDimensions: function() {
2265
2266
            if (!this.dropdown.length) return;
2267
2268
            // reset
2269
            this.dropdown.removeClass('uk-dropdown-top uk-dropdown-bottom uk-dropdown-left uk-dropdown-right uk-dropdown-stack uk-dropdown-autoflip').css({
2270
                topLeft :'',
2271
                left :'',
2272
                marginLeft :'',
2273
                marginRight :''
2274
            });
2275
2276
            if (this.justified && this.justified.length) {
2277
                this.dropdown.css('min-width', '');
2278
            }
2279
2280
            var $this          = this,
0 ignored issues
show
Unused Code introduced by
The variable $this seems to be never used. Consider removing it.
Loading history...
2281
                pos            = UI.$.extend({}, this.offsetParent.offset(), {width: this.offsetParent[0].offsetWidth, height: this.offsetParent[0].offsetHeight}),
2282
                posoffset      = this.options.offset,
2283
                dropdown       = this.dropdown,
2284
                offset         = dropdown.show().offset() || {left: 0, top: 0},
2285
                width          = dropdown.outerWidth(),
2286
                height         = dropdown.outerHeight(),
2287
                boundarywidth  = this.boundary.width(),
2288
                boundaryoffset = this.boundary[0] !== window && this.boundary.offset() ? this.boundary.offset(): {top:0, left:0},
0 ignored issues
show
Unused Code introduced by
The variable boundaryoffset seems to be never used. Consider removing it.
Loading history...
2289
                dpos           = this.options.pos;
2290
2291
            var variants =  {
2292
                    'bottom-left'   : {top: 0 + pos.height + posoffset, left: 0},
2293
                    'bottom-right'  : {top: 0 + pos.height + posoffset, left: 0 + pos.width - width},
2294
                    'bottom-center' : {top: 0 + pos.height + posoffset, left: 0 + pos.width / 2 - width / 2},
2295
                    'top-left'      : {top: 0 - height - posoffset, left: 0},
2296
                    'top-right'     : {top: 0 - height - posoffset, left: 0 + pos.width - width},
2297
                    'top-center'    : {top: 0 - height - posoffset, left: 0 + pos.width / 2 - width / 2},
2298
                    'left-top'      : {top: 0, left: 0 - width - posoffset},
2299
                    'left-bottom'   : {top: 0 + pos.height - height, left: 0 - width - posoffset},
2300
                    'left-center'   : {top: 0 + pos.height / 2 - height / 2, left: 0 - width - posoffset},
2301
                    'right-top'     : {top: 0, left: 0 + pos.width + posoffset},
2302
                    'right-bottom'  : {top: 0 + pos.height - height, left: 0 + pos.width + posoffset},
2303
                    'right-center'  : {top: 0 + pos.height / 2 - height / 2, left: 0 + pos.width + posoffset}
2304
                },
2305
                css = {},
2306
                pp;
2307
2308
            pp = dpos.split('-');
2309
            css = variants[dpos] ? variants[dpos] : variants['bottom-left'];
2310
2311
            // justify dropdown
2312
            if (this.justified && this.justified.length) {
2313
                justify(dropdown.css({left:0}), this.justified, boundarywidth);
2314
            } else {
2315
2316
                if (this.options.preventflip !== true) {
2317
2318
                    var fdpos;
2319
2320
                    switch(this.checkBoundary(pos.left + css.left, pos.top + css.top, width, height, boundarywidth)) {
2321
                        case "x":
2322
                            if(this.options.preventflip !=='x') fdpos = flips['x'][dpos] || 'right-top';
2323
                            break;
2324
                        case "y":
2325
                            if(this.options.preventflip !=='y') fdpos = flips['y'][dpos] || 'top-left';
2326
                            break;
2327
                        case "xy":
2328
                            if(!this.options.preventflip) fdpos = flips['xy'][dpos] || 'right-bottom';
2329
                            break;
2330
                    }
2331
2332
                    if (fdpos) {
2333
2334
                        pp  = fdpos.split('-');
2335
                        css = variants[fdpos] ? variants[fdpos] : variants['bottom-left'];
2336
                        dropdown.addClass('uk-dropdown-autoflip');
2337
2338
                        // check flipped
2339
                        if (this.checkBoundary(pos.left + css.left, pos.top + css.top, width, height, boundarywidth)) {
2340
                            pp  = dpos.split('-');
2341
                            css = variants[dpos] ? variants[dpos] : variants['bottom-left'];
2342
                        }
2343
                    }
2344
                }
2345
            }
2346
2347
            if (width > boundarywidth) {
2348
                dropdown.addClass('uk-dropdown-stack');
2349
                this.trigger('stack.uk.dropdown', [this]);
2350
            }
2351
2352
            dropdown.css(css).css('display', '').addClass('uk-dropdown-'+pp[0]);
2353
        },
2354
2355
        checkBoundary: function(left, top, width, height, boundarywidth) {
2356
2357
            var axis = "";
2358
2359
            if (left < 0 || ((left - UI.$win.scrollLeft())+width) > boundarywidth) {
2360
               axis += "x";
2361
            }
2362
2363
            if ((top - UI.$win.scrollTop()) < 0 || ((top - UI.$win.scrollTop())+height) > window.innerHeight) {
2364
               axis += "y";
2365
            }
2366
2367
            return axis;
2368
        }
2369
    });
2370
2371
2372
    UI.component('dropdownOverlay', {
2373
2374
        defaults: {
2375
           justify : false,
2376
           cls     : '',
2377
           duration: 200
2378
        },
2379
2380
        boot: function() {
2381
2382
            // init code
2383
            UI.ready(function(context) {
2384
2385
                UI.$('[data-uk-dropdown-overlay]', context).each(function() {
2386
                    var ele = UI.$(this);
2387
2388
                    if (!ele.data('dropdownOverlay')) {
2389
                        UI.dropdownOverlay(ele, UI.Utils.options(ele.attr('data-uk-dropdown-overlay')));
2390
                    }
2391
                });
2392
            });
2393
        },
2394
2395
        init: function() {
2396
2397
            var $this = this;
2398
2399
            this.justified = this.options.justify ? UI.$(this.options.justify) : false;
2400
            this.overlay   = this.element.find('uk-dropdown-overlay');
2401
2402
            if (!this.overlay.length) {
2403
                this.overlay = UI.$('<div class="uk-dropdown-overlay"></div>').appendTo(this.element);
2404
            }
2405
2406
            this.overlay.addClass(this.options.cls);
2407
2408
            this.on({
2409
2410
                'beforeshow.uk.dropdown': function(e, dropdown) {
2411
                    $this.dropdown = dropdown;
2412
2413
                    if ($this.justified && $this.justified.length) {
2414
                        justify($this.overlay.css({display:'block', marginLeft:'', marginRight:''}), $this.justified, $this.justified.outerWidth());
2415
                    }
2416
                },
2417
2418
                'show.uk.dropdown': function(e, dropdown) {
2419
2420
                    var h = $this.dropdown.dropdown.outerHeight(true);
2421
2422
                    $this.dropdown.element.removeClass('uk-open');
2423
2424
                    $this.overlay.stop().css('display', 'block').animate({height: h}, $this.options.duration, function() {
2425
2426
                       $this.dropdown.dropdown.css('visibility', '');
2427
                       $this.dropdown.element.addClass('uk-open');
2428
2429
                       UI.Utils.checkDisplay($this.dropdown.dropdown, true);
2430
                    });
2431
2432
                    $this.pointerleave = false;
2433
                },
2434
2435
                'hide.uk.dropdown': function() {
2436
                    $this.overlay.stop().animate({height: 0}, $this.options.duration);
2437
                },
2438
2439
                'pointerenter.uk.dropdown': function(e, dropdown) {
2440
                    clearTimeout($this.remainIdle);
2441
                },
2442
2443
                'pointerleave.uk.dropdown': function(e, dropdown) {
2444
                    $this.pointerleave = true;
2445
                }
2446
            });
2447
2448
2449
            this.overlay.on({
2450
2451
                'mouseenter': function() {
2452
                    if ($this.remainIdle) {
2453
                        clearTimeout($this.dropdown.remainIdle);
2454
                        clearTimeout($this.remainIdle);
2455
                    }
2456
                },
2457
2458
                'mouseleave': function(){
2459
2460
                    if ($this.pointerleave && active) {
2461
2462
                        $this.remainIdle = setTimeout(function() {
2463
                           if(active) active.hide();
2464
                        }, active.options.remaintime);
2465
                    }
2466
                }
2467
            })
2468
        }
2469
2470
    });
2471
2472
2473
    function justify(ele, justifyTo, boundarywidth, offset) {
2474
2475
        ele           = UI.$(ele);
2476
        justifyTo     = UI.$(justifyTo);
2477
        boundarywidth = boundarywidth || window.innerWidth;
2478
        offset        = offset || ele.offset();
2479
2480
        if (justifyTo.length) {
2481
2482
            var jwidth = justifyTo.outerWidth();
2483
2484
            ele.css('min-width', jwidth);
2485
2486
            if (UI.langdirection == 'right') {
2487
2488
                var right1   = boundarywidth - (justifyTo.offset().left + jwidth),
2489
                    right2   = boundarywidth - (ele.offset().left + ele.outerWidth());
2490
2491
                ele.css('margin-right', right1 - right2);
2492
2493
            } else {
2494
                ele.css('margin-left', justifyTo.offset().left - offset.left);
2495
            }
2496
        }
2497
    }
2498
2499
})(UIkit2);
2500
2501 View Code Duplication
(function(UI) {
2502
2503
    "use strict";
2504
2505
    var grids = [];
2506
2507
    UI.component('gridMatchHeight', {
2508
2509
        defaults: {
2510
            target        : false,
2511
            row           : true,
2512
            ignorestacked : false,
2513
            observe       : false
2514
        },
2515
2516
        boot: function() {
2517
2518
            // init code
2519
            UI.ready(function(context) {
2520
2521
                UI.$('[data-uk-grid-match]', context).each(function() {
2522
                    var grid = UI.$(this), obj;
2523
2524
                    if (!grid.data('gridMatchHeight')) {
2525
                        obj = UI.gridMatchHeight(grid, UI.Utils.options(grid.attr('data-uk-grid-match')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
2526
                    }
2527
                });
2528
            });
2529
        },
2530
2531
        init: function() {
2532
2533
            var $this = this;
2534
2535
            this.columns  = this.element.children();
2536
            this.elements = this.options.target ? this.find(this.options.target) : this.columns;
2537
2538
            if (!this.columns.length) return;
2539
2540
            UI.$win.on('load resize orientationchange', (function() {
2541
2542
                var fn = function() {
2543
                    if ($this.element.is(':visible')) $this.match();
2544
                };
2545
2546
                UI.$(function() { fn(); });
2547
2548
                return UI.Utils.debounce(fn, 50);
2549
            })());
2550
2551
            if (this.options.observe) {
2552
2553
                UI.domObserve(this.element, function(e) {
2554
                    if ($this.element.is(':visible')) $this.match();
2555
                });
2556
            }
2557
2558
            this.on('display.uk.check', function(e) {
2559
                if(this.element.is(':visible')) this.match();
2560
            }.bind(this));
2561
2562
            grids.push(this);
2563
        },
2564
2565
        match: function() {
2566
2567
            var firstvisible = this.columns.filter(':visible:first');
2568
2569
            if (!firstvisible.length) return;
2570
2571
            var stacked = Math.ceil(100 * parseFloat(firstvisible.css('width')) / parseFloat(firstvisible.parent().css('width'))) >= 100;
2572
2573
            if (stacked && !this.options.ignorestacked) {
2574
                this.revert();
2575
            } else {
2576
                UI.Utils.matchHeights(this.elements, this.options);
2577
            }
2578
2579
            return this;
2580
        },
2581
2582
        revert: function() {
2583
            this.elements.css('min-height', '');
2584
            return this;
2585
        }
2586
    });
2587
2588
    UI.component('gridMargin', {
2589
2590
        defaults: {
2591
            cls      : 'uk-grid-margin',
2592
            rowfirst : 'uk-row-first'
2593
        },
2594
2595
        boot: function() {
2596
2597
            // init code
2598
            UI.ready(function(context) {
2599
2600
                UI.$('[data-uk-grid-margin]', context).each(function() {
2601
                    var grid = UI.$(this), obj;
2602
2603
                    if (!grid.data('gridMargin')) {
2604
                        obj = UI.gridMargin(grid, UI.Utils.options(grid.attr('data-uk-grid-margin')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
2605
                    }
2606
                });
2607
            });
2608
        },
2609
2610
        init: function() {
2611
2612
            var stackMargin = UI.stackMargin(this.element, this.options);
2613
        }
2614
    });
2615
2616
})(UIkit2);
2617
2618 View Code Duplication
(function(UI) {
2619
2620
    "use strict";
2621
2622
    var active = false, activeCount = 0, $html = UI.$html, body;
2623
2624
    UI.$win.on('resize orientationchange', UI.Utils.debounce(function(){
2625
        UI.$('.uk-modal.uk-open').each(function(){
2626
            return UI.$(this).data('modal') && UI.$(this).data('modal').resize();
2627
        });
2628
    }, 150));
2629
2630
    UI.component('modal', {
2631
2632
        defaults: {
2633
            keyboard: true,
2634
            bgclose: true,
2635
            minScrollHeight: 150,
2636
            center: false,
2637
            modal: true
2638
        },
2639
2640
        scrollable: false,
2641
        transition: false,
2642
        hasTransitioned: true,
2643
2644
        init: function() {
2645
2646
            if (!body) body = UI.$('body');
2647
2648
            if (!this.element.length) return;
2649
2650
            var $this = this;
2651
2652
            this.paddingdir = 'padding-' + (UI.langdirection == 'left' ? 'right':'left');
2653
            this.dialog     = this.find('.uk-modal-dialog');
2654
2655
            this.active     = false;
2656
2657
            // Update ARIA
2658
            this.element.attr('aria-hidden', this.element.hasClass('uk-open'));
2659
2660
            this.on('click', '.uk-modal-close', function(e) {
2661
                e.preventDefault();
2662
                $this.hide();
2663
            }).on('click', function(e) {
2664
2665
                var target = UI.$(e.target);
2666
2667
                if (target[0] == $this.element[0] && $this.options.bgclose) {
2668
                    $this.hide();
2669
                }
2670
            });
2671
2672
            UI.domObserve(this.element, function(e) { $this.resize(); });
2673
        },
2674
2675
        toggle: function() {
2676
            return this[this.isActive() ? 'hide' : 'show']();
2677
        },
2678
2679
        show: function() {
2680
2681
            if (!this.element.length) return;
2682
2683
            var $this = this;
2684
2685
            if (this.isActive()) return;
2686
2687
            if (this.options.modal && active) {
2688
                active.hide(true);
2689
            }
2690
2691
            this.element.removeClass('uk-open').show();
2692
            this.resize(true);
2693
2694
            if (this.options.modal) {
2695
                active = this;
2696
            }
2697
2698
            this.active = true;
2699
2700
            activeCount++;
2701
2702
            if (UI.support.transition) {
2703
                this.hasTransitioned = false;
2704
                this.element.one(UI.support.transition.end, function(){
2705
                    $this.hasTransitioned = true;
2706
                    UI.Utils.focus($this.dialog, 'a[href]');
2707
                }).addClass('uk-open');
2708
            } else {
2709
                this.element.addClass('uk-open');
2710
                UI.Utils.focus(this.dialog, 'a[href]');
2711
            }
2712
2713
            $html.addClass('uk-modal-page').height(); // force browser engine redraw
2714
2715
            // Update ARIA
2716
            this.element.attr('aria-hidden', 'false');
2717
2718
            this.element.trigger('show.uk.modal');
2719
2720
            UI.Utils.checkDisplay(this.dialog, true);
2721
2722
            return this;
2723
        },
2724
2725
        hide: function(force) {
2726
2727
            if (!force && UI.support.transition && this.hasTransitioned) {
2728
2729
                var $this = this;
2730
2731
                this.one(UI.support.transition.end, function() {
2732
                    $this._hide();
2733
                }).removeClass('uk-open');
2734
2735
            } else {
2736
2737
                this._hide();
2738
            }
2739
2740
            return this;
2741
        },
2742
2743
        resize: function(force) {
2744
2745
            if (!this.isActive() && !force) return;
2746
2747
            var bodywidth  = body.width();
2748
2749
            this.scrollbarwidth = window.innerWidth - bodywidth;
2750
2751
            body.css(this.paddingdir, this.scrollbarwidth);
2752
2753
            this.element.css('overflow-y', this.scrollbarwidth ? 'scroll' : 'auto');
2754
2755
            if (!this.updateScrollable() && this.options.center) {
2756
2757
                var dh  = this.dialog.outerHeight(),
2758
                pad = parseInt(this.dialog.css('margin-top'), 10) + parseInt(this.dialog.css('margin-bottom'), 10);
2759
2760
                if ((dh + pad) < window.innerHeight) {
2761
                    this.dialog.css({top: (window.innerHeight/2 - dh/2) - pad });
2762
                } else {
2763
                    this.dialog.css({top: ''});
2764
                }
2765
            }
2766
        },
2767
2768
        updateScrollable: function() {
2769
2770
            // has scrollable?
2771
            var scrollable = this.dialog.find('.uk-overflow-container:visible:first');
2772
2773
            if (scrollable.length) {
2774
2775
                scrollable.css('height', 0);
2776
2777
                var offset = Math.abs(parseInt(this.dialog.css('margin-top'), 10)),
2778
                dh     = this.dialog.outerHeight(),
2779
                wh     = window.innerHeight,
2780
                h      = wh - 2*(offset < 20 ? 20:offset) - dh;
2781
2782
                scrollable.css({
2783
                    maxHeight: (h < this.options.minScrollHeight ? '':h),
2784
                    height:''
2785
                });
2786
2787
                return true;
2788
            }
2789
2790
            return false;
2791
        },
2792
2793
        _hide: function() {
2794
2795
            this.active = false;
2796
            if (activeCount > 0) activeCount--;
2797
            else activeCount = 0;
2798
2799
            this.element.hide().removeClass('uk-open');
2800
2801
            // Update ARIA
2802
            this.element.attr('aria-hidden', 'true');
2803
2804
            if (!activeCount) {
2805
                $html.removeClass('uk-modal-page');
2806
                body.css(this.paddingdir, "");
2807
            }
2808
2809
            if (active===this) active = false;
2810
2811
            this.trigger('hide.uk.modal');
2812
        },
2813
2814
        isActive: function() {
2815
            return this.element.hasClass('uk-open');
2816
        }
2817
2818
    });
2819
2820
    UI.component('modalTrigger', {
2821
2822
        boot: function() {
2823
2824
            // init code
2825
            UI.$html.on('click.modal.uikit', '[data-uk-modal]', function(e) {
2826
2827
                var ele = UI.$(this);
2828
2829
                if (ele.is('a')) {
2830
                    e.preventDefault();
2831
                }
2832
2833
                if (!ele.data('modalTrigger')) {
2834
                    var modal = UI.modalTrigger(ele, UI.Utils.options(ele.attr('data-uk-modal')));
2835
                    modal.show();
2836
                }
2837
2838
            });
2839
2840
            // close modal on esc button
2841
            UI.$html.on('keydown.modal.uikit', function (e) {
2842
2843
                if (active && e.keyCode === 27 && active.options.keyboard) { // ESC
2844
                    e.preventDefault();
2845
                    active.hide();
2846
                }
2847
            });
2848
        },
2849
2850
        init: function() {
2851
2852
            var $this = this;
2853
2854
            this.options = UI.$.extend({
2855
                target: $this.element.is('a') ? $this.element.attr('href') : false
2856
            }, this.options);
2857
2858
            this.modal = UI.modal(this.options.target, this.options);
2859
2860
            this.on("click", function(e) {
2861
                e.preventDefault();
2862
                $this.show();
2863
            });
2864
2865
            //methods
2866
            this.proxy(this.modal, 'show hide isActive');
2867
        }
2868
    });
2869
2870
    UI.modal.dialog = function(content, options) {
2871
2872
        var modal = UI.modal(UI.$(UI.modal.dialog.template).appendTo('body'), options);
2873
2874
        modal.on('hide.uk.modal', function(){
2875
            if (modal.persist) {
2876
                modal.persist.appendTo(modal.persist.data('modalPersistParent'));
2877
                modal.persist = false;
2878
            }
2879
            modal.element.remove();
2880
        });
2881
2882
        setContent(content, modal);
2883
2884
        return modal;
2885
    };
2886
2887
    UI.modal.dialog.template = '<div class="uk-modal"><div class="uk-modal-dialog" style="min-height:0;"></div></div>';
2888
2889
    UI.modal.alert = function(content, options) {
2890
2891
        options = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options);
2892
2893
        var modal = UI.modal.dialog(([
2894
            '<div class="uk-margin uk-modal-content">'+String(content)+'</div>',
2895
            '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-button-primary uk-modal-close">'+options.labels.Ok+'</button></div>'
2896
        ]).join(""), options);
2897
2898
        modal.on('show.uk.modal', function(){
2899
            setTimeout(function(){
2900
                modal.element.find('button:first').focus();
2901
            }, 50);
2902
        });
2903
2904
        return modal.show();
2905
    };
2906
2907
    UI.modal.confirm = function(content, onconfirm, oncancel) {
2908
2909
        var options = arguments.length > 1 && arguments[arguments.length-1] ? arguments[arguments.length-1] : {};
2910
2911
        onconfirm = UI.$.isFunction(onconfirm) ? onconfirm : function(){};
2912
        oncancel  = UI.$.isFunction(oncancel) ? oncancel : function(){};
2913
        options   = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, UI.$.isFunction(options) ? {}:options);
2914
2915
        var modal = UI.modal.dialog(([
2916
            '<div class="uk-margin uk-modal-content">'+String(content)+'</div>',
2917
            '<div class="uk-modal-footer uk-text-right"><button class="uk-button js-modal-confirm-cancel">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-confirm">'+options.labels.Ok+'</button></div>'
2918
        ]).join(""), options);
2919
2920
        modal.element.find(".js-modal-confirm, .js-modal-confirm-cancel").on("click", function(){
2921
            UI.$(this).is('.js-modal-confirm') ? onconfirm() : oncancel();
2922
            modal.hide();
2923
        });
2924
2925
        modal.on('show.uk.modal', function(){
2926
            setTimeout(function(){
2927
                modal.element.find('.js-modal-confirm').focus();
2928
            }, 50);
2929
        });
2930
2931
        return modal.show();
2932
    };
2933
2934
    UI.modal.prompt = function(text, value, onsubmit, options) {
2935
2936
        onsubmit = UI.$.isFunction(onsubmit) ? onsubmit : function(value){};
2937
        options  = UI.$.extend(true, {bgclose:false, keyboard:false, modal:false, labels:UI.modal.labels}, options);
2938
2939
        var modal = UI.modal.dialog(([
2940
            text ? '<div class="uk-modal-content uk-form">'+String(text)+'</div>':'',
2941
            '<div class="uk-margin-small-top uk-modal-content uk-form"><p><input type="text" class="uk-width-1-1"></p></div>',
2942
            '<div class="uk-modal-footer uk-text-right"><button class="uk-button uk-modal-close">'+options.labels.Cancel+'</button> <button class="uk-button uk-button-primary js-modal-ok">'+options.labels.Ok+'</button></div>'
2943
        ]).join(""), options),
2944
2945
        input = modal.element.find("input[type='text']").val(value || '').on('keyup', function(e){
2946
            if (e.keyCode == 13) {
2947
                modal.element.find('.js-modal-ok').trigger('click');
2948
            }
2949
        });
2950
2951
        modal.element.find('.js-modal-ok').on('click', function(){
2952
            if (onsubmit(input.val())!==false){
2953
                modal.hide();
2954
            }
2955
        });
2956
2957
        return modal.show();
2958
    };
2959
2960
    UI.modal.blockUI = function(content, options) {
2961
2962
        var modal = UI.modal.dialog(([
2963
            '<div class="uk-margin uk-modal-content">'+String(content || '<div class="uk-text-center">...</div>')+'</div>'
2964
        ]).join(""), UI.$.extend({bgclose:false, keyboard:false, modal:false}, options));
2965
2966
        modal.content = modal.element.find('.uk-modal-content:first');
2967
2968
        return modal.show();
2969
    };
2970
2971
    UI.modal.labels = {
2972
        Ok: 'Ok',
2973
        Cancel: 'Cancel'
2974
    };
2975
2976
    // helper functions
2977
    function setContent(content, modal){
2978
2979
        if(!modal) return;
2980
2981
        if (typeof content === 'object') {
2982
2983
            // convert DOM object to a jQuery object
2984
            content = content instanceof jQuery ? content : UI.$(content);
2985
2986
            if(content.parent().length) {
2987
                modal.persist = content;
2988
                modal.persist.data('modalPersistParent', content.parent());
2989
            }
2990
        }else if (typeof content === 'string' || typeof content === 'number') {
2991
                // just insert the data as innerHTML
2992
                content = UI.$('<div></div>').html(content);
2993
        }else {
2994
                // unsupported data type!
2995
                content = UI.$('<div></div>').html('UIkit2.modal Error: Unsupported data type: ' + typeof content);
2996
        }
2997
2998
        content.appendTo(modal.element.find('.uk-modal-dialog'));
2999
3000
        return modal;
3001
    }
3002
3003
})(UIkit2);
3004
3005 View Code Duplication
(function(UI) {
3006
3007
    "use strict";
3008
3009
    UI.component('nav', {
3010
3011
        defaults: {
3012
            toggle: '>li.uk-parent > a[href="#"]',
3013
            lists: '>li.uk-parent > ul',
3014
            multiple: false
3015
        },
3016
3017
        boot: function() {
3018
3019
            // init code
3020
            UI.ready(function(context) {
3021
3022
                UI.$('[data-uk-nav]', context).each(function() {
3023
                    var nav = UI.$(this);
3024
3025
                    if (!nav.data('nav')) {
3026
                        var obj = UI.nav(nav, UI.Utils.options(nav.attr('data-uk-nav')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
3027
                    }
3028
                });
3029
            });
3030
        },
3031
3032
        init: function() {
3033
3034
            var $this = this;
3035
3036
            this.on('click.uk.nav', this.options.toggle, function(e) {
3037
                e.preventDefault();
3038
                var ele = UI.$(this);
3039
                $this.open(ele.parent()[0] == $this.element[0] ? ele : ele.parent("li"));
3040
            });
3041
3042
            this.update();
3043
3044
            UI.domObserve(this.element, function(e) {
3045
                if ($this.element.find($this.options.lists).not('[role]').length) {
3046
                    $this.update();
3047
                }
3048
            });
3049
        },
3050
3051
        update: function() {
3052
3053
            var $this = this;
3054
3055
            this.find(this.options.lists).each(function() {
3056
3057
                var $ele   = UI.$(this).attr('role', 'menu'),
3058
                    parent = $ele.closest('li'),
3059
                    active = parent.hasClass("uk-active");
3060
3061
                if (!parent.data('list-container')) {
3062
                    $ele.wrap('<div style="overflow:hidden;height:0;position:relative;"></div>');
3063
                    parent.data('list-container', $ele.parent()[active ? 'removeClass':'addClass']('uk-hidden'));
3064
                }
3065
3066
                // Init ARIA
3067
                parent.attr('aria-expanded', parent.hasClass("uk-open"));
3068
3069
                if (active) $this.open(parent, true);
3070
            });
3071
        },
3072
3073
        open: function(li, noanimation) {
3074
3075
            var $this = this, element = this.element, $li = UI.$(li), $container = $li.data('list-container');
3076
3077
            if (!this.options.multiple) {
3078
3079
                element.children('.uk-open').not(li).each(function() {
3080
3081
                    var ele = UI.$(this);
3082
3083
                    if (ele.data('list-container')) {
3084
                        ele.data('list-container').stop().animate({height: 0}, function() {
3085
                            UI.$(this).parent().removeClass('uk-open').end().addClass('uk-hidden');
3086
                        });
3087
                    }
3088
                });
3089
            }
3090
3091
            $li.toggleClass('uk-open');
3092
3093
            // Update ARIA
3094
            $li.attr('aria-expanded', $li.hasClass('uk-open'));
3095
3096
            if ($container) {
3097
3098
                if ($li.hasClass('uk-open')) {
3099
                    $container.removeClass('uk-hidden');
3100
                }
3101
3102
                if (noanimation) {
3103
3104
                    $container.stop().height($li.hasClass('uk-open') ? 'auto' : 0);
3105
3106
                    if (!$li.hasClass('uk-open')) {
3107
                        $container.addClass('uk-hidden');
3108
                    }
3109
3110
                    this.trigger('display.uk.check');
3111
3112
                } else {
3113
3114
                    $container.stop().animate({
3115
                        height: ($li.hasClass('uk-open') ? getHeight($container.find('ul:first')) : 0)
3116
                    }, function() {
3117
3118
                        if (!$li.hasClass('uk-open')) {
3119
                            $container.addClass('uk-hidden');
3120
                        } else {
3121
                            $container.css('height', '');
3122
                        }
3123
3124
                        $this.trigger('display.uk.check');
3125
                    });
3126
                }
3127
            }
3128
        }
3129
    });
3130
3131
3132
    // helper
3133
3134
    function getHeight(ele) {
3135
3136
        var $ele = UI.$(ele), height = 'auto';
3137
3138
        if ($ele.is(':visible')) {
3139
            height = $ele.outerHeight();
3140
        } else {
3141
3142
            var tmp = {
3143
                position: $ele.css('position'),
3144
                visibility: $ele.css('visibility'),
3145
                display: $ele.css('display')
3146
            };
3147
3148
            height = $ele.css({position: 'absolute', visibility: 'hidden', display: 'block'}).outerHeight();
3149
3150
            $ele.css(tmp); // reset element
3151
        }
3152
3153
        return height;
3154
    }
3155
3156
})(UIkit2);
3157
3158 View Code Duplication
(function(UI) {
3159
3160
    "use strict";
3161
3162
    var scrollpos = {x: window.scrollX, y: window.scrollY},
3163
        $win      = UI.$win,
3164
        $doc      = UI.$doc,
3165
        $html     = UI.$html,
3166
        Offcanvas = {
3167
3168
        show: function(element, options) {
3169
3170
            element = UI.$(element);
3171
3172
            if (!element.length) return;
3173
3174
            options = UI.$.extend({mode: 'push'}, options);
3175
3176
            var $body     = UI.$('body'),
3177
                bar       = element.find('.uk-offcanvas-bar:first'),
3178
                rtl       = (UI.langdirection == 'right'),
3179
                flip      = bar.hasClass('uk-offcanvas-bar-flip') ? -1:1,
3180
                dir       = flip * (rtl ? -1 : 1),
3181
3182
                scrollbarwidth =  window.innerWidth - $body.width();
3183
3184
            scrollpos = {x: window.pageXOffset, y: window.pageYOffset};
3185
3186
            bar.attr('mode', options.mode);
3187
            element.addClass('uk-active');
3188
3189
            $body.css({width: window.innerWidth - scrollbarwidth, height: window.innerHeight}).addClass('uk-offcanvas-page');
3190
3191
            if (options.mode == 'push' || options.mode == 'reveal') {
3192
                $body.css((rtl ? 'margin-right' : 'margin-left'), (rtl ? -1 : 1) * (bar.outerWidth() * dir));
3193
            }
3194
3195
            if (options.mode == 'reveal') {
3196
                bar.css('clip', 'rect(0, '+bar.outerWidth()+'px, 100vh, 0)');
3197
            }
3198
3199
            $html.css('margin-top', scrollpos.y * -1).width(); // .width() - force redraw
3200
3201
3202
            bar.addClass('uk-offcanvas-bar-show');
3203
3204
            this._initElement(element);
3205
3206
            bar.trigger('show.uk.offcanvas', [element, bar]);
3207
3208
            // Update ARIA
3209
            element.attr('aria-hidden', 'false');
3210
        },
3211
3212
        hide: function(force) {
3213
3214
            var $body = UI.$('body'),
3215
                panel = UI.$('.uk-offcanvas.uk-active'),
3216
                rtl   = (UI.langdirection == 'right'),
3217
                bar   = panel.find('.uk-offcanvas-bar:first'),
3218
                finalize = function() {
3219
                    $body.removeClass('uk-offcanvas-page').css({width: '', height: '', marginLeft: '', marginRight: ''});
3220
                    panel.removeClass('uk-active');
3221
3222
                    bar.removeClass('uk-offcanvas-bar-show');
3223
                    $html.css('margin-top', '');
3224
                    window.scrollTo(scrollpos.x, scrollpos.y);
3225
                    bar.trigger('hide.uk.offcanvas', [panel, bar]);
3226
3227
                    // Update ARIA
3228
                    panel.attr('aria-hidden', 'true');
3229
                };
3230
3231
            if (!panel.length) return;
3232
            if (bar.attr('mode') == 'none') force = true;
3233
3234
            if (UI.support.transition && !force) {
3235
3236
                $body.one(UI.support.transition.end, function() {
3237
                    finalize();
3238
                }).css((rtl ? 'margin-right' : 'margin-left'), '');
3239
3240
                if (bar.attr('mode') == 'reveal') {
3241
                    bar.css('clip', '');
3242
                }
3243
3244
                setTimeout(function(){
3245
                    bar.removeClass('uk-offcanvas-bar-show');
3246
                }, 0);
3247
3248
            } else {
3249
                finalize();
3250
            }
3251
        },
3252
3253
        _initElement: function(element) {
3254
3255
            if (element.data('OffcanvasInit')) return;
3256
3257
            element.on('click.uk.offcanvas swipeRight.uk.offcanvas swipeLeft.uk.offcanvas', function(e) {
3258
3259
                var target = UI.$(e.target);
3260
3261
                if (!e.type.match(/swipe/)) {
3262
3263
                    if (!target.hasClass('uk-offcanvas-close')) {
3264
                        if (target.hasClass('uk-offcanvas-bar')) return;
3265
                        if (target.parents('.uk-offcanvas-bar:first').length) return;
3266
                    }
3267
                }
3268
3269
                e.stopImmediatePropagation();
3270
                Offcanvas.hide();
3271
            });
3272
3273
            element.on('click', 'a[href*="#"]', function(e){
3274
3275
                var link = UI.$(this),
3276
                    href = link.attr('href');
3277
3278
                if (href == '#') {
3279
                    return;
3280
                }
3281
3282
                UI.$doc.one('hide.uk.offcanvas', function() {
3283
3284
                    var target;
3285
3286
                    try {
3287
                        target = UI.$(link[0].hash);
3288
                    } catch (e){
3289
                        target = '';
3290
                    }
3291
3292
                    if (!target.length) {
3293
                        target = UI.$('[name="'+link[0].hash.replace('#','')+'"]');
3294
                    }
3295
3296
                    if (target.length && UI.Utils.scrollToElement) {
3297
                        UI.Utils.scrollToElement(target, UI.Utils.options(link.attr('data-uk-smooth-scroll') || '{}'));
3298
                    } else {
3299
                        window.location.href = href;
3300
                    }
3301
                });
3302
3303
                Offcanvas.hide();
3304
            });
3305
3306
            element.data('OffcanvasInit', true);
3307
        }
3308
    };
3309
3310
    UI.component('offcanvasTrigger', {
3311
3312
        boot: function() {
3313
3314
            // init code
3315
            $html.on('click.offcanvas.uikit', '[data-uk-offcanvas]', function(e) {
3316
3317
                e.preventDefault();
3318
3319
                var ele = UI.$(this);
3320
3321
                if (!ele.data('offcanvasTrigger')) {
3322
                    var obj = UI.offcanvasTrigger(ele, UI.Utils.options(ele.attr('data-uk-offcanvas')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
3323
                    ele.trigger("click");
3324
                }
3325
            });
3326
3327
            $html.on('keydown.uk.offcanvas', function(e) {
3328
3329
                if (e.keyCode === 27) { // ESC
3330
                    Offcanvas.hide();
3331
                }
3332
            });
3333
        },
3334
3335
        init: function() {
3336
3337
            var $this = this;
3338
3339
            this.options = UI.$.extend({
3340
                target: $this.element.is('a') ? $this.element.attr('href') : false,
3341
                mode: 'push'
3342
            }, this.options);
3343
3344
            this.on('click', function(e) {
3345
                e.preventDefault();
3346
                Offcanvas.show($this.options.target, $this.options);
3347
            });
3348
        }
3349
    });
3350
3351
    UI.offcanvas = Offcanvas;
3352
3353
})(UIkit2);
3354
3355 View Code Duplication
(function(UI) {
3356
3357
    "use strict";
3358
3359
    var Animations;
3360
3361
    UI.component('switcher', {
3362
3363
        defaults: {
3364
            connect   : false,
3365
            toggle    : '>*',
3366
            active    : 0,
3367
            animation : false,
3368
            duration  : 200,
3369
            swiping   : true
3370
        },
3371
3372
        animating: false,
3373
3374
        boot: function() {
3375
3376
            // init code
3377
            UI.ready(function(context) {
3378
3379
                UI.$('[data-uk-switcher]', context).each(function() {
3380
                    var switcher = UI.$(this);
3381
3382
                    if (!switcher.data('switcher')) {
3383
                        var obj = UI.switcher(switcher, UI.Utils.options(switcher.attr('data-uk-switcher')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
3384
                    }
3385
                });
3386
            });
3387
        },
3388
3389
        init: function() {
3390
3391
            var $this = this;
3392
3393
            this.on('click.uk.switcher', this.options.toggle, function(e) {
3394
                e.preventDefault();
3395
                $this.show(this);
3396
            });
3397
3398
            if (!this.options.connect) {
3399
                return;
3400
            }
3401
3402
            this.connect = UI.$(this.options.connect);
3403
3404
            if (!this.connect.length) {
3405
                return;
3406
            }
3407
3408
            this.connect.on('click.uk.switcher', '[data-uk-switcher-item]', function(e) {
3409
3410
                e.preventDefault();
3411
3412
                var item = UI.$(this).attr('data-uk-switcher-item');
3413
3414
                if ($this.index == item) return;
3415
3416
                switch(item) {
3417
                    case 'next':
3418
                    case 'previous':
3419
                        $this.show($this.index + (item=='next' ? 1:-1));
3420
                        break;
3421
                    default:
3422
                        $this.show(parseInt(item, 10));
3423
                }
3424
            });
3425
3426
            if (this.options.swiping) {
3427
3428
                this.connect.on('swipeRight swipeLeft', function(e) {
3429
                    e.preventDefault();
3430
                    if (!window.getSelection().toString()) {
3431
                        $this.show($this.index + (e.type == 'swipeLeft' ? 1 : -1));
3432
                    }
3433
                });
3434
            }
3435
3436
            this.update();
3437
        },
3438
3439
        update: function() {
3440
3441
            this.connect.children().removeClass('uk-active').attr('aria-hidden', 'true');
3442
3443
            var toggles = this.find(this.options.toggle),
3444
                active  = toggles.filter('.uk-active');
3445
3446
            if (active.length) {
3447
                this.show(active, false);
3448
            } else {
3449
3450
                if (this.options.active===false) return;
3451
3452
                active = toggles.eq(this.options.active);
3453
                this.show(active.length ? active : toggles.eq(0), false);
3454
            }
3455
3456
            // Init ARIA for toggles
3457
            toggles.not(active).attr('aria-expanded', 'false');
3458
            active.attr('aria-expanded', 'true');
3459
        },
3460
3461
        show: function(tab, animate) {
3462
3463
            if (this.animating) {
3464
                return;
3465
            }
3466
3467
            var toggles = this.find(this.options.toggle);
3468
3469
            if (isNaN(tab)) {
3470
                tab = UI.$(tab);
3471
            } else {
3472
                tab = tab < 0 ? toggles.length-1 : tab;
3473
                tab = toggles.eq(toggles[tab] ? tab : 0);
3474
            }
3475
3476
            var $this     = this,
3477
                active    = UI.$(tab),
3478
                animation = Animations[this.options.animation] || function(current, next) {
3479
3480
                    if (!$this.options.animation) {
3481
                        return Animations.none.apply($this);
3482
                    }
3483
3484
                    var anim = $this.options.animation.split(',');
3485
3486
                    if (anim.length == 1) {
3487
                        anim[1] = anim[0];
3488
                    }
3489
3490
                    anim[0] = anim[0].trim();
3491
                    anim[1] = anim[1].trim();
3492
3493
                    return coreAnimation.apply($this, [anim, current, next]);
3494
                };
3495
3496
            if (animate===false || !UI.support.animation) {
3497
                animation = Animations.none;
3498
            }
3499
3500
            if (active.hasClass("uk-disabled")) return;
3501
3502
            // Update ARIA for Toggles
3503
            toggles.attr('aria-expanded', 'false');
3504
            active.attr('aria-expanded', 'true');
3505
3506
            toggles.filter(".uk-active").removeClass("uk-active");
3507
            active.addClass("uk-active");
3508
3509
            if (this.options.connect && this.connect.length) {
3510
3511
                this.index = this.find(this.options.toggle).index(active);
3512
3513
                if (this.index == -1 ) {
3514
                    this.index = 0;
3515
                }
3516
3517
                this.connect.each(function() {
3518
3519
                    var container = UI.$(this),
3520
                        children  = UI.$(container.children()),
3521
                        current   = UI.$(children.filter('.uk-active')),
3522
                        next      = UI.$(children.eq($this.index));
3523
3524
                        $this.animating = true;
3525
3526
                        animation.apply($this, [current, next]).then(function(){
3527
3528
                            current.removeClass("uk-active");
3529
                            next.addClass("uk-active");
3530
3531
                            // Update ARIA for connect
3532
                            current.attr('aria-hidden', 'true');
3533
                            next.attr('aria-hidden', 'false');
3534
3535
                            UI.Utils.checkDisplay(next, true);
3536
3537
                            $this.animating = false;
3538
3539
                        });
3540
                });
3541
            }
3542
3543
            this.trigger("show.uk.switcher", [active]);
3544
        }
3545
    });
3546
3547
    Animations = {
3548
3549
        'none': function() {
3550
            var d = UI.$.Deferred();
3551
            d.resolve();
3552
            return d.promise();
3553
        },
3554
3555
        'fade': function(current, next) {
3556
            return coreAnimation.apply(this, ['uk-animation-fade', current, next]);
3557
        },
3558
3559
        'slide-bottom': function(current, next) {
3560
            return coreAnimation.apply(this, ['uk-animation-slide-bottom', current, next]);
3561
        },
3562
3563
        'slide-top': function(current, next) {
3564
            return coreAnimation.apply(this, ['uk-animation-slide-top', current, next]);
3565
        },
3566
3567
        'slide-vertical': function(current, next, dir) {
3568
3569
            var anim = ['uk-animation-slide-top', 'uk-animation-slide-bottom'];
3570
3571
            if (current && current.index() > next.index()) {
3572
                anim.reverse();
3573
            }
3574
3575
            return coreAnimation.apply(this, [anim, current, next]);
3576
        },
3577
3578
        'slide-left': function(current, next) {
3579
            return coreAnimation.apply(this, ['uk-animation-slide-left', current, next]);
3580
        },
3581
3582
        'slide-right': function(current, next) {
3583
            return coreAnimation.apply(this, ['uk-animation-slide-right', current, next]);
3584
        },
3585
3586
        'slide-horizontal': function(current, next, dir) {
3587
3588
            var anim = ['uk-animation-slide-right', 'uk-animation-slide-left'];
3589
3590
            if (current && current.index() > next.index()) {
3591
                anim.reverse();
3592
            }
3593
3594
            return coreAnimation.apply(this, [anim, current, next]);
3595
        },
3596
3597
        'scale': function(current, next) {
3598
            return coreAnimation.apply(this, ['uk-animation-scale-up', current, next]);
3599
        }
3600
    };
3601
3602
    UI.switcher.animations = Animations;
3603
3604
3605
    // helpers
3606
3607
    function coreAnimation(cls, current, next) {
3608
3609
        var d = UI.$.Deferred(), clsIn = cls, clsOut = cls, release;
3610
3611
        if (next[0]===current[0]) {
3612
            d.resolve();
3613
            return d.promise();
3614
        }
3615
3616
        if (typeof(cls) == 'object') {
3617
            clsIn  = cls[0];
3618
            clsOut = cls[1] || cls[0];
3619
        }
3620
3621
        UI.$body.css('overflow-x', 'hidden'); // fix scroll jumping in iOS
3622
3623
        release = function() {
3624
3625
            if (current) current.hide().removeClass('uk-active '+clsOut+' uk-animation-reverse');
3626
3627
            next.addClass(clsIn).one(UI.support.animation.end, function() {
3628
3629
                setTimeout(function () {
3630
                    next.removeClass(''+clsIn+'').css({opacity:'', display:''});
3631
                }, 0);
3632
3633
                d.resolve();
3634
3635
                UI.$body.css('overflow-x', '');
3636
3637
                if (current) current.css({opacity:'', display:''});
3638
3639
            }.bind(this)).show();
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
3640
        };
3641
3642
        next.css('animation-duration', this.options.duration+'ms');
3643
3644
        if (current && current.length) {
3645
3646
            current.css('animation-duration', this.options.duration+'ms');
3647
3648
            current.css('display', 'none').addClass(clsOut+' uk-animation-reverse').one(UI.support.animation.end, function() {
3649
                release();
3650
            }.bind(this)).css('display', '');
0 ignored issues
show
unused-code introduced by
The call to bind does not seem necessary since the function does not use this. Consider calling it directly.
Loading history...
3651
3652
        } else {
3653
            next.addClass('uk-active');
3654
            release();
3655
        }
3656
3657
        return d.promise();
3658
    }
3659
3660
})(UIkit2);
3661
3662 View Code Duplication
(function(UI) {
3663
3664
    "use strict";
3665
3666
    UI.component('tab', {
3667
3668
        defaults: {
3669
            target    : '>li:not(.uk-tab-responsive, .uk-disabled)',
3670
            connect   : false,
3671
            active    : 0,
3672
            animation : false,
3673
            duration  : 200,
3674
            swiping   : true
3675
        },
3676
3677
        boot: function() {
3678
3679
            // init code
3680
            UI.ready(function(context) {
3681
3682
                UI.$('[data-uk-tab]', context).each(function() {
3683
3684
                    var tab = UI.$(this);
3685
3686
                    if (!tab.data('tab')) {
3687
                        var obj = UI.tab(tab, UI.Utils.options(tab.attr('data-uk-tab')));
0 ignored issues
show
Unused Code introduced by
The variable obj seems to be never used. Consider removing it.
Loading history...
3688
                    }
3689
                });
3690
            });
3691
        },
3692
3693
        init: function() {
3694
3695
            var $this = this;
3696
3697
            this.current = false;
3698
3699
            this.on('click.uk.tab', this.options.target, function(e) {
3700
3701
                e.preventDefault();
3702
3703
                if ($this.switcher && $this.switcher.animating) {
3704
                    return;
3705
                }
3706
3707
                var current = $this.find($this.options.target).not(this);
3708
3709
                current.removeClass('uk-active').blur();
3710
3711
                $this.trigger('change.uk.tab', [UI.$(this).addClass('uk-active'), $this.current]);
3712
3713
                $this.current = UI.$(this);
3714
3715
                // Update ARIA
3716
                if (!$this.options.connect) {
3717
                    current.attr('aria-expanded', 'false');
3718
                    UI.$(this).attr('aria-expanded', 'true');
3719
                }
3720
            });
3721
3722
            if (this.options.connect) {
3723
                this.connect = UI.$(this.options.connect);
3724
            }
3725
3726
            // init responsive tab
3727
            this.responsivetab = UI.$('<li class="uk-tab-responsive uk-active"><a></a></li>').append('<div class="uk-dropdown uk-dropdown-small"><ul class="uk-nav uk-nav-dropdown"></ul><div>');
3728
3729
            this.responsivetab.dropdown = this.responsivetab.find('.uk-dropdown');
3730
            this.responsivetab.lst      = this.responsivetab.dropdown.find('ul');
3731
            this.responsivetab.caption  = this.responsivetab.find('a:first');
3732
3733
            if (this.element.hasClass('uk-tab-bottom')) this.responsivetab.dropdown.addClass('uk-dropdown-up');
3734
3735
            // handle click
3736
            this.responsivetab.lst.on('click.uk.tab', 'a', function(e) {
3737
3738
                e.preventDefault();
3739
                e.stopPropagation();
3740
3741
                var link = UI.$(this);
3742
3743
                $this.element.children('li:not(.uk-tab-responsive)').eq(link.data('index')).trigger('click');
3744
            });
3745
3746
            this.on('show.uk.switcher change.uk.tab', function(e, tab) {
3747
                $this.responsivetab.caption.html(tab.text());
3748
            });
3749
3750
            this.element.append(this.responsivetab);
3751
3752
            // init UIkit components
3753
            if (this.options.connect) {
3754
3755
                this.switcher = UI.switcher(this.element, {
3756
                    toggle    : '>li:not(.uk-tab-responsive)',
3757
                    connect   : this.options.connect,
3758
                    active    : this.options.active,
3759
                    animation : this.options.animation,
3760
                    duration  : this.options.duration,
3761
                    swiping   : this.options.swiping
3762
                });
3763
            }
3764
3765
            UI.dropdown(this.responsivetab, {mode: 'click', preventflip: 'y'});
3766
3767
            // init
3768
            $this.trigger('change.uk.tab', [this.element.find(this.options.target).not('.uk-tab-responsive').filter('.uk-active')]);
3769
3770
            this.check();
3771
3772
            UI.$win.on('resize orientationchange', UI.Utils.debounce(function(){
3773
                if ($this.element.is(':visible'))  $this.check();
3774
            }, 100));
3775
3776
            this.on('display.uk.check', function(){
3777
                if ($this.element.is(':visible'))  $this.check();
3778
            });
3779
        },
3780
3781
        check: function() {
3782
3783
            var children = this.element.children('li:not(.uk-tab-responsive)').removeClass('uk-hidden');
3784
3785
            if (!children.length) {
3786
                this.responsivetab.addClass('uk-hidden');
3787
                return;
3788
            }
3789
3790
            var top          = (children.eq(0).offset().top + Math.ceil(children.eq(0).height()/2)),
3791
                doresponsive = false,
3792
                item, link, clone;
3793
3794
            this.responsivetab.lst.empty();
3795
3796
            children.each(function(){
3797
3798
                if (UI.$(this).offset().top > top) {
3799
                    doresponsive = true;
3800
                }
3801
            });
3802
3803
            if (doresponsive) {
3804
3805
                for (var i = 0; i < children.length; i++) {
3806
3807
                    item  = UI.$(children.eq(i));
3808
                    link  = item.find('a');
0 ignored issues
show
Unused Code introduced by
The variable link seems to be never used. Consider removing it.
Loading history...
3809
3810
                    if (item.css('float') != 'none' && !item.attr('uk-dropdown')) {
3811
3812
                        if (!item.hasClass('uk-disabled')) {
3813
3814
                            clone = UI.$(item[0].outerHTML);
3815
                            clone.find('a').data('index', i);
3816
3817
                            this.responsivetab.lst.append(clone);
3818
                        }
3819
3820
                        item.addClass('uk-hidden');
3821
                    }
3822
                }
3823
            }
3824
3825
            this.responsivetab[this.responsivetab.lst.children('li').length ? 'removeClass':'addClass']('uk-hidden');
3826
        }
3827
    });
3828
3829
})(UIkit2);
3830
3831 View Code Duplication
(function(UI){
3832
3833
    "use strict";
3834
3835
    UI.component('cover', {
3836
3837
        defaults: {
3838
            automute : true
3839
        },
3840
3841
        boot: function() {
3842
3843
            // auto init
3844
            UI.ready(function(context) {
3845
3846
                UI.$('[data-uk-cover]', context).each(function(){
3847
3848
                    var ele = UI.$(this);
3849
3850
                    if(!ele.data('cover')) {
3851
                        var plugin = UI.cover(ele, UI.Utils.options(ele.attr('data-uk-cover')));
0 ignored issues
show
Unused Code introduced by
The variable plugin seems to be never used. Consider removing it.
Loading history...
3852
                    }
3853
                });
3854
            });
3855
        },
3856
3857
        init: function() {
3858
3859
            this.parent = this.element.parent();
3860
3861
            UI.$win.on('load resize orientationchange', UI.Utils.debounce(function(){
3862
                this.check();
3863
            }.bind(this), 100));
3864
3865
            this.on('display.uk.check', function(e) {
3866
                if (this.element.is(':visible')) this.check();
3867
            }.bind(this));
3868
3869
            this.check();
3870
3871
            if (this.element.is('iframe') && this.options.automute) {
3872
3873
                var src = this.element.attr('src');
3874
3875
                this.element.attr('src', '').on('load', function(){
3876
                    this.contentWindow.postMessage('{ "event": "command", "func": "mute", "method":"setVolume", "value":0}', '*');
3877
                }).attr('src', [src, (src.indexOf('?') > -1 ? '&':'?'), 'enablejsapi=1&api=1'].join(''));
3878
            }
3879
        },
3880
3881
        check: function() {
3882
3883
            this.element.css({ width  : '', height : '' });
3884
3885
            this.dimension = {w: this.element.width(), h: this.element.height()};
3886
3887
            if (this.element.attr('width') && !isNaN(this.element.attr('width'))) {
3888
                this.dimension.w = this.element.attr('width');
3889
            }
3890
3891
            if (this.element.attr('height') && !isNaN(this.element.attr('height'))) {
3892
                this.dimension.h = this.element.attr('height');
3893
            }
3894
3895
            this.ratio = this.dimension.w / this.dimension.h;
3896
3897
            var w = this.parent.width(), h = this.parent.height(), width, height;
3898
3899
            // if element height < parent height (gap underneath)
3900
            if ((w / this.ratio) < h) {
3901
3902
                width  = Math.ceil(h * this.ratio);
3903
                height = h;
3904
3905
            // element width < parent width (gap to right)
3906
            } else {
3907
3908
                width  = w;
3909
                height = Math.ceil(w / this.ratio);
3910
            }
3911
3912
            this.element.css({ width  : width, height : height });
3913
        }
3914
    });
3915
3916
})(UIkit2);
3917