PluginProbe ʕ •ᴥ•ʔ
Shortcodes and extra features for Phlox theme / 2.8.1
Shortcodes and extra features for Phlox theme v2.8.1
2.17.20 trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.0.6 1.0.9 1.1.0 1.3.0 1.3.1 1.3.10 1.3.14 1.3.2 1.3.3 1.3.6 1.4.0 1.4.1 1.4.2 1.5.0 1.5.2 1.6.0 1.6.2 1.6.4 1.7.0 1.7.2 2.10.0 2.10.1 2.10.3 2.10.5 2.10.7 2.10.8 2.10.9 2.11.0 2.11.1 2.11.2 2.12.0 2.14.0 2.15.0 2.15.2 2.15.4 2.15.5 2.15.6 2.15.7 2.15.8 2.15.9 2.16.0 2.16.1 2.16.2 2.16.3 2.16.4 2.17.0 2.17.1 2.17.12 2.17.13 2.17.14 2.17.15 2.17.16 2.17.2 2.17.3 2.17.4 2.17.5 2.17.6 2.17.8 2.17.9 2.4.12 2.4.13 2.4.14 2.4.16 2.4.18 2.4.19 2.4.9 2.5.0 2.5.1 2.5.10 2.5.11 2.5.12 2.5.13 2.5.14 2.5.15 2.5.16 2.5.17 2.5.19 2.5.2 2.5.20 2.5.3 2.5.7 2.5.8 2.5.9 2.6.0 2.6.1 2.6.10 2.6.12 2.6.13 2.6.14 2.6.15 2.6.16 2.6.17 2.6.19 2.6.2 2.6.20 2.6.4 2.6.5 2.6.7 2.7.0 2.7.1 2.7.10 2.7.11 2.7.12 2.7.13 2.7.14 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 2.7.8 2.7.9 2.8.0 2.8.1 2.8.2 2.8.3 2.8.4 2.8.5 2.8.6 2.8.7 2.8.9 2.9.0 2.9.12 2.9.14 2.9.15 2.9.16 2.9.17 2.9.18 2.9.19 2.9.2 2.9.20 2.9.21 2.9.22 2.9.3 2.9.4 2.9.5 2.9.6 2.9.7 2.9.8
auxin-elements / admin / assets / js / plugins.js
auxin-elements / admin / assets / js Last commit date
elementor 5 years ago solo 5 years ago tinymce 9 years ago index.php 9 years ago plugins.js 5 years ago plugins.min.js 5 years ago scripts.js 7 years ago
plugins.js
2696 lines
1 /*! Phlox Core Plugin - v2.8.1 (2021-07)
2 * All required javascript plugins for admin
3 * http://phlox.pro/
4 * Place any jQuery/helper plugins in here, instead of separate, slower script files!
5 */
6
7 if( typeof Object.create !== 'function' ){ Object.create = function (obj){ function F(){} F.prototype = obj; return new F();}; }
8
9 /*!
10 * ================== admin/assets/js/libs/featherlight.js ===================
11 **/
12
13 /**
14 * Featherlight - ultra slim jQuery lightbox
15 * Version 1.7.12 - http://noelboss.github.io/featherlight/
16 *
17 * Copyright 2017, Noël Raoul Bossart (http://www.noelboss.com)
18 * MIT Licensed.
19 **/
20 (function($) {
21 "use strict";
22
23 if('undefined' === typeof $) {
24 if('console' in window){ window.console.info('Too much lightness, Featherlight needs jQuery.'); }
25 return;
26 }
27 if($.fn.jquery.match(/-ajax/)) {
28 if('console' in window){ window.console.info('Featherlight needs regular jQuery, not the slim version.'); }
29 return;
30 }
31 /* Featherlight is exported as $.featherlight.
32 It is a function used to open a featherlight lightbox.
33
34 [tech]
35 Featherlight uses prototype inheritance.
36 Each opened lightbox will have a corresponding object.
37 That object may have some attributes that override the
38 prototype's.
39 Extensions created with Featherlight.extend will have their
40 own prototype that inherits from Featherlight's prototype,
41 thus attributes can be overriden either at the object level,
42 or at the extension level.
43 To create callbacks that chain themselves instead of overriding,
44 use chainCallbacks.
45 For those familiar with CoffeeScript, this correspond to
46 Featherlight being a class and the Gallery being a class
47 extending Featherlight.
48 The chainCallbacks is used since we don't have access to
49 CoffeeScript's `super`.
50 */
51
52 function Featherlight($content, config) {
53 if(this instanceof Featherlight) { /* called with new */
54 this.id = Featherlight.id++;
55 this.setup($content, config);
56 this.chainCallbacks(Featherlight._callbackChain);
57 } else {
58 var fl = new Featherlight($content, config);
59 fl.open();
60 return fl;
61 }
62 }
63
64 var opened = [],
65 pruneOpened = function(remove) {
66 opened = $.grep(opened, function(fl) {
67 return fl !== remove && fl.$instance.closest('body').length > 0;
68 } );
69 return opened;
70 };
71
72 // Removes keys of `set` from `obj` and returns the removed key/values.
73 function slice(obj, set) {
74 var r = {};
75 for (var key in obj) {
76 if (key in set) {
77 r[key] = obj[key];
78 delete obj[key];
79 }
80 }
81 return r;
82 }
83
84 // NOTE: List of available [iframe attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).
85 var iFrameAttributeSet = {
86 allowfullscreen: 1, frameborder: 1, height: 1, longdesc: 1, marginheight: 1, marginwidth: 1,
87 name: 1, referrerpolicy: 1, scrolling: 1, sandbox: 1, src: 1, srcdoc: 1, width: 1
88 };
89
90 // Converts camelCased attributes to dasherized versions for given prefix:
91 // parseAttrs({hello: 1, hellFrozeOver: 2}, 'hell') => {froze-over: 2}
92 function parseAttrs(obj, prefix) {
93 var attrs = {},
94 regex = new RegExp('^' + prefix + '([A-Z])(.*)');
95 for (var key in obj) {
96 var match = key.match(regex);
97 if (match) {
98 var dasherized = (match[1] + match[2].replace(/([A-Z])/g, '-$1')).toLowerCase();
99 attrs[dasherized] = obj[key];
100 }
101 }
102 return attrs;
103 }
104
105 /* document wide key handler */
106 var eventMap = { keyup: 'onKeyUp', resize: 'onResize' };
107
108 var globalEventHandler = function(event) {
109 $.each(Featherlight.opened().reverse(), function() {
110 if (!event.isDefaultPrevented()) {
111 if (false === this[eventMap[event.type]](event)) {
112 event.preventDefault(); event.stopPropagation(); return false;
113 }
114 }
115 });
116 };
117
118 var toggleGlobalEvents = function(set) {
119 if(set !== Featherlight._globalHandlerInstalled) {
120 Featherlight._globalHandlerInstalled = set;
121 var events = $.map(eventMap, function(_, name) { return name+'.'+Featherlight.prototype.namespace; } ).join(' ');
122 $(window)[set ? 'on' : 'off'](events, globalEventHandler);
123 }
124 };
125
126 Featherlight.prototype = {
127 constructor: Featherlight,
128 /*** defaults ***/
129 /* extend featherlight with defaults and methods */
130 namespace: 'featherlight', /* Name of the events and css class prefix */
131 targetAttr: 'data-featherlight', /* Attribute of the triggered element that contains the selector to the lightbox content */
132 variant: null, /* Class that will be added to change look of the lightbox */
133 resetCss: false, /* Reset all css */
134 background: null, /* Custom DOM for the background, wrapper and the closebutton */
135 openTrigger: 'click', /* Event that triggers the lightbox */
136 closeTrigger: 'click', /* Event that triggers the closing of the lightbox */
137 filter: null, /* Selector to filter events. Think $(...).on('click', filter, eventHandler) */
138 root: 'body', /* Where to append featherlights */
139 openSpeed: 250, /* Duration of opening animation */
140 closeSpeed: 250, /* Duration of closing animation */
141 closeOnClick: 'background', /* Close lightbox on click ('background', 'anywhere' or false) */
142 closeOnEsc: true, /* Close lightbox when pressing esc */
143 closeIcon: '✕', /* Close icon */
144 loading: '', /* Content to show while initial content is loading */
145 persist: false, /* If set, the content will persist and will be shown again when opened again. 'shared' is a special value when binding multiple elements for them to share the same content */
146 otherClose: null, /* Selector for alternate close buttons (e.g. "a.close") */
147 beforeOpen: $.noop, /* Called before open. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */
148 beforeContent: $.noop, /* Called when content is loaded. Gets event as parameter, this contains all data */
149 beforeClose: $.noop, /* Called before close. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */
150 afterOpen: $.noop, /* Called after open. Gets event as parameter, this contains all data */
151 afterContent: $.noop, /* Called after content is ready and has been set. Gets event as parameter, this contains all data */
152 afterClose: $.noop, /* Called after close. Gets event as parameter, this contains all data */
153 onKeyUp: $.noop, /* Called on key up for the frontmost featherlight */
154 onResize: $.noop, /* Called after new content and when a window is resized */
155 type: null, /* Specify type of lightbox. If unset, it will check for the targetAttrs value. */
156 contentFilters: ['jquery', 'image', 'html', 'ajax', 'iframe', 'text'], /* List of content filters to use to determine the content */
157
158 /*** methods ***/
159 /* setup iterates over a single instance of featherlight and prepares the background and binds the events */
160 setup: function(target, config){
161 /* all arguments are optional */
162 if (typeof target === 'object' && target instanceof $ === false && !config) {
163 config = target;
164 target = undefined;
165 }
166
167 var self = $.extend(this, config, {target: target}),
168 css = !self.resetCss ? self.namespace : self.namespace+'-reset', /* by adding -reset to the classname, we reset all the default css */
169 $background = $(self.background || [
170 '<div class="'+css+'-loading '+css+'">',
171 '<div class="'+css+'-content">',
172 '<button class="'+css+'-close-icon '+ self.namespace + '-close" aria-label="Close">',
173 self.closeIcon,
174 '</button>',
175 '<div class="'+self.namespace+'-inner">' + self.loading + '</div>',
176 '</div>',
177 '</div>'].join('')),
178 closeButtonSelector = '.'+self.namespace+'-close' + (self.otherClose ? ',' + self.otherClose : '');
179
180 self.$instance = $background.clone().addClass(self.variant); /* clone DOM for the background, wrapper and the close button */
181
182 /* close when click on background/anywhere/null or closebox */
183 self.$instance.on(self.closeTrigger+'.'+self.namespace, function(event) {
184 if(event.isDefaultPrevented()) {
185 return;
186 }
187 var $target = $(event.target);
188 if( ('background' === self.closeOnClick && $target.is('.'+self.namespace))
189 || 'anywhere' === self.closeOnClick
190 || $target.closest(closeButtonSelector).length ){
191 self.close(event);
192 event.preventDefault();
193 }
194 });
195
196 return this;
197 },
198
199 /* this method prepares the content and converts it into a jQuery object or a promise */
200 getContent: function(){
201 if(this.persist !== false && this.$content) {
202 return this.$content;
203 }
204 var self = this,
205 filters = this.constructor.contentFilters,
206 readTargetAttr = function(name){ return self.$currentTarget && self.$currentTarget.attr(name); },
207 targetValue = readTargetAttr(self.targetAttr),
208 data = self.target || targetValue || '';
209
210 /* Find which filter applies */
211 var filter = filters[self.type]; /* check explicit type like {type: 'image'} */
212
213 /* check explicit type like data-featherlight="image" */
214 if(!filter && data in filters) {
215 filter = filters[data];
216 data = self.target && targetValue;
217 }
218 data = data || readTargetAttr('href') || '';
219
220 /* check explicity type & content like {image: 'photo.jpg'} */
221 if(!filter) {
222 for(var filterName in filters) {
223 if(self[filterName]) {
224 filter = filters[filterName];
225 data = self[filterName];
226 }
227 }
228 }
229
230 /* otherwise it's implicit, run checks */
231 if(!filter) {
232 var target = data;
233 data = null;
234 $.each(self.contentFilters, function() {
235 filter = filters[this];
236 if(filter.test) {
237 data = filter.test(target);
238 }
239 if(!data && filter.regex && target.match && target.match(filter.regex)) {
240 data = target;
241 }
242 return !data;
243 });
244 if(!data) {
245 if('console' in window){ window.console.error('Featherlight: no content filter found ' + (target ? ' for "' + target + '"' : ' (no target specified)')); }
246 return false;
247 }
248 }
249 /* Process it */
250 return filter.process.call(self, data);
251 },
252
253 /* sets the content of $instance to $content */
254 setContent: function($content){
255 this.$instance.removeClass(this.namespace+'-loading');
256
257 /* we need a special class for the iframe */
258 this.$instance.toggleClass(this.namespace+'-iframe', $content.is('iframe'));
259
260 /* replace content by appending to existing one before it is removed
261 this insures that featherlight-inner remain at the same relative
262 position to any other items added to featherlight-content */
263 this.$instance.find('.'+this.namespace+'-inner')
264 .not($content) /* excluded new content, important if persisted */
265 .slice(1).remove().end() /* In the unexpected event where there are many inner elements, remove all but the first one */
266 .replaceWith($.contains(this.$instance[0], $content[0]) ? '' : $content);
267
268 this.$content = $content.addClass(this.namespace+'-inner');
269
270 return this;
271 },
272
273 /* opens the lightbox. "this" contains $instance with the lightbox, and with the config.
274 Returns a promise that is resolved after is successfully opened. */
275 open: function(event){
276 var self = this;
277 self.$instance.hide().appendTo(self.root);
278 if((!event || !event.isDefaultPrevented())
279 && self.beforeOpen(event) !== false) {
280
281 if(event){
282 event.preventDefault();
283 }
284 var $content = self.getContent();
285
286 if($content) {
287 opened.push(self);
288
289 toggleGlobalEvents(true);
290
291 self.$instance.fadeIn(self.openSpeed);
292 self.beforeContent(event);
293
294 /* Set content and show */
295 return $.when($content)
296 .always(function($content){
297 self.setContent($content);
298 self.afterContent(event);
299 })
300 .then(self.$instance.promise())
301 /* Call afterOpen after fadeIn is done */
302 .done(function(){ self.afterOpen(event); });
303 }
304 }
305 self.$instance.detach();
306 return $.Deferred().reject().promise();
307 },
308
309 /* closes the lightbox. "this" contains $instance with the lightbox, and with the config
310 returns a promise, resolved after the lightbox is successfully closed. */
311 close: function(event){
312 var self = this,
313 deferred = $.Deferred();
314
315 if(self.beforeClose(event) === false) {
316 deferred.reject();
317 } else {
318
319 if (0 === pruneOpened(self).length) {
320 toggleGlobalEvents(false);
321 }
322
323 self.$instance.fadeOut(self.closeSpeed,function(){
324 self.$instance.detach();
325 self.afterClose(event);
326 deferred.resolve();
327 });
328 }
329 return deferred.promise();
330 },
331
332 /* resizes the content so it fits in visible area and keeps the same aspect ratio.
333 Does nothing if either the width or the height is not specified.
334 Called automatically on window resize.
335 Override if you want different behavior. */
336 resize: function(w, h) {
337 if (w && h) {
338 /* Reset apparent image size first so container grows */
339 this.$content.css('width', '').css('height', '');
340 /* Calculate the worst ratio so that dimensions fit */
341 /* Note: -1 to avoid rounding errors */
342 var ratio = Math.max(
343 w / (this.$content.parent().width()-1),
344 h / (this.$content.parent().height()-1));
345 /* Resize content */
346 if (ratio > 1) {
347 ratio = h / Math.floor(h / ratio); /* Round ratio down so height calc works */
348 this.$content.css('width', '' + w / ratio + 'px').css('height', '' + h / ratio + 'px');
349 }
350 }
351 },
352
353 /* Utility function to chain callbacks
354 [Warning: guru-level]
355 Used be extensions that want to let users specify callbacks but
356 also need themselves to use the callbacks.
357 The argument 'chain' has callback names as keys and function(super, event)
358 as values. That function is meant to call `super` at some point.
359 */
360 chainCallbacks: function(chain) {
361 for (var name in chain) {
362 this[name] = chain[name].bind(this, this[name].bind(this));
363 }
364 }
365 };
366
367 $.extend(Featherlight, {
368 id: 0, /* Used to id single featherlight instances */
369 autoBind: '[data-featherlight]', /* Will automatically bind elements matching this selector. Clear or set before onReady */
370 defaults: Featherlight.prototype, /* You can access and override all defaults using $.featherlight.defaults, which is just a synonym for $.featherlight.prototype */
371 /* Contains the logic to determine content */
372 contentFilters: {
373 jquery: {
374 regex: /^[#.]\w/, /* Anything that starts with a class name or identifiers */
375 test: function(elem) { return elem instanceof $ && elem; },
376 process: function(elem) { return this.persist !== false ? $(elem) : $(elem).clone(true); }
377 },
378 image: {
379 regex: /\.(png|jpg|jpeg|gif|tiff?|bmp|svg)(\?\S*)?$/i,
380 process: function(url) {
381 var self = this,
382 deferred = $.Deferred(),
383 img = new Image(),
384 $img = $('<img src="'+url+'" alt="" class="'+self.namespace+'-image" />');
385 img.onload = function() {
386 /* Store naturalWidth & height for IE8 */
387 $img.naturalWidth = img.width; $img.naturalHeight = img.height;
388 deferred.resolve( $img );
389 };
390 img.onerror = function() { deferred.reject($img); };
391 img.src = url;
392 return deferred.promise();
393 }
394 },
395 html: {
396 regex: /^\s*<[\w!][^<]*>/, /* Anything that starts with some kind of valid tag */
397 process: function(html) { return $(html); }
398 },
399 ajax: {
400 regex: /./, /* At this point, any content is assumed to be an URL */
401 process: function(url) {
402 var self = this,
403 deferred = $.Deferred();
404 /* we are using load so one can specify a target with: url.html #targetelement */
405 var $container = $('<div></div>').load(url, function(response, status){
406 if ( status !== "error" ) {
407 deferred.resolve($container.contents());
408 }
409 deferred.fail();
410 });
411 return deferred.promise();
412 }
413 },
414 iframe: {
415 process: function(url) {
416 var deferred = new $.Deferred();
417 var $content = $('<iframe/>');
418 var css = parseAttrs(this, 'iframe');
419 var attrs = slice(css, iFrameAttributeSet);
420 $content.hide()
421 .attr('src', url)
422 .attr(attrs)
423 .css(css)
424 .on('load', function() { deferred.resolve($content.show()); })
425 // We can't move an <iframe> and avoid reloading it,
426 // so let's put it in place ourselves right now:
427 .appendTo(this.$instance.find('.' + this.namespace + '-content'));
428 return deferred.promise();
429 }
430 },
431 text: {
432 process: function(text) { return $('<div>', {text: text}); }
433 }
434 },
435
436 functionAttributes: ['beforeOpen', 'afterOpen', 'beforeContent', 'afterContent', 'beforeClose', 'afterClose'],
437
438 /*** class methods ***/
439 /* read element's attributes starting with data-featherlight- */
440 readElementConfig: function(element, namespace) {
441 var Klass = this,
442 regexp = new RegExp('^data-' + namespace + '-(.*)'),
443 config = {};
444 if (element && element.attributes) {
445 $.each(element.attributes, function(){
446 var match = this.name.match(regexp);
447 if (match) {
448 var val = this.value,
449 name = $.camelCase(match[1]);
450 if ($.inArray(name, Klass.functionAttributes) >= 0) { /* jshint -W054 */
451 val = new Function(val); /* jshint +W054 */
452 } else {
453 try { val = JSON.parse(val); }
454 catch(e) {}
455 }
456 config[name] = val;
457 }
458 });
459 }
460 return config;
461 },
462
463 /* Used to create a Featherlight extension
464 [Warning: guru-level]
465 Creates the extension's prototype that in turn
466 inherits Featherlight's prototype.
467 Could be used to extend an extension too...
468 This is pretty high level wizardy, it comes pretty much straight
469 from CoffeeScript and won't teach you anything about Featherlight
470 as it's not really specific to this library.
471 My suggestion: move along and keep your sanity.
472 */
473 extend: function(child, defaults) {
474 /* Setup class hierarchy, adapted from CoffeeScript */
475 var Ctor = function(){ this.constructor = child; };
476 Ctor.prototype = this.prototype;
477 child.prototype = new Ctor();
478 child.__super__ = this.prototype;
479 /* Copy class methods & attributes */
480 $.extend(child, this, defaults);
481 child.defaults = child.prototype;
482 return child;
483 },
484
485 attach: function($source, $content, config) {
486 var Klass = this;
487 if (typeof $content === 'object' && $content instanceof $ === false && !config) {
488 config = $content;
489 $content = undefined;
490 }
491 /* make a copy */
492 config = $.extend({}, config);
493
494 /* Only for openTrigger and namespace... */
495 var namespace = config.namespace || Klass.defaults.namespace,
496 tempConfig = $.extend({}, Klass.defaults, Klass.readElementConfig($source[0], namespace), config),
497 sharedPersist;
498 var handler = function(event) {
499 var $target = $(event.currentTarget);
500 /* ... since we might as well compute the config on the actual target */
501 var elemConfig = $.extend(
502 {$source: $source, $currentTarget: $target},
503 Klass.readElementConfig($source[0], tempConfig.namespace),
504 Klass.readElementConfig(event.currentTarget, tempConfig.namespace),
505 config);
506 var fl = sharedPersist || $target.data('featherlight-persisted') || new Klass($content, elemConfig);
507 if(fl.persist === 'shared') {
508 sharedPersist = fl;
509 } else if(fl.persist !== false) {
510 $target.data('featherlight-persisted', fl);
511 }
512 if (elemConfig.$currentTarget.blur) {
513 elemConfig.$currentTarget.blur(); // Otherwise 'enter' key might trigger the dialog again
514 }
515 fl.open(event);
516 };
517
518 $source.on(tempConfig.openTrigger+'.'+tempConfig.namespace, tempConfig.filter, handler);
519
520 return handler;
521 },
522
523 current: function() {
524 var all = this.opened();
525 return all[all.length - 1] || null;
526 },
527
528 opened: function() {
529 var klass = this;
530 pruneOpened();
531 return $.grep(opened, function(fl) { return fl instanceof klass; } );
532 },
533
534 close: function(event) {
535 var cur = this.current();
536 if(cur) { return cur.close(event); }
537 },
538
539 /* Does the auto binding on startup.
540 Meant only to be used by Featherlight and its extensions
541 */
542 _onReady: function() {
543 var Klass = this;
544 if(Klass.autoBind){
545 /* Bind existing elements */
546 $(Klass.autoBind).each(function(){
547 Klass.attach($(this));
548 });
549 /* If a click propagates to the document level, then we have an item that was added later on */
550 $(document).on('click', Klass.autoBind, function(evt) {
551 if (evt.isDefaultPrevented()) {
552 return;
553 }
554 /* Bind featherlight */
555 var handler = Klass.attach($(evt.currentTarget));
556 /* Dispatch event directly */
557 handler(evt);
558 });
559 }
560 },
561
562 /* Featherlight uses the onKeyUp callback to intercept the escape key.
563 Private to Featherlight.
564 */
565 _callbackChain: {
566 onKeyUp: function(_super, event){
567 if(27 === event.keyCode) {
568 if (this.closeOnEsc) {
569 $.featherlight.close(event);
570 }
571 return false;
572 } else {
573 return _super(event);
574 }
575 },
576
577 beforeOpen: function(_super, event) {
578 // Used to disable scrolling
579 $(document.documentElement).addClass('with-featherlight');
580
581 // Remember focus:
582 this._previouslyActive = document.activeElement;
583
584 // Disable tabbing:
585 // See http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus
586 this._$previouslyTabbable = $("a, input, select, textarea, iframe, button, iframe, [contentEditable=true]")
587 .not('[tabindex]')
588 .not(this.$instance.find('button'));
589
590 this._$previouslyWithTabIndex = $('[tabindex]').not('[tabindex="-1"]');
591 this._previousWithTabIndices = this._$previouslyWithTabIndex.map(function(_i, elem) {
592 return $(elem).attr('tabindex');
593 });
594
595 this._$previouslyWithTabIndex.add(this._$previouslyTabbable).attr('tabindex', -1);
596
597 if (document.activeElement.blur) {
598 document.activeElement.blur();
599 }
600 return _super(event);
601 },
602
603 afterClose: function(_super, event) {
604 var r = _super(event);
605 // Restore focus
606 var self = this;
607 this._$previouslyTabbable.removeAttr('tabindex');
608 this._$previouslyWithTabIndex.each(function(i, elem) {
609 $(elem).attr('tabindex', self._previousWithTabIndices[i]);
610 });
611 this._previouslyActive.focus();
612 // Restore scroll
613 if(Featherlight.opened().length === 0) {
614 $(document.documentElement).removeClass('with-featherlight');
615 }
616 return r;
617 },
618
619 onResize: function(_super, event){
620 this.resize(this.$content.naturalWidth, this.$content.naturalHeight);
621 return _super(event);
622 },
623
624 afterContent: function(_super, event){
625 var r = _super(event);
626 this.$instance.find('[autofocus]:not([disabled])').focus();
627 this.onResize(event);
628 return r;
629 }
630 }
631 });
632
633 $.featherlight = Featherlight;
634
635 /* bind jQuery elements to trigger featherlight */
636 $.fn.featherlight = function($content, config) {
637 Featherlight.attach(this, $content, config);
638 return this;
639 };
640
641 /* bind featherlight on ready if config autoBind is set */
642 $(document).ready(function(){ Featherlight._onReady(); });
643 }(jQuery));
644
645
646 /*!
647 * ================== admin/assets/js/libs/jquery.scrollTo.js ===================
648 **/
649
650 /*!
651 * jQuery.scrollTo
652 * Copyright (c) 2007-2015 Ariel Flesler - aflesler<a>gmail<d>com | http://flesler.blogspot.com
653 * Licensed under MIT
654 * http://flesler.blogspot.com/2007/10/jqueryscrollto.html
655 * @projectDescription Lightweight, cross-browser and highly customizable animated scrolling with jQuery
656 * @author Ariel Flesler
657 * @version 2.1.2
658 */
659 ;(function(factory) {
660 'use strict';
661 if (typeof define === 'function' && define.amd) {
662 // AMD
663 define(['jquery'], factory);
664 } else if (typeof module !== 'undefined' && module.exports) {
665 // CommonJS
666 module.exports = factory(require('jquery'));
667 } else {
668 // Global
669 factory(jQuery);
670 }
671 })(function($) {
672 'use strict';
673
674 var isFunction = function(value) {return typeof value === 'function';}
675
676 var $scrollTo = $.scrollTo = function(target, duration, settings) {
677 return $(window).scrollTo(target, duration, settings);
678 };
679
680 $scrollTo.defaults = {
681 axis:'xy',
682 duration: 0,
683 limit:true
684 };
685
686 function isWin(elem) {
687 return !elem.nodeName ||
688 $.inArray(elem.nodeName.toLowerCase(), ['iframe','#document','html','body']) !== -1;
689 }
690
691 $.fn.scrollTo = function(target, duration, settings) {
692 if (typeof duration === 'object') {
693 settings = duration;
694 duration = 0;
695 }
696 if (typeof settings === 'function') {
697 settings = { onAfter:settings };
698 }
699 if (target === 'max') {
700 target = 9e9;
701 }
702
703 settings = $.extend({}, $scrollTo.defaults, settings);
704 // Speed is still recognized for backwards compatibility
705 duration = duration || settings.duration;
706 // Make sure the settings are given right
707 var queue = settings.queue && settings.axis.length > 1;
708 if (queue) {
709 // Let's keep the overall duration
710 duration /= 2;
711 }
712 settings.offset = both(settings.offset);
713 settings.over = both(settings.over);
714
715 return this.each(function() {
716 // Null target yields nothing, just like jQuery does
717 if (target === null) return;
718
719 var win = isWin(this),
720 elem = win ? this.contentWindow || window : this,
721 $elem = $(elem),
722 targ = target,
723 attr = {},
724 toff;
725
726 switch (typeof targ) {
727 // A number will pass the regex
728 case 'number':
729 case 'string':
730 if (/^([+-]=?)?\d+(\.\d+)?(px|%)?$/.test(targ)) {
731 targ = both(targ);
732 // We are done
733 break;
734 }
735 // Relative/Absolute selector
736 targ = win ? $(targ) : $(targ, elem);
737 /* falls through */
738 case 'object':
739 if (targ.length === 0) return;
740 // DOMElement / jQuery
741 if (targ.is || targ.style) {
742 // Get the real position of the target
743 toff = (targ = $(targ)).offset();
744 }
745 }
746
747 var offset = isFunction(settings.offset) && settings.offset(elem, targ) || settings.offset;
748
749 $.each(settings.axis.split(''), function(i, axis) {
750 var Pos = axis === 'x' ? 'Left' : 'Top',
751 pos = Pos.toLowerCase(),
752 key = 'scroll' + Pos,
753 prev = $elem[key](),
754 max = $scrollTo.max(elem, axis);
755
756 if (toff) {// jQuery / DOMElement
757 attr[key] = toff[pos] + (win ? 0 : prev - $elem.offset()[pos]);
758
759 // If it's a dom element, reduce the margin
760 if (settings.margin) {
761 attr[key] -= parseInt(targ.css('margin'+Pos), 10) || 0;
762 attr[key] -= parseInt(targ.css('border'+Pos+'Width'), 10) || 0;
763 }
764
765 attr[key] += offset[pos] || 0;
766
767 if (settings.over[pos]) {
768 // Scroll to a fraction of its width/height
769 attr[key] += targ[axis === 'x'?'width':'height']() * settings.over[pos];
770 }
771 } else {
772 var val = targ[pos];
773 // Handle percentage values
774 attr[key] = val.slice && val.slice(-1) === '%' ?
775 parseFloat(val) / 100 * max
776 : val;
777 }
778
779 // Number or 'number'
780 if (settings.limit && /^\d+$/.test(attr[key])) {
781 // Check the limits
782 attr[key] = attr[key] <= 0 ? 0 : Math.min(attr[key], max);
783 }
784
785 // Don't waste time animating, if there's no need.
786 if (!i && settings.axis.length > 1) {
787 if (prev === attr[key]) {
788 // No animation needed
789 attr = {};
790 } else if (queue) {
791 // Intermediate animation
792 animate(settings.onAfterFirst);
793 // Don't animate this axis again in the next iteration.
794 attr = {};
795 }
796 }
797 });
798
799 animate(settings.onAfter);
800
801 function animate(callback) {
802 var opts = $.extend({}, settings, {
803 // The queue setting conflicts with animate()
804 // Force it to always be true
805 queue: true,
806 duration: duration,
807 complete: callback && function() {
808 callback.call(elem, targ, settings);
809 }
810 });
811 $elem.animate(attr, opts);
812 }
813 });
814 };
815
816 // Max scrolling position, works on quirks mode
817 // It only fails (not too badly) on IE, quirks mode.
818 $scrollTo.max = function(elem, axis) {
819 var Dim = axis === 'x' ? 'Width' : 'Height',
820 scroll = 'scroll'+Dim;
821
822 if (!isWin(elem))
823 return elem[scroll] - $(elem)[Dim.toLowerCase()]();
824
825 var size = 'client' + Dim,
826 doc = elem.ownerDocument || elem.document,
827 html = doc.documentElement,
828 body = doc.body;
829
830 return Math.max(html[scroll], body[scroll]) - Math.min(html[size], body[size]);
831 };
832
833 function both(val) {
834 return isFunction(val) || $.isPlainObject(val) ? val : { top:val, left:val };
835 }
836
837 // Add special hooks so that window scroll properties can be animated
838 $.Tween.propHooks.scrollLeft =
839 $.Tween.propHooks.scrollTop = {
840 get: function(t) {
841 return $(t.elem)[t.prop]();
842 },
843 set: function(t) {
844 var curr = this.get(t);
845 // If interrupt is true and user scrolled, stop animating
846 if (t.options.interrupt && t._last && t._last !== curr) {
847 return $(t.elem).stop();
848 }
849 var next = Math.round(t.now);
850 // Don't waste CPU
851 // Browsers don't render floating point scroll
852 if (curr !== next) {
853 $(t.elem)[t.prop](next);
854 t._last = this.get(t);
855 }
856 }
857 };
858
859 // AMD requirement
860 return $scrollTo;
861 });
862
863
864 /*!
865 * ================== admin/assets/js/libs/jqurey.blockUI.js ===================
866 **/
867
868 /*!
869 * jQuery blockUI plugin
870 * Version 2.70.0-2014.11.23
871 * Requires jQuery v1.7 or later
872 *
873 * Examples at: http://malsup.com/jquery/block/
874 * Copyright (c) 2007-2013 M. Alsup
875 * Dual licensed under the MIT and GPL licenses:
876 * http://www.opensource.org/licenses/mit-license.php
877 * http://www.gnu.org/licenses/gpl.html
878 *
879 * Thanks to Amir-Hossein Sobhi for some excellent contributions!
880 */
881 ;(function() {
882 /*jshint eqeqeq:false curly:false latedef:false */
883 "use strict";
884
885 function setup($) {
886 $.fn._fadeIn = $.fn.fadeIn;
887
888 var noOp = $.noop || function() {};
889
890 // this bit is to ensure we don't call setExpression when we shouldn't (with extra muscle to handle
891 // confusing userAgent strings on Vista)
892 var msie = /MSIE/.test(navigator.userAgent);
893 var ie6 = /MSIE 6.0/.test(navigator.userAgent) && ! /MSIE 8.0/.test(navigator.userAgent);
894 var mode = document.documentMode || 0;
895 var setExpr = 'function' === typeof document.createElement('div').style.setExpression ? document.createElement('div').style.setExpression : false;
896
897 // global $ methods for blocking/unblocking the entire page
898 $.blockUI = function(opts) { install(window, opts); };
899 $.unblockUI = function(opts) { remove(window, opts); };
900
901 // convenience method for quick growl-like notifications (http://www.google.com/search?q=growl)
902 $.growlUI = function(title, message, timeout, onClose) {
903 var $m = $('<div class="growlUI"></div>');
904 if (title) $m.append('<h1>'+title+'</h1>');
905 if (message) $m.append('<h2>'+message+'</h2>');
906 if (timeout === undefined) timeout = 3000;
907
908 // Added by konapun: Set timeout to 30 seconds if this growl is moused over, like normal toast notifications
909 var callBlock = function(opts) {
910 opts = opts || {};
911
912 $.blockUI({
913 message: $m,
914 fadeIn : typeof opts.fadeIn !== 'undefined' ? opts.fadeIn : 700,
915 fadeOut: typeof opts.fadeOut !== 'undefined' ? opts.fadeOut : 1000,
916 timeout: typeof opts.timeout !== 'undefined' ? opts.timeout : timeout,
917 centerY: false,
918 showOverlay: false,
919 onUnblock: onClose,
920 css: $.blockUI.defaults.growlCSS
921 });
922 };
923
924 callBlock();
925 var nonmousedOpacity = $m.css('opacity');
926 $m.on( 'mouseover', function() {
927 callBlock({
928 fadeIn: 0,
929 timeout: 30000
930 });
931
932 var displayBlock = $('.blockMsg');
933 displayBlock.stop(); // cancel fadeout if it has started
934 displayBlock.fadeTo(300, 1); // make it easier to read the message by removing transparency
935 }).on( 'mouseout', function() {
936 $('.blockMsg').fadeOut(1000);
937 });
938 // End konapun additions
939 };
940
941 // plugin method for blocking element content
942 $.fn.block = function(opts) {
943 if ( this[0] === window ) {
944 $.blockUI( opts );
945 return this;
946 }
947 var fullOpts = $.extend({}, $.blockUI.defaults, opts || {});
948 this.each(function() {
949 var $el = $(this);
950 if (fullOpts.ignoreIfBlocked && $el.data('blockUI.isBlocked'))
951 return;
952 $el.unblock({ fadeOut: 0 });
953 });
954
955 return this.each(function() {
956 if ($.css(this,'position') == 'static') {
957 this.style.position = 'relative';
958 $(this).data('blockUI.static', true);
959 }
960 this.style.zoom = 1; // force 'hasLayout' in ie
961 install(this, opts);
962 });
963 };
964
965 // plugin method for unblocking element content
966 $.fn.unblock = function(opts) {
967 if ( this[0] === window ) {
968 $.unblockUI( opts );
969 return this;
970 }
971 return this.each(function() {
972 remove(this, opts);
973 });
974 };
975
976 $.blockUI.version = 2.70; // 2nd generation blocking at no extra cost!
977
978 // override these in your code to change the default behavior and style
979 $.blockUI.defaults = {
980 // message displayed when blocking (use null for no message)
981 message: '<h1>Please wait...</h1>',
982
983 title: null, // title string; only used when theme == true
984 draggable: true, // only used when theme == true (requires jquery-ui.js to be loaded)
985
986 theme: false, // set to true to use with jQuery UI themes
987
988 // styles for the message when blocking; if you wish to disable
989 // these and use an external stylesheet then do this in your code:
990 // $.blockUI.defaults.css = {};
991 css: {
992 padding: 0,
993 margin: 0,
994 width: '30%',
995 top: '40%',
996 left: '35%',
997 textAlign: 'center',
998 color: '#000',
999 border: '3px solid #aaa',
1000 backgroundColor:'#fff',
1001 cursor: 'wait'
1002 },
1003
1004 // minimal style set used when themes are used
1005 themedCSS: {
1006 width: '30%',
1007 top: '40%',
1008 left: '35%'
1009 },
1010
1011 // styles for the overlay
1012 overlayCSS: {
1013 backgroundColor: '#000',
1014 opacity: 0.6,
1015 cursor: 'wait'
1016 },
1017
1018 // style to replace wait cursor before unblocking to correct issue
1019 // of lingering wait cursor
1020 cursorReset: 'default',
1021
1022 // styles applied when using $.growlUI
1023 growlCSS: {
1024 width: '350px',
1025 top: '10px',
1026 left: '',
1027 right: '10px',
1028 border: 'none',
1029 padding: '5px',
1030 opacity: 0.6,
1031 cursor: 'default',
1032 color: '#fff',
1033 backgroundColor: '#000',
1034 '-webkit-border-radius':'10px',
1035 '-moz-border-radius': '10px',
1036 'border-radius': '10px'
1037 },
1038
1039 // IE issues: 'about:blank' fails on HTTPS and javascript:false is s-l-o-w
1040 // (hat tip to Jorge H. N. de Vasconcelos)
1041 /*jshint scripturl:true */
1042 iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank',
1043
1044 // force usage of iframe in non-IE browsers (handy for blocking applets)
1045 forceIframe: false,
1046
1047 // z-index for the blocking overlay
1048 baseZ: 1000,
1049
1050 // set these to true to have the message automatically centered
1051 centerX: true, // <-- only effects element blocking (page block controlled via css above)
1052 centerY: true,
1053
1054 // allow body element to be stetched in ie6; this makes blocking look better
1055 // on "short" pages. disable if you wish to prevent changes to the body height
1056 allowBodyStretch: true,
1057
1058 // enable if you want key and mouse events to be disabled for content that is blocked
1059 bindEvents: true,
1060
1061 // be default blockUI will supress tab navigation from leaving blocking content
1062 // (if bindEvents is true)
1063 constrainTabKey: true,
1064
1065 // fadeIn time in millis; set to 0 to disable fadeIn on block
1066 fadeIn: 200,
1067
1068 // fadeOut time in millis; set to 0 to disable fadeOut on unblock
1069 fadeOut: 400,
1070
1071 // time in millis to wait before auto-unblocking; set to 0 to disable auto-unblock
1072 timeout: 0,
1073
1074 // disable if you don't want to show the overlay
1075 showOverlay: true,
1076
1077 // if true, focus will be placed in the first available input field when
1078 // page blocking
1079 focusInput: true,
1080
1081 // elements that can receive focus
1082 focusableElements: ':input:enabled:visible',
1083
1084 // suppresses the use of overlay styles on FF/Linux (due to performance issues with opacity)
1085 // no longer needed in 2012
1086 // applyPlatformOpacityRules: true,
1087
1088 // callback method invoked when fadeIn has completed and blocking message is visible
1089 onBlock: null,
1090
1091 // callback method invoked when unblocking has completed; the callback is
1092 // passed the element that has been unblocked (which is the window object for page
1093 // blocks) and the options that were passed to the unblock call:
1094 // onUnblock(element, options)
1095 onUnblock: null,
1096
1097 // callback method invoked when the overlay area is clicked.
1098 // setting this will turn the cursor to a pointer, otherwise cursor defined in overlayCss will be used.
1099 onOverlayClick: null,
1100
1101 // don't ask; if you really must know: http://groups.google.com/group/jquery-en/browse_thread/thread/36640a8730503595/2f6a79a77a78e493#2f6a79a77a78e493
1102 quirksmodeOffsetHack: 4,
1103
1104 // class name of the message block
1105 blockMsgClass: 'blockMsg',
1106
1107 // if it is already blocked, then ignore it (don't unblock and reblock)
1108 ignoreIfBlocked: false
1109 };
1110
1111 // private data and functions follow...
1112
1113 var pageBlock = null;
1114 var pageBlockEls = [];
1115
1116 function install(el, opts) {
1117 var css, themedCSS;
1118 var full = (el == window);
1119 var msg = (opts && opts.message !== undefined ? opts.message : undefined);
1120 opts = $.extend({}, $.blockUI.defaults, opts || {});
1121
1122 if (opts.ignoreIfBlocked && $(el).data('blockUI.isBlocked'))
1123 return;
1124
1125 opts.overlayCSS = $.extend({}, $.blockUI.defaults.overlayCSS, opts.overlayCSS || {});
1126 css = $.extend({}, $.blockUI.defaults.css, opts.css || {});
1127 if (opts.onOverlayClick)
1128 opts.overlayCSS.cursor = 'pointer';
1129
1130 themedCSS = $.extend({}, $.blockUI.defaults.themedCSS, opts.themedCSS || {});
1131 msg = msg === undefined ? opts.message : msg;
1132
1133 // remove the current block (if there is one)
1134 if (full && pageBlock)
1135 remove(window, {fadeOut:0});
1136
1137 // if an existing element is being used as the blocking content then we capture
1138 // its current place in the DOM (and current display style) so we can restore
1139 // it when we unblock
1140 if (msg && typeof msg != 'string' && (msg.parentNode || msg.jquery)) {
1141 var node = msg.jquery ? msg[0] : msg;
1142 var data = {};
1143 $(el).data('blockUI.history', data);
1144 data.el = node;
1145 data.parent = node.parentNode;
1146 data.display = node.style.display;
1147 data.position = node.style.position;
1148 if (data.parent)
1149 data.parent.removeChild(node);
1150 }
1151
1152 $(el).data('blockUI.onUnblock', opts.onUnblock);
1153 var z = opts.baseZ;
1154
1155 // blockUI uses 3 layers for blocking, for simplicity they are all used on every platform;
1156 // layer1 is the iframe layer which is used to supress bleed through of underlying content
1157 // layer2 is the overlay layer which has opacity and a wait cursor (by default)
1158 // layer3 is the message content that is displayed while blocking
1159 var lyr1, lyr2, lyr3, s;
1160 if (msie || opts.forceIframe)
1161 lyr1 = $('<iframe class="blockUI" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;position:absolute;width:100%;height:100%;top:0;left:0" src="'+opts.iframeSrc+'"></iframe>');
1162 else
1163 lyr1 = $('<div class="blockUI" style="display:none"></div>');
1164
1165 if (opts.theme)
1166 lyr2 = $('<div class="blockUI blockOverlay ui-widget-overlay" style="z-index:'+ (z++) +';display:none"></div>');
1167 else
1168 lyr2 = $('<div class="blockUI blockOverlay" style="z-index:'+ (z++) +';display:none;border:none;margin:0;padding:0;width:100%;height:100%;top:0;left:0"></div>');
1169
1170 if (opts.theme && full) {
1171 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:fixed">';
1172 if ( opts.title ) {
1173 s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
1174 }
1175 s += '<div class="ui-widget-content ui-dialog-content"></div>';
1176 s += '</div>';
1177 }
1178 else if (opts.theme) {
1179 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement ui-dialog ui-widget ui-corner-all" style="z-index:'+(z+10)+';display:none;position:absolute">';
1180 if ( opts.title ) {
1181 s += '<div class="ui-widget-header ui-dialog-titlebar ui-corner-all blockTitle">'+(opts.title || '&nbsp;')+'</div>';
1182 }
1183 s += '<div class="ui-widget-content ui-dialog-content"></div>';
1184 s += '</div>';
1185 }
1186 else if (full) {
1187 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockPage" style="z-index:'+(z+10)+';display:none;position:fixed"></div>';
1188 }
1189 else {
1190 s = '<div class="blockUI ' + opts.blockMsgClass + ' blockElement" style="z-index:'+(z+10)+';display:none;position:absolute"></div>';
1191 }
1192 lyr3 = $(s);
1193
1194 // if we have a message, style it
1195 if (msg) {
1196 if (opts.theme) {
1197 lyr3.css(themedCSS);
1198 lyr3.addClass('ui-widget-content');
1199 }
1200 else
1201 lyr3.css(css);
1202 }
1203
1204 // style the overlay
1205 if (!opts.theme /*&& (!opts.applyPlatformOpacityRules)*/)
1206 lyr2.css(opts.overlayCSS);
1207 lyr2.css('position', full ? 'fixed' : 'absolute');
1208
1209 // make iframe layer transparent in IE
1210 if (msie || opts.forceIframe)
1211 lyr1.css('opacity',0.0);
1212
1213 //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el);
1214 var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el);
1215 $.each(layers, function() {
1216 this.appendTo($par);
1217 });
1218
1219 if (opts.theme && opts.draggable && $.fn.draggable) {
1220 lyr3.draggable({
1221 handle: '.ui-dialog-titlebar',
1222 cancel: 'li'
1223 });
1224 }
1225
1226 // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling)
1227 var expr = setExpr && (!$.support.boxModel || $('object,embed', full ? null : el).length > 0);
1228 if (ie6 || expr) {
1229 // give body 100% height
1230 if (full && opts.allowBodyStretch && $.support.boxModel)
1231 $('html,body').css('height','100%');
1232
1233 // fix ie6 issue when blocked element has a border width
1234 if ((ie6 || !$.support.boxModel) && !full) {
1235 var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth');
1236 var fixT = t ? '(0 - '+t+')' : 0;
1237 var fixL = l ? '(0 - '+l+')' : 0;
1238 }
1239
1240 // simulate fixed position
1241 $.each(layers, function(i,o) {
1242 var s = o[0].style;
1243 s.position = 'absolute';
1244 if (i < 2) {
1245 if (full)
1246 s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.support.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"');
1247 else
1248 s.setExpression('height','this.parentNode.offsetHeight + "px"');
1249 if (full)
1250 s.setExpression('width','jQuery.support.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"');
1251 else
1252 s.setExpression('width','this.parentNode.offsetWidth + "px"');
1253 if (fixL) s.setExpression('left', fixL);
1254 if (fixT) s.setExpression('top', fixT);
1255 }
1256 else if (opts.centerY) {
1257 if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"');
1258 s.marginTop = 0;
1259 }
1260 else if (!opts.centerY && full) {
1261 var top = (opts.css && opts.css.top) ? parseInt(opts.css.top, 10) : 0;
1262 var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"';
1263 s.setExpression('top',expression);
1264 }
1265 });
1266 }
1267
1268 // show the message
1269 if (msg) {
1270 if (opts.theme)
1271 lyr3.find('.ui-widget-content').append(msg);
1272 else
1273 lyr3.append(msg);
1274 if (msg.jquery || msg.nodeType)
1275 $(msg).show();
1276 }
1277
1278 if ((msie || opts.forceIframe) && opts.showOverlay)
1279 lyr1.show(); // opacity is zero
1280 if (opts.fadeIn) {
1281 var cb = opts.onBlock ? opts.onBlock : noOp;
1282 var cb1 = (opts.showOverlay && !msg) ? cb : noOp;
1283 var cb2 = msg ? cb : noOp;
1284 if (opts.showOverlay)
1285 lyr2._fadeIn(opts.fadeIn, cb1);
1286 if (msg)
1287 lyr3._fadeIn(opts.fadeIn, cb2);
1288 }
1289 else {
1290 if (opts.showOverlay)
1291 lyr2.show();
1292 if (msg)
1293 lyr3.show();
1294 if (opts.onBlock)
1295 opts.onBlock.bind(lyr3)();
1296 }
1297
1298 // bind key and mouse events
1299 bind(1, el, opts);
1300
1301 if (full) {
1302 pageBlock = lyr3[0];
1303 pageBlockEls = $(opts.focusableElements,pageBlock);
1304 if (opts.focusInput)
1305 setTimeout(focus, 20);
1306 }
1307 else
1308 center(lyr3[0], opts.centerX, opts.centerY);
1309
1310 if (opts.timeout) {
1311 // auto-unblock
1312 var to = setTimeout(function() {
1313 if (full)
1314 $.unblockUI(opts);
1315 else
1316 $(el).unblock(opts);
1317 }, opts.timeout);
1318 $(el).data('blockUI.timeout', to);
1319 }
1320 }
1321
1322 // remove the block
1323 function remove(el, opts) {
1324 var count;
1325 var full = (el == window);
1326 var $el = $(el);
1327 var data = $el.data('blockUI.history');
1328 var to = $el.data('blockUI.timeout');
1329 if (to) {
1330 clearTimeout(to);
1331 $el.removeData('blockUI.timeout');
1332 }
1333 opts = $.extend({}, $.blockUI.defaults, opts || {});
1334 bind(0, el, opts); // unbind events
1335
1336 if (opts.onUnblock === null) {
1337 opts.onUnblock = $el.data('blockUI.onUnblock');
1338 $el.removeData('blockUI.onUnblock');
1339 }
1340
1341 var els;
1342 if (full) // crazy selector to handle odd field errors in ie6/7
1343 els = $(document.body).children().filter('.blockUI').add('body > .blockUI');
1344 else
1345 els = $el.find('>.blockUI');
1346
1347 // fix cursor issue
1348 if ( opts.cursorReset ) {
1349 if ( els.length > 1 )
1350 els[1].style.cursor = opts.cursorReset;
1351 if ( els.length > 2 )
1352 els[2].style.cursor = opts.cursorReset;
1353 }
1354
1355 if (full)
1356 pageBlock = pageBlockEls = null;
1357
1358 if (opts.fadeOut) {
1359 count = els.length;
1360 els.stop().fadeOut(opts.fadeOut, function() {
1361 if ( --count === 0)
1362 reset(els,data,opts,el);
1363 });
1364 }
1365 else
1366 reset(els, data, opts, el);
1367 }
1368
1369 // move blocking element back into the DOM where it started
1370 function reset(els,data,opts,el) {
1371 var $el = $(el);
1372 if ( $el.data('blockUI.isBlocked') )
1373 return;
1374
1375 els.each(function(i,o) {
1376 // remove via DOM calls so we don't lose event handlers
1377 if (this.parentNode)
1378 this.parentNode.removeChild(this);
1379 });
1380
1381 if (data && data.el) {
1382 data.el.style.display = data.display;
1383 data.el.style.position = data.position;
1384 data.el.style.cursor = 'default'; // #59
1385 if (data.parent)
1386 data.parent.appendChild(data.el);
1387 $el.removeData('blockUI.history');
1388 }
1389
1390 if ($el.data('blockUI.static')) {
1391 $el.css('position', 'static'); // #22
1392 }
1393
1394 if (typeof opts.onUnblock == 'function')
1395 opts.onUnblock(el,opts);
1396
1397 // fix issue in Safari 6 where block artifacts remain until reflow
1398 var body = $(document.body), w = body.width(), cssW = body[0].style.width;
1399 body.width(w-1).width(w);
1400 body[0].style.width = cssW;
1401 }
1402
1403 // bind/unbind the handler
1404 function bind(b, el, opts) {
1405 var full = el == window, $el = $(el);
1406
1407 // don't bother unbinding if there is nothing to unbind
1408 if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked')))
1409 return;
1410
1411 $el.data('blockUI.isBlocked', b);
1412
1413 // don't bind events when overlay is not in use or if bindEvents is false
1414 if (!full || !opts.bindEvents || (b && !opts.showOverlay))
1415 return;
1416
1417 // bind anchors and inputs for mouse and key events
1418 var events = 'mousedown mouseup keydown keypress keyup touchstart touchend touchmove';
1419 if (b)
1420 $(document).on(events, opts, handler);
1421 else
1422 $(document).off(events, handler);
1423
1424 // former impl...
1425 // var $e = $('a,:input');
1426 // b ? $e.bind(events, opts, handler) : $e.unbind(events, handler);
1427 }
1428
1429 // event handler to suppress keyboard/mouse events when blocking
1430 function handler(e) {
1431 // allow tab navigation (conditionally)
1432 if (e.type === 'keydown' && e.keyCode && e.keyCode == 9) {
1433 if (pageBlock && e.data.constrainTabKey) {
1434 var els = pageBlockEls;
1435 var fwd = !e.shiftKey && e.target === els[els.length-1];
1436 var back = e.shiftKey && e.target === els[0];
1437 if (fwd || back) {
1438 setTimeout(function(){focus(back);},10);
1439 return false;
1440 }
1441 }
1442 }
1443 var opts = e.data;
1444 var target = $(e.target);
1445 if (target.hasClass('blockOverlay') && opts.onOverlayClick)
1446 opts.onOverlayClick(e);
1447
1448 // allow events within the message content
1449 if (target.parents('div.' + opts.blockMsgClass).length > 0)
1450 return true;
1451
1452 // allow events for content that is not being blocked
1453 return target.parents().children().filter('div.blockUI').length === 0;
1454 }
1455
1456 function focus(back) {
1457 if (!pageBlockEls)
1458 return;
1459 var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0];
1460 if (e)
1461 e.trigger( 'focus' );
1462 }
1463
1464 function center(el, x, y) {
1465 var p = el.parentNode, s = el.style;
1466 var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth');
1467 var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth');
1468 if (x) s.left = l > 0 ? (l+'px') : '0';
1469 if (y) s.top = t > 0 ? (t+'px') : '0';
1470 }
1471
1472 function sz(el, p) {
1473 return parseInt($.css(el,p),10)||0;
1474 }
1475
1476 }
1477
1478
1479 /*global define:true */
1480 if (typeof define === 'function' && define.amd && define.amd.jQuery) {
1481 define(['jquery'], setup);
1482 } else {
1483 setup(jQuery);
1484 }
1485
1486 })();
1487
1488
1489 /*!
1490 * ================== admin/assets/js/libs/wizard.js ===================
1491 **/
1492
1493 (function($, window, document, undefined) {
1494 "use strict";
1495
1496 // Create the defaults once
1497 var pluginName = "AuxWizard",
1498 defaults = {
1499 modalClass: ".aux-open-modal",
1500 loading: aux_setup_params.svg_loader
1501 };
1502 // The actual plugin constructor
1503 function Plugin(element, options) {
1504 this.element = element;
1505 this.$element = $(element);
1506 this.settings = $.extend({}, defaults, options);
1507 this._defaults = defaults;
1508 this._name = pluginName;
1509
1510 this.$modalElement = null;
1511 this._modalButton = null;
1512 this._ajaxData = null;
1513 this._ajaxUrl = aux_setup_params.ajaxurl;
1514 this._elStorage = {};
1515 this._importData = {};
1516
1517 // Isotope Elements
1518 this.$isotopeTemplate = null;
1519 this.$isotopeList = null;
1520 this.$isotopePlugins = null;
1521
1522 this.init();
1523 }
1524
1525 // Avoid Plugin.prototype conflicts
1526 $.extend(Plugin.prototype, {
1527 init: function() {
1528 // Create isotope elements
1529 this._callIsotope();
1530 // Isotope change group
1531 $(".aux-isotope-group").on("change", this._changeGroup.bind(this));
1532
1533 // General Events
1534 this._openModal();
1535 this._manipulations();
1536
1537 this._lazyloadConfig();
1538
1539 // Steps Manager Event
1540 $(document).on(
1541 "click",
1542 ".aux-next-step",
1543 this._stepManager.bind(this)
1544 );
1545
1546 // Install & Uninstall Demo Events
1547 $(document).on(
1548 "click",
1549 ".aux-install-demo",
1550 this._demoManager.bind(this)
1551 );
1552 $(document).on(
1553 "click",
1554 ".aux-uninstall-demo",
1555 this._uninstallDemo.bind(this)
1556 );
1557
1558 // Template Manager Event
1559 $(document).on(
1560 "click",
1561 ".aux-copy-template",
1562 this._tempManager.bind(this)
1563 );
1564
1565 // Install Plugins Event
1566 $(document).on(
1567 "click",
1568 ".install-plugins",
1569 this._pluginManager.bind(this)
1570 );
1571
1572 // Install Plugins Event
1573 $(document).on(
1574 "click",
1575 ".aux-install-updates",
1576 this._updateManager.bind(this)
1577 );
1578
1579 // Activate license
1580 $(document).on(
1581 "submit",
1582 ".auxin-check-purchase",
1583 this._activateLicense.bind(this)
1584 );
1585
1586 // Refresh Page
1587 $(document).on(
1588 "click",
1589 ".aux-refresh-page",
1590 this._refresh.bind(this)
1591 );
1592
1593 // Check envato elements email - get license code
1594 $(document).on(
1595 "click",
1596 ".aux-verify-elements-email",
1597 this._verifyEnvatoElementsEmail.bind(this)
1598 );
1599
1600 // Check envato elements token
1601 $(document).on(
1602 "click",
1603 ".aux-verify-elements-token",
1604 this._verifyEnvatoElementsToken.bind(this)
1605 );
1606
1607 },
1608
1609 /**
1610 * global AJAX callback
1611 */
1612 _globalAJAX: function(callback) {
1613 // Do Ajax & update default value
1614 $.ajax({
1615 url: this._ajaxUrl,
1616 type: "post",
1617 data: this._ajaxData
1618 }).done(callback);
1619 },
1620
1621 /**
1622 * refresh page
1623 */
1624
1625 _refresh: function(e) {
1626 // check preventDefault existence
1627 if (typeof e.preventDefault !== "undefined") {
1628 e.preventDefault();
1629 }
1630 location.reload();
1631 },
1632
1633 /**
1634 * Activate user license
1635 */
1636 _activateLicense: function(e) {
1637 // Check currentTarget existence
1638 if (!e.currentTarget) {
1639 return;
1640 }
1641 // check preventDefault existence
1642 if (typeof e.preventDefault !== "undefined") {
1643 e.preventDefault();
1644 }
1645
1646 // Set variables
1647 var $formElemment = $(e.currentTarget),
1648 $buttonElement = $formElemment.find(".aux-activate-license"),
1649 $noticeElement = $formElemment.find(".aux-notice"),
1650 statusClass = null,
1651 getFormInputs = {};
1652 $.each($formElemment.serializeArray(), function(i, field) {
1653 getFormInputs[field.name] = field.value;
1654 });
1655 // If the notice container is not exist, we've to add it.
1656 if (!$noticeElement.length) {
1657 $noticeElement = $("<div>", { class: "aux-notice" }).appendTo(
1658 $formElemment
1659 );
1660 }
1661 this._ajaxData = {
1662 action: getFormInputs.action,
1663 usermail: getFormInputs.usermail,
1664 purchase: getFormInputs.purchase,
1665 security: getFormInputs.security
1666 };
1667
1668 // Manipulation
1669 $buttonElement.addClass("aux-button-loading");
1670 $noticeElement.removeClass("success warning").hide();
1671
1672 this._controlActions("off");
1673 // Call AJAX with current _ajaxData value
1674 this._globalAJAX(
1675 function(response) {
1676 // Check response status
1677 if (response !== null && response.success) {
1678 // Then do these actions
1679 $buttonElement.addClass(
1680 "aux-button-success aux-refresh-page"
1681 );
1682 $noticeElement.addClass("success");
1683 statusClass = "aux-button-success aux-button-loading";
1684 $(this._modalButton)
1685 .closest(".aux-purchase-activation-notice")
1686 .fadeOut();
1687 } else {
1688 // Then do these actions
1689 $buttonElement.addClass("aux-button-error");
1690 $noticeElement.addClass("warning");
1691 statusClass = "aux-button-error aux-button-loading";
1692 }
1693 // Remove form progress class
1694 $formElemment.removeClass("aux-form-in-progress");
1695 // Actions
1696 setTimeout(function() {
1697 $buttonElement.removeClass(statusClass);
1698 $buttonElement
1699 .find("span")
1700 .text(response.data.buttonText);
1701 }, 1000);
1702 $noticeElement.show().html(response.data.message);
1703 this._controlActions("on");
1704 }.bind(this)
1705 );
1706 },
1707
1708 /**
1709 * open modal box (Based on featherlight plugin)
1710 */
1711 _openModal: function() {
1712 var self = this;
1713 // Display modal demo on click button
1714 var $advancedAjaxModal = $(self.settings.modalClass).featherlight({
1715 targetAttr: "href",
1716 closeOnEsc: false,
1717 closeOnClick: false,
1718 contentFilters: ["ajax"],
1719 loading: this.settings.loading,
1720 otherClose: ".aux-pp-close",
1721 afterOpen: function(e) {
1722 // init PerfectScrollbar
1723 if ($(".featherlight .aux-wizard-plugins").length) {
1724 var PScrollbar = new PerfectScrollbar(
1725 ".featherlight .aux-wizard-plugins"
1726 );
1727 }
1728 // Set golbal modal button
1729 self._modalButton = e.currentTarget;
1730 self.$modalElement = this.$instance;
1731 // Run template manager function
1732 if ($(self._modalButton).hasClass("aux-has-next-action")) {
1733 self._tempManager({ currentTarget: e.currentTarget });
1734 }
1735 }
1736 });
1737 var $simpleAjaxModal = $(".aux-ajax-open-modal").featherlight({
1738 targetAttr: "href",
1739 contentFilters: ["ajax"],
1740 otherClose: ".aux-pp-close",
1741 closeOnClick: false,
1742 loading: this.settings.loading,
1743 afterOpen: function(e) {
1744 // Set golbal modal button
1745 self._modalButton = e.currentTarget;
1746 self.$modalElement = this.$instance;
1747 }
1748 });
1749 // Auto open modal
1750 if ($simpleAjaxModal.data("auto-open") === 1) {
1751 $simpleAjaxModal.click();
1752 }
1753 },
1754
1755 /**
1756 * a callback to change the group of AuxIsotope (Used in the Template Kits Switcher to select modes between 'page' & 'section')
1757 */
1758 _changeGroup: function(e) {
1759 // Check currentTarget existence
1760 if (!e.currentTarget) {
1761 return;
1762 }
1763 // Set variables
1764 var groupName = e.currentTarget.checked ? "section" : "page";
1765 this._ajaxData = {
1766 action: "aux_isotope_group",
1767 group: groupName,
1768 nonce: $(e.currentTarget).data("nonce"),
1769 key: "templates_kit"
1770 };
1771 // Call AJAX with current _ajaxData value
1772 this._globalAJAX(
1773 function(response) {
1774 if (response !== null && response.success) {
1775 this.$isotopeTemplate.AuxIsotope(
1776 "changeGroup",
1777 groupName
1778 );
1779 } else {
1780 console.log(response);
1781 }
1782 }.bind(this)
1783 );
1784 },
1785
1786 /* ------------------------------------------------------------------------------ */
1787 // Update Manager
1788
1789 /**
1790 * Update manager main function
1791 */
1792 _updateManager: function(e) {
1793 // Check currentTarget existence
1794 if (!e.currentTarget) {
1795 return;
1796 }
1797 // check preventDefault existence
1798 if (typeof e.preventDefault !== "undefined") {
1799 e.preventDefault();
1800 }
1801
1802 var $buttonElement = $(e.currentTarget);
1803 this.$buttonParentEl = $buttonElement.closest(".aux-updates-step");
1804 this.$updatesListEl = this.$buttonParentEl.find(".aux-update-list");
1805 this.$updatesList = this.$updatesListEl.find(".aux-item");
1806 this._itemsCompleted = 0;
1807 this._attemptsBuffer = 0;
1808 this._currentItem = null;
1809 this._itemType = null;
1810 this._dataNonce = $buttonElement.data("nonce");
1811 this._buttonTarget = e.currentTarget;
1812 this.$currentNode = null;
1813
1814 // Manipulation
1815 this.$updatesListEl.addClass("installing");
1816 $buttonElement
1817 .text(aux_setup_params.btnworks_text)
1818 .addClass("disabled");
1819
1820 this._controlActions("off");
1821 this._processUpdates();
1822 },
1823
1824 /**
1825 * Process update elements
1826 */
1827 _processUpdates: function() {
1828 var self = this,
1829 doNext = false;
1830
1831 if (this.$currentNode) {
1832 if (!this.$currentNode.data("done_item")) {
1833 this._itemsCompleted++;
1834 this.$currentNode.data("done_item", 1);
1835 }
1836 }
1837
1838 this.$updatesList.each(function() {
1839 if (self._currentItem == null || doNext) {
1840 $(this).addClass("work-in-progress");
1841 self._currentItem = $(this).data("key");
1842 self._itemType = $(this).data("type");
1843 self.$currentNode = $(this);
1844 self._installUpdate();
1845 doNext = false;
1846 } else if ($(this).data("key") === self._currentItem) {
1847 $(this).removeClass("work-in-progress");
1848 doNext = true;
1849 }
1850 });
1851
1852 // If all plugins finished, then
1853 if (this._itemsCompleted >= this.$updatesList.length) {
1854 // Activate control actions
1855 this._controlActions("on");
1856 // Remove installing class
1857 this.$updatesListEl.removeClass("installing");
1858 // Remove disable class from button
1859 $(this._buttonTarget)
1860 .text(aux_setup_params.activate_text)
1861 .removeClass("disabled");
1862 if (this.$updatesList.not(".aux-success").length == 0) {
1863 // Refresh current page when all the plugins has been successfully updated.
1864 this._refresh({ currentTarget: this._buttonTarget });
1865 }
1866 }
1867 },
1868
1869 /**
1870 * Process update by type & key
1871 */
1872 _installUpdate: function() {
1873 if (this._currentItem) {
1874 this._ajaxData = {
1875 action: "auxin_start_upgrading",
1876 key: this._currentItem,
1877 type: this._itemType,
1878 nonce: this._dataNonce
1879 };
1880 this._globalAJAX(
1881 function(response) {
1882 this._updateActions(response);
1883 }.bind(this)
1884 );
1885 }
1886 },
1887
1888 /**
1889 * Item update events
1890 */
1891 _updateActions: function(response) {
1892 // Check response type
1893 if (typeof response === "object" && response.success) {
1894 // Update item status message
1895 this.$currentNode
1896 .find(".column-status span")
1897 .text(response.data.successMessage);
1898 // otherwise it's just installed and we should make a notify to user
1899 this.$currentNode
1900 .addClass("aux-success")
1901 .find(".aux-check-column")
1902 .remove();
1903 this.$currentNode
1904 .find(".check-column")
1905 .append(
1906 "<i class='aux-success-icon auxicon-check-mark-circle-outline'></i>"
1907 );
1908 } else {
1909 // error & try again with next item
1910 this.$currentNode
1911 .addClass("aux-error")
1912 .find(".column-status span")
1913 .text(response.data.errorMessage);
1914 }
1915 // Then jump to next item
1916 this._processUpdates();
1917 },
1918
1919 /* ------------------------------------------------------------------------------ */
1920 // Step Manager
1921
1922 /**
1923 * the step manager functionality (Used in modal box)
1924 */
1925 _stepManager: function(e) {
1926 // Check currentTarget existence
1927 if (!e.currentTarget) {
1928 return;
1929 }
1930 // check preventDefault existence
1931 if (typeof e.preventDefault !== "undefined") {
1932 e.preventDefault();
1933 }
1934 // Set variables
1935 var $buttonElement = $(e.currentTarget),
1936 $modalSectionElement = this.$modalElement.find(
1937 ".aux-steps-col"
1938 );
1939 this._ajaxData = {
1940 action: "aux_step_manager",
1941 next_step: $buttonElement.data("next-step"),
1942 nonce: $buttonElement.data("step-nonce"),
1943 args: $buttonElement.data("args"),
1944 next_action: $buttonElement.data("next-action")
1945 };
1946 // Manipulation
1947 $modalSectionElement.addClass("aux-step-in-progress");
1948 this._controlActions("off");
1949 // Call AJAX with current _ajaxData value
1950 this._globalAJAX(
1951 function(response) {
1952 if (response !== null && response.success) {
1953 $modalSectionElement
1954 .removeClass("aux-step-in-progress")
1955 .html(response.data.markup);
1956 // Run hidden action
1957 if (this._ajaxData.next_action) {
1958 this._tempManager({
1959 currentTarget: this._modalButton
1960 });
1961 }
1962 } else {
1963 console.log(response);
1964 }
1965 this._controlActions("on");
1966 }.bind(this)
1967 );
1968 },
1969
1970 /* ------------------------------------------------------------------------------ */
1971 // template Manager
1972
1973 /**
1974 * Template kits manager functionality
1975 */
1976 _tempManager: function(e) {
1977 // Check currentTarget existence
1978 if (!e.currentTarget) {
1979 return;
1980 }
1981 // check preventDefault existence
1982 if (typeof e.preventDefault !== "undefined") {
1983 e.preventDefault();
1984 }
1985 // Set variables
1986 var $buttonElement = $(e.currentTarget),
1987 $modalSectionElement =
1988 this.$modalElement != null
1989 ? this.$modalElement.find(".aux-steps-col")
1990 : null;
1991 this._ajaxData = {
1992 action: "auxin_templates_data",
1993 verify: $buttonElement.data("nonce"),
1994 ID: $buttonElement.data("template-id"),
1995 type: $buttonElement.data("template-type"),
1996 tmpl: $buttonElement.data("template-page-tmpl"),
1997 status: $buttonElement.data("status-type"),
1998 title: $buttonElement.data("template-title")
1999 };
2000 // Manipulation
2001 if (this._ajaxData.status === "copy") {
2002 $buttonElement.addClass("aux-button-loading");
2003 }
2004 this._controlActions("off");
2005 // Call AJAX with current _ajaxData value
2006 this._globalAJAX(
2007 function(response) {
2008 if (response !== null && response.success) {
2009 if (response.data.status === "copy") {
2010 // Put our data in elementor localStorage
2011 this._updateElementorLocalStorage(
2012 this._ajaxData.type,
2013 response.data.result.content
2014 );
2015 // Then do these actions
2016 $buttonElement.addClass("aux-button-success");
2017 setTimeout(function() {
2018 $buttonElement.removeClass(
2019 "aux-button-success aux-button-loading"
2020 );
2021 }, 1000);
2022 } else {
2023 // Change button type to copy
2024 $buttonElement
2025 .data("status-type", "copy")
2026 .prop("data-status-type", "copy")
2027 .addClass("aux-copy-template aux-orange")
2028 .removeClass(
2029 "aux-import-template aux-has-next-action aux-green2"
2030 )
2031 .removeAttr("href");
2032 // Change button text to copy
2033 $buttonElement
2034 .find("span")
2035 .text(response.data.label);
2036 // Display the more button
2037 $buttonElement
2038 .next(".aux-more-button")
2039 .removeClass("hide");
2040 // Update modal section data with success template
2041 $modalSectionElement.html(response.data.result);
2042 }
2043 } else {
2044 // Update modal section data with error template
2045 $modalSectionElement.html(response.data);
2046 }
2047 this._controlActions("on");
2048 }.bind(this)
2049 );
2050 },
2051
2052 /**
2053 * Update elementor localStorage data with new custom elements
2054 */
2055 _updateElementorLocalStorage: function(elementsType, elements) {
2056 this._elStorage["transfer"] = {
2057 type: "copy",
2058 elementsType: elementsType,
2059 elements: elements
2060 };
2061 localStorage.setItem("elementor", JSON.stringify(this._elStorage));
2062 },
2063
2064 /* ------------------------------------------------------------------------------ */
2065 // Demo Manager
2066
2067 /**
2068 * Demo manager main function
2069 */
2070 _demoManager: function(e) {
2071 // Check currentTarget existence
2072 if (!e.currentTarget) {
2073 return;
2074 }
2075 // check preventDefault existence
2076 if (typeof e.preventDefault !== "undefined") {
2077 e.preventDefault();
2078 }
2079 // Set variable
2080 var $buttonElement = $(e.currentTarget),
2081 $buttonParentEl = $buttonElement.closest(
2082 ".aux-setup-demo-actions"
2083 ),
2084 $buttonWrapperEl = $buttonParentEl.find(".aux-return-back"),
2085 $progressBarEl = $buttonParentEl.find(".aux-progress"),
2086 $optionsElement = this.$modalElement.find(".aux-install-demos"),
2087 $demoProgress = this.$modalElement.find(
2088 ".aux-install-demos-waiting"
2089 );
2090 this._ajaxData = {
2091 action: "auxin_demo_data",
2092 ID: $buttonElement.data("import-id"),
2093 verify: $buttonElement.data("nonce"),
2094 options: $optionsElement
2095 .find(".aux-import-parts")
2096 .serializeArray()
2097 };
2098 this.$progressBarLabelEl = $progressBarEl.find(
2099 ".aux-progress-label"
2100 );
2101
2102 // Actions
2103 $optionsElement.addClass("hide");
2104 $demoProgress.removeClass("hide");
2105 $buttonWrapperEl.addClass("hide");
2106 $progressBarEl.removeClass("hide");
2107 this.$progressBarLabelEl.text("Getting Demo Data ...");
2108
2109 this._controlActions("off");
2110 this._globalAJAX(
2111 function(response) {
2112 if (response !== null && response.success) {
2113 this._demoImport({
2114 target: e.currentTarget,
2115 step: "download",
2116 message: "Downloading Media ...",
2117 index: null
2118 });
2119 } else {
2120 console.log(response);
2121 $optionsElement.removeClass("hide");
2122 $demoProgress.addClass("hide");
2123 $buttonWrapperEl.removeClass("hide");
2124 $progressBarEl.addClass("hide");
2125 this._controlActions("on");
2126 }
2127 }.bind(this)
2128 );
2129 },
2130
2131 /**
2132 * Import step by step
2133 */
2134 _demoImport: function(data) {
2135 // Set variable
2136 this._ajaxData = {
2137 action: "import_step",
2138 step: data.step,
2139 index: data.index
2140 };
2141
2142 this.$progressBarLabelEl.text(data.message);
2143
2144 this._globalAJAX(
2145 function(response) {
2146 if (response !== null && response.success) {
2147 if (response.data.next !== "final") {
2148 this._demoImport({
2149 target: data.target,
2150 step: response.data.next,
2151 message: response.data.message,
2152 index: response.data.hasOwnProperty("index")
2153 ? response.data.index
2154 : ""
2155 });
2156 } else {
2157 this.$progressBarLabelEl.text(
2158 response.data.message
2159 );
2160 setTimeout(
2161 function() {
2162 this._controlActions("on");
2163 // Next Step Trigger
2164 this._stepManager({
2165 currentTarget: data.target
2166 });
2167 }.bind(this),
2168 1000
2169 );
2170 }
2171 } else {
2172 console.log(response);
2173 }
2174 }.bind(this)
2175 );
2176 },
2177
2178 /**
2179 * Uninstall demo functionality
2180 */
2181 _uninstallDemo: function(e) {
2182 // Check currentTarget existence
2183 if (!e.currentTarget) {
2184 return;
2185 }
2186 // check preventDefault existence
2187 if (typeof e.preventDefault !== "undefined") {
2188 e.preventDefault();
2189 }
2190 // Set variable
2191 var $buttonElement = $(e.currentTarget),
2192 $buttonParentEl = $buttonElement.closest(
2193 ".aux-setup-demo-actions"
2194 );
2195 this._ajaxData = {
2196 action: "aux_ajax_uninstall",
2197 id: $buttonElement.data("demo-id"),
2198 key: $(this._modalButton).data("demo-key"),
2199 nonce: $buttonElement.data("demo-nonce"),
2200 plugins: $buttonElement.data("demo-plugins")
2201 };
2202
2203 // Actions
2204 $buttonParentEl.find(".aux-return-back").addClass("hide");
2205 $buttonParentEl.find(".aux-progress").removeClass("hide");
2206
2207 this._controlActions("off");
2208
2209 this._globalAJAX(
2210 function(response) {
2211 $buttonParentEl
2212 .find(".aux-return-back")
2213 .removeClass("hide");
2214 $buttonParentEl.find(".aux-progress").addClass("hide");
2215
2216 if (response !== null && response.success) {
2217 this.$modalElement
2218 .find(".aux-steps-col")
2219 .html(response.data.markup);
2220 $(this._modalButton)
2221 .removeClass("aux-uninstall aux-orange")
2222 .addClass("aux-green2")
2223 .text(response.data.button)
2224 .attr("href", response.data.url);
2225 } else {
2226 console.log(response);
2227 }
2228 this._controlActions("on");
2229 }.bind(this)
2230 );
2231 },
2232
2233 /* ------------------------------------------------------------------------------ */
2234 // Plugin Manager
2235
2236 /**
2237 * Install/Activate Plugin
2238 */
2239 _pluginManager: function(e) {
2240 // Check currentTarget existence
2241 if (!e.currentTarget) {
2242 return;
2243 }
2244 // check preventDefault existence
2245 if (typeof e.preventDefault !== "undefined") {
2246 e.preventDefault();
2247 }
2248 // Set variable
2249 var $buttonElement = $(e.currentTarget);
2250 this.$buttonParentEl = $buttonElement.closest(
2251 ".aux-has-required-plugins"
2252 );
2253 this.$pluginsListEl = this.$buttonParentEl.find(
2254 ".aux-wizard-plugins"
2255 );
2256 this._selectedPluginsNum = this.$buttonParentEl.find(
2257 '.aux-plugin input[name="plugin[]"]:checked'
2258 ).length;
2259 this._itemsCompleted = 0;
2260 this._attemptsBuffer = 0;
2261 this._currentItem = null;
2262 this._buttonTarget = e.currentTarget;
2263 this.$currentNode = null;
2264
2265 // Manipulation
2266 this.$pluginsListEl.addClass("installing");
2267 $buttonElement
2268 .text(aux_setup_params.btnworks_text)
2269 .addClass("disabled");
2270
2271 this._controlActions("off");
2272 this._processPlugins();
2273 },
2274
2275 /**
2276 * Process selected plugins
2277 */
2278 _processPlugins: function() {
2279 var self = this,
2280 doNext = false,
2281 $pluginsList = this.$buttonParentEl.find(".aux-plugin");
2282
2283 // Scroll on each progress in modal view
2284 this._pluginScrollTo();
2285
2286 if (this.$currentNode) {
2287 if (!this.$currentNode.data("done_item")) {
2288 this._itemsCompleted++;
2289 this.$currentNode.data("done_item", 1);
2290 }
2291 this.$currentNode.find(".spinner").css("visibility", "hidden");
2292 }
2293
2294 $pluginsList.each(function() {
2295 if (self._currentItem == null || doNext) {
2296 if (
2297 $(this)
2298 .find('input[name="plugin[]"]')
2299 .is(":checked")
2300 ) {
2301 $(this).addClass("work-in-progress");
2302 self._currentItem = $(this).data("slug");
2303 self.$currentNode = $(this);
2304 self.$currentNode
2305 .find(".spinner")
2306 .css("visibility", "visible");
2307 self._installPlugin();
2308 doNext = false;
2309 }
2310 } else if ($(this).data("slug") === self._currentItem) {
2311 $(this).removeClass("work-in-progress");
2312 doNext = true;
2313 }
2314 });
2315
2316 // If all plugins finished, then
2317 if (this._itemsCompleted >= this._selectedPluginsNum) {
2318 // Activate control actions
2319 this._controlActions("on");
2320 // Remove installing class
2321 this.$buttonParentEl
2322 .find(".aux-wizard-plugins")
2323 .removeClass("installing");
2324 // Remove disable class from button
2325 $(this._buttonTarget).text(aux_setup_params.activate_text);
2326 // Change the text of "Skip This Step" button to "Next Step"
2327 this.$buttonParentEl
2328 .find(".skip-next")
2329 .text(aux_setup_params.nextstep_text);
2330 // Continue loading process
2331 if (
2332 this.$buttonParentEl.find(".aux-plugin").not(".aux-success")
2333 .length == 0 &&
2334 this.$buttonParentEl.hasClass("aux-modal-item")
2335 ) {
2336 // Change button text and data value if all required plugins has been installed & activated
2337 this._stepManager({ currentTarget: this._buttonTarget });
2338 }
2339 }
2340 },
2341
2342 /**
2343 * Process plugin by slug
2344 */
2345 _installPlugin: function() {
2346 if (this._currentItem) {
2347 var plugins = this.$buttonParentEl
2348 .find('.aux-wizard-plugins input[name="plugin[]"]:checked')
2349 .map(function() {
2350 return $(this).val();
2351 })
2352 .get();
2353 this._ajaxData = {
2354 action: "aux_setup_plugins",
2355 wpnonce: aux_setup_params.wpnonce,
2356 slug: this._currentItem,
2357 plugins: plugins
2358 };
2359 this._globalAJAX(
2360 function(response) {
2361 this._pluginActions(response);
2362 }.bind(this)
2363 );
2364 }
2365 },
2366
2367 /**
2368 * Plugin activation events
2369 */
2370 _pluginActions: function(response) {
2371 // Check response type
2372 if (typeof response === "object" && response.success) {
2373 // Update plugin status message
2374 this.$currentNode
2375 .find(".column-status span")
2376 .text(response.data.message);
2377 // At this point, if the response contains the url, it means that we need to install/activate it.
2378 if (typeof response.data.url !== "undefined") {
2379 if (this.currentItemHash == response.data.hash) {
2380 this.$currentNode
2381 .data("done_item", 0)
2382 .find(".column-status span")
2383 .text("failed");
2384 this.currentItemHash = null;
2385 this._installPlugin();
2386 } else {
2387 // we have an ajax url action to perform.
2388 this._ajaxUrl = response.data.url;
2389 this._ajaxData = response.data;
2390 this.currentItemHash = response.data.hash;
2391 this._globalAJAX(
2392 function(html) {
2393 // Reset ajax url to default admin ajax value
2394 this._ajaxUrl = aux_setup_params.ajaxurl;
2395 this.$currentNode
2396 .find(".column-status span")
2397 .text(response.data.message);
2398 this._installPlugin();
2399 }.bind(this)
2400 );
2401 }
2402 } else {
2403 // otherwise it's just installed and we should make a notify to user
2404 this.$currentNode
2405 .addClass("aux-success")
2406 .find(".aux-check-column")
2407 .remove();
2408 this.$currentNode
2409 .find(".check-column")
2410 .append(
2411 "<i class='aux-success-icon auxicon-check-mark-circle-outline'></i>"
2412 );
2413 // Then jump to next plugin
2414 this._processPlugins();
2415 }
2416 } else {
2417 // If there is an error, we will try to reinstall plugin twice with buffer checkup.
2418 if (this._attemptsBuffer > 1) {
2419 // Reset buffer value
2420 this._attemptsBuffer = 0;
2421 // error & try again with next plugin
2422 this.$currentNode
2423 .addClass("aux-error")
2424 .find(".column-status span")
2425 .text("Ajax Error!");
2426 this._processPlugins();
2427 } else {
2428 // Try again & update buffer value
2429 this.currentItemHash = null;
2430 this._attemptsBuffer++;
2431 this._installPlugin();
2432 }
2433 }
2434 },
2435
2436 /**
2437 * Scroll to active plugin row
2438 */
2439 _pluginScrollTo: function() {
2440 $(".aux-modal-item .aux-wizard-plugins").each(function() {
2441 $(this).scrollTo($(this).find(".work-in-progress"), 400);
2442 });
2443 },
2444
2445 /* ------------------------------------------------------------------------------ */
2446 // General Events
2447
2448 /**
2449 * Enable/Disable some control actions
2450 */
2451 _controlActions: function(type) {
2452 switch (type) {
2453 case "on":
2454 $(window).off("beforeunload");
2455 $(document).on("keydown keypress keyup");
2456 $(".aux-pp-close").removeClass("hide");
2457 break;
2458 default:
2459 $(window).on("beforeunload", function() {
2460 return aux_setup_params.onbefore_text;
2461 });
2462 $(document).off("keydown keypress keyup");
2463 $(".aux-pp-close").addClass("hide");
2464 }
2465 },
2466
2467 /**
2468 * Isotope callbacks
2469 */
2470 _callIsotope: function() {
2471 // isotope for template page
2472 this.$isotopeTemplate = $(".aux-isotope-templates").AuxIsotope({
2473 itemSelector: ".aux-iso-item",
2474 revealTransitionDuration: 0,
2475 revealBetweenDelay: 0,
2476 revealTransitionDelay: 0,
2477 hideTransitionDuration: 0,
2478 hideBetweenDelay: 0,
2479 hideTransitionDelay: 0,
2480 updateUponResize: true,
2481 transitionHelper: true,
2482 filters: ".aux-filters",
2483 slug: "filter",
2484 imgSizes: true
2485 });
2486
2487 // general isotope layout
2488 this.$isotopeList = $(".aux-isotope-list").AuxIsotope({
2489 itemSelector: ".aux-iso-item",
2490 revealTransitionDuration: 600,
2491 revealBetweenDelay: 50,
2492 revealTransitionDelay: 0,
2493 hideTransitionDuration: 300,
2494 hideBetweenDelay: 0,
2495 hideTransitionDelay: 0,
2496 updateUponResize: true,
2497 transitionHelper: true,
2498 filters: ".aux-filters",
2499 slug: "filter",
2500 imgSizes: true
2501 });
2502 // isotope for plugins list
2503 this.$isotopePlugins = $(".aux-isotope-plugins-list").AuxIsotope({
2504 itemSelector: ".aux-iso-item",
2505 revealTransitionDuration: 600,
2506 revealBetweenDelay: 50,
2507 revealTransitionDelay: 50,
2508 hideTransitionDuration: 100,
2509 hideBetweenDelay: 0,
2510 hideTransitionDelay: 0,
2511 updateUponResize: true,
2512 transitionHelper: true,
2513 filters: ".aux-filters",
2514 slug: "filter",
2515 imgSizes: true
2516 });
2517 },
2518
2519 /**
2520 * Refresh the isotope layout on load of each image
2521 */
2522 _lazyloadConfig: function() {
2523 document.addEventListener('lazyloaded', function( e ){
2524 $(window).trigger('resize');
2525 });
2526 },
2527
2528 /**
2529 * Global Manipulations
2530 */
2531 _manipulations: function() {
2532 // Auxin Toggle Select Plugin
2533 $(".aux-togglable").AuxinToggleSelected();
2534
2535 // init plugins border effect
2536 $('.aux-wizard-plugins input[name="plugin[]"]').each(function() {
2537 if ($(this).is(":checked")) {
2538 $(this)
2539 .closest(".aux-table-row")
2540 .addClass("is-checked");
2541 } else {
2542 $(this)
2543 .closest(".aux-table-row")
2544 .removeClass("is-checked");
2545 }
2546 $(this).on( 'click', function() {
2547 if ($(this).is(":checked")) {
2548 $(this)
2549 .closest(".aux-table-row")
2550 .addClass("is-checked");
2551 } else {
2552 $(this)
2553 .closest(".aux-table-row")
2554 .removeClass("is-checked");
2555 }
2556 });
2557 });
2558
2559 // Install plugins button display depends on user's checkbox selection
2560 $(".aux-plugins-step input[type=checkbox]").change(function() {
2561 if (
2562 $('.aux-wizard-plugins input[name="plugin[]"]').filter(
2563 ":checked"
2564 ).length > 0
2565 ) {
2566 $(".install-plugins").removeClass("disabled");
2567 } else {
2568 $(".install-plugins").addClass("disabled");
2569 }
2570 });
2571
2572 // Install demos button display depends on user's checkbox selection
2573 $(document).on(
2574 "click",
2575 ".aux-install-demos input[type=checkbox]",
2576 function(e) {
2577 if (
2578 $(".featherlight-content")
2579 .find("input[type=checkbox]")
2580 .filter(":checked").length > 0
2581 ) {
2582 $(".featherlight-content")
2583 .find(".button-next")
2584 .removeClass("aux-next-step")
2585 .data("callback", "install_demos")
2586 .attr("data-callback", "install_demos")
2587 .text(aux_setup_params.makedemo_text);
2588 } else {
2589 $(".featherlight-content")
2590 .find(".button-next")
2591 .addClass("aux-next-step")
2592 .text(aux_setup_params.nextstep_text)
2593 .data("callback", null)
2594 .removeAttr("data-callback");
2595 }
2596 }
2597 );
2598
2599 // a simple event to select custom demo type
2600 $(document).on("click", ".aux-radio", function(e) {
2601 $(this)
2602 .closest("form")
2603 .find(".aux-border")
2604 .removeClass("is-checked");
2605 $(this)
2606 .parent(".aux-border")
2607 .addClass("is-checked");
2608 });
2609
2610 // Display/Hide the pophover box of more button (Used in template kits three dotted button)
2611 $(document).on("click", ".aux-more-button", function(e) {
2612 e.preventDefault();
2613 $(this)
2614 .next(".aux-more-items")
2615 .toggleClass("aux-display");
2616 });
2617 },
2618
2619 /**
2620 * Get envato elements license code
2621 */
2622 _verifyEnvatoElementsEmail: function(e) {
2623
2624 // Check currentTarget existence
2625 if (!e.currentTarget) {
2626 return;
2627 }
2628
2629 var email = $('.email-field').val();
2630 var self = this;
2631 var $modalSectionElement = this.$modalElement.find(
2632 ".aux-steps-col"
2633 );
2634 this._buttonTarget = e.currentTarget
2635 this._ajaxData = {
2636 action: 'aux_verify_envato_elements_email',
2637 email: email,
2638 };
2639 $modalSectionElement.addClass("aux-step-in-progress");
2640 this._globalAJAX(
2641 function(response) {
2642 if (response.status) {
2643 self._stepManager({ currentTarget: self._buttonTarget });
2644 } else {
2645 $modalSectionElement.removeClass("aux-step-in-progress");
2646 $('.token-wrapper .result').addClass('error').text(response.message);
2647 }
2648 }
2649 );
2650 },
2651
2652 /**
2653 * verify envato elements token
2654 */
2655 _verifyEnvatoElementsToken: function(e) {
2656
2657 // Check currentTarget existence
2658 if (!e.currentTarget) {
2659 return;
2660 }
2661
2662 var token = $('.token-field').val();
2663 var self = this;
2664 var $modalSectionElement = this.$modalElement.find(
2665 ".aux-steps-col"
2666 );
2667 this._buttonTarget = e.currentTarget
2668 this._ajaxData = {
2669 action: 'aux_verify_envato_elements_token',
2670 token: token,
2671 };
2672 $modalSectionElement.addClass("aux-step-in-progress");
2673 this._globalAJAX(
2674 function(response) {
2675 if (response.status) {
2676 $modalSectionElement.removeClass("aux-step-in-progress");
2677 $('.token-wrapper .result').addClass('success').text(response.message);
2678 self._stepManager({ currentTarget: self._buttonTarget });
2679 } else {
2680 $modalSectionElement.removeClass("aux-step-in-progress");
2681 $('.token-wrapper .result').addClass('error').text(response.message);
2682 }
2683
2684 }
2685 );
2686 }
2687 });
2688
2689 // A really lightweight plugin wrapper around the constructor,
2690 // preventing against multiple instantiations
2691 $.fn[pluginName] = function(options) {
2692 return this.each(function() {
2693 new Plugin(this, options);
2694 });
2695 };
2696 })(jQuery, window, document);