PageSourceSearch

https://www.convert.com/wp-content/themes/olympus/js/ladda.js

js convert.com collected 2026-10-01 08:34:18 UTC 21,044 bytes, 810 lines download raw bytes

1/**
2 * Copyright (c) 2011-2014 Felix Gnass
3 * Licensed under the MIT license
4 */
5(function(root, factory) {
6
7  // CommonJS
8  if (typeof exports == 'object') {
9    module.exports = factory();
10  }
11  // AMD module
12  else if (typeof define == 'function' && define.amd) {
13    define(factory);
14  }
15  // Browser global
16  else {
17    root.Spinner = factory();
18  }
19
20}
21(this, function() {
22  "use strict";
23
24  var prefixes = ['webkit', 'Moz', 'ms', 'O'] /* Vendor prefixes */
25    , animations = {} /* Animation rules keyed by their name */
26    , useCssAnimations /* Whether to use CSS animations or setTimeout */
27
28  /**
29   * Utility function to create elements. If no tag name is given,
30   * a DIV is created. Optionally properties can be passed.
31   */
32  function createEl(tag, prop) {
33    var el = document.createElement(tag || 'div')
34      , n
35
36    for(n in prop) el[n] = prop[n]
37    return el
38  }
39
40  /**
41   * Appends children and returns the parent.
42   */
43  function ins(parent /* child1, child2, ...*/) {
44    for (var i=1, n=arguments.length; i<n; i++)
45      parent.appendChild(arguments[i])
46
47    return parent
48  }
49
50  /**
51   * Insert a new stylesheet to hold the @keyframe or VML rules.
52   */
53  var sheet = (function() {
54    var el = createEl('style', {type : 'text/css'})
55    ins(document.getElementsByTagName('head')[0], el)
56    return el.sheet || el.styleSheet
57  }())
58
59  /**
60   * Creates an opacity keyframe animation rule and returns its name.
61   * Since most mobile Webkits have timing issues with animation-delay,
62   * we create separate rules for each line/segment.
63   */
64  function addAnimation(alpha, trail, i, lines) {
65    var name = ['opacity', trail, ~~(alpha*100), i, lines].join('-')
66      , start = 0.01 + i/lines * 100
67      , z = Math.max(1 - (1-alpha) / trail * (100-start), alpha)
68      , prefix = useCssAnimations.substring(0, useCssAnimations.indexOf('Animation')).toLowerCase()
69      , pre = prefix && '-' + prefix + '-' || ''
70
71    if (!animations[name]) {
72      sheet.insertRule(
73        '@' + pre + 'keyframes ' + name + '{' +
74        '0%{opacity:' + z + '}' +
75        start + '%{opacity:' + alpha + '}' +
76        (start+0.01) + '%{opacity:1}' +
77        (start+trail) % 100 + '%{opacity:' + alpha + '}' +
78        '100%{opacity:' + z + '}' +
79        '}', sheet.cssRules.length)
80
81      animations[name] = 1
82    }
83
84    return name
85  }
86
87  /**
88   * Tries various vendor prefixes and returns the first supported property.
89   */
90  function vendor(el, prop) {
91    var s = el.style
92      , pp
93      , i
94
95    prop = prop.charAt(0).toUpperCase() + prop.slice(1)
96    for(i=0; i<prefixes.length; i++) {
97      pp = prefixes[i]+prop
98      if(s[pp] !== undefined) return pp
99    }
100    if(s[prop] !== undefined) return prop
101  }
102
103  /**
104   * Sets multiple style properties at once.
105   */
106  function css(el, prop) {
107    for (var n in prop)
108      el.style[vendor(el, n)||n] = prop[n]
109
110    return el
111  }
112
113  /**
114   * Fills in default values.
115   */
116  function merge(obj) {
117    for (var i=1; i < arguments.length; i++) {
118      var def = arguments[i]
119      for (var n in def)
120        if (obj[n] === undefined) obj[n] = def[n]
121    }
122    return obj
123  }
124
125  /**
126   * Returns the absolute page-offset of the given element.
127   */
128  function pos(el) {
129    var o = { x:el.offsetLeft, y:el.offsetTop }
130    while((el = el.offsetParent))
131      o.x+=el.offsetLeft, o.y+=el.offsetTop
132
133    return o
134  }
135
136  /**
137   * Returns the line color from the given string or array.
138   */
139  function getColor(color, idx) {
140    return typeof color == 'string' ? color : color[idx % color.length]
141  }
142
143  // Built-in defaults
144
145  var defaults = {
146    lines: 12,            // The number of lines to draw
147    length: 7,            // The length of each line
148    width: 5,             // The line thickness
149    radius: 10,           // The radius of the inner circle
150    rotate: 0,            // Rotation offset
151    corners: 1,           // Roundness (0..1)
152    color: '#000',        // #rgb or #rrggbb
153    direction: 1,         // 1: clockwise, -1: counterclockwise
154    speed: 1,             // Rounds per second
155    trail: 100,           // Afterglow percentage
156    opacity: 1/4,         // Opacity of the lines
157    fps: 20,              // Frames per second when using setTimeout()
158    zIndex: 2e9,          // Use a high z-index by default
159    className: 'spinner', // CSS class to assign to the element
160    top: '50%',           // center vertically
161    left: '50%',          // center horizontally
162    position: 'absolute'  // element position
163  }
164
165  /** The constructor */
166  function Spinner(o) {
167    this.opts = merge(o || {}, Spinner.defaults, defaults)
168  }
169
170  // Global defaults that override the built-ins:
171  Spinner.defaults = {}
172
173  merge(Spinner.prototype, {
174
175    /**
176     * Adds the spinner to the given target element. If this instance is already
177     * spinning, it is automatically removed from its previous target b calling
178     * stop() internally.
179     */
180    spin: function(target) {
181      this.stop()
182
183      var self = this
184        , o = self.opts
185        , el = self.el = css(createEl(0, {className: o.className}), {position: o.position, width: 0, zIndex: o.zIndex})
186        , mid = o.radius+o.length+o.width
187
188      css(el, {
189        left: o.left,
190        top: o.top
191      })
192        
193      if (target) {
194        target.insertBefore(el, target.firstChild||null)
195      }
196
197      el.setAttribute('role', 'progressbar')
198      self.lines(el, self.opts)
199
200      if (!useCssAnimations) {
201        // No CSS animation support, use setTimeout() instead
202        var i = 0
203          , start = (o.lines - 1) * (1 - o.direction) / 2
204          , alpha
205          , fps = o.fps
206          , f = fps/o.speed
207          , ostep = (1-o.opacity) / (f*o.trail / 100)
208          , astep = f/o.lines
209
210        ;(function anim() {
211          i++;
212          for (var j = 0; j < o.lines; j++) {
213            alpha = Math.max(1 - (i + (o.lines - j) * astep) % f * ostep, o.opacity)
214
215            self.opacity(el, j * o.direction + start, alpha, o)
216          }
217          self.timeout = self.el && setTimeout(anim, ~~(1000/fps))
218        })()
219      }
220      return self
221    },
222
223    /**
224     * Stops and removes the Spinner.
225     */
226    stop: function() {
227      var el = this.el
228      if (el) {
229        clearTimeout(this.timeout)
230        if (el.parentNode) el.parentNode.removeChild(el)
231        this.el = undefined
232      }
233      return this
234    },
235
236    /**
237     * Internal method that draws the individual lines. Will be overwritten
238     * in VML fallback mode below.
239     */
240    lines: function(el, o) {
241      var i = 0
242        , start = (o.lines - 1) * (1 - o.direction) / 2
243        , seg
244
245      function fill(color, shadow) {
246        return css(createEl(), {
247          position: 'absolute',
248          width: (o.length+o.width) + 'px',
249          height: o.width + 'px',
250          background: color,
251          boxShadow: shadow,
252          transformOrigin: 'left',
253          transform: 'rotate(' + ~~(360/o.lines*i+o.rotate) + 'deg) translate(' + o.radius+'px' +',0)',
254          borderRadius: (o.corners * o.width>>1) + 'px'
255        })
256      }
257
258      for (; i < o.lines; i++) {
259        seg = css(createEl(), {
260          position: 'absolute',
261          top: 1+~(o.width/2) + 'px',
262          transform: o.hwaccel ? 'translate3d(0,0,0)' : '',
263          opacity: o.opacity,
264          animation: useCssAnimations && addAnimation(o.opacity, o.trail, start + i * o.direction, o.lines) + ' ' + 1/o.speed + 's linear infinite'
265        })
266
267        if (o.shadow) ins(seg, css(fill('#000', '0 0 4px ' + '#000'), {top: 2+'px'}))
268        ins(el, ins(seg, fill(getColor(o.color, i), '0 0 1px rgba(0,0,0,.1)')))
269      }
270      return el
271    },
272
273    /**
274     * Internal method that adjusts the opacity of a single line.
275     * Will be overwritten in VML fallback mode below.
276     */
277    opacity: function(el, i, val) {
278      if (i < el.childNodes.length) el.childNodes[i].style.opacity = val
279    }
280
281  })
282
283
284  function initVML() {
285
286    /* Utility function to create a VML tag */
287    function vml(tag, attr) {
288      return createEl('<' + tag + ' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">', attr)
289    }
290
291    // No CSS transforms but VML support, add a CSS rule for VML elements:
292    sheet.addRule('.spin-vml', 'behavior:url(#default#VML)')
293
294    Spinner.prototype.lines = function(el, o) {
295      var r = o.length+o.width
296        , s = 2*r
297
298      function grp() {
299        return css(
300          vml('group', {
301            coordsize: s + ' ' + s,
302            coordorigin: -r + ' ' + -r
303          }),
304          { width: s, height: s }
305        )
306      }
307
308      var margin = -(o.width+o.length)*2 + 'px'
309        , g = css(grp(), {position: 'absolute', top: margin, left
309: margin})
310        , i
311
312      function seg(i, dx, filter) {
313        ins(g,
314          ins(css(grp(), {rotation: 360 / o.lines * i + 'deg', left: ~~dx}),
315            ins(css(vml('roundrect', {arcsize: o.corners}), {
316                width: r,
317                height: o.width,
318                left: o.radius,
319                top: -o.width>>1,
320                filter: filter
321              }),
322              vml('fill', {color: getColor(o.color, i), opacity: o.opacity}),
323              vml('stroke', {opacity: 0}) // transparent stroke to fix color bleeding upon opacity change
324            )
325          )
326        )
327      }
328
329      if (o.shadow)
330        for (i = 1; i <= o.lines; i++)
331          seg(i, -2, 'progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)')
332
333      for (i = 1; i <= o.lines; i++) seg(i)
334      return ins(el, g)
335    }
336
337    Spinner.prototype.opacity = function(el, i, val, o) {
338      var c = el.firstChild
339      o = o.shadow && o.lines || 0
340      if (c && i+o < c.childNodes.length) {
341        c = c.childNodes[i+o]; c = c && c.firstChild; c = c && c.firstChild
342        if (c) c.opacity = val
343      }
344    }
345  }
346
347  var probe = css(createEl('group'), {behavior: 'url(#default#VML)'})
348
349  if (!vendor(probe, 'transform') && probe.adj) initVML()
350  else useCssAnimations = vendor(probe, 'animation')
351
352  return Spinner
353
354}));
355
356
357/*!
358 * Ladda
359 * http://lab.hakim.se/ladda
360 * MIT licensed
361 *
362 * Copyright (C) 2015 Hakim El Hattab, http://hakim.se
363 */
364/* jshint node:true, browser:true */
365(function( root, factory ) {
366
367	// CommonJS
368	if( typeof exports === 'object' )  {
369		module.exports = factory(require('spin.js'));
370	}
371	// AMD module
372	else if( typeof define === 'function' && define.amd ) {
373		define( [ 'spin' ], factory );
374	}
375	// Browser global
376	else {
377		root.Ladda = factory( root.Spinner );
378	}
379
380}
381(this, function( Spinner ) {
382	'use strict';
383
384	// All currently instantiated instances of Ladda
385	var ALL_INSTANCES = [];
386
387	/**
388	 * Creates a new instance of Ladda which wraps the
389	 * target button element.
390	 *
391	 * @return An API object that can be used to control
392	 * the loading animation state.
393	 */
394	function create( button ) {
395
396		if( typeof button === 'undefined' ) {
397			console.warn( "Ladda button target must be defined." );
398			return;
399		}
400
401		// The button must have the class "ladda-button"
402		if( !/ladda-button/i.test( button.className ) ) {
403			button.className += ' ladda-button';
404		}
405
406		// Style is required, default to "expand-right"
407		if( !button.hasAttribute( 'data-style' ) ) {
408			button.setAttribute( 'data-style', 'expand-right' );
409		}
410
411		// The text contents must be wrapped in a ladda-label
412		// element, create one if it doesn't already exist
413		if( !button.querySelector( '.ladda-label' ) ) {
414			var laddaLabel = document.createElement( 'span' );
415			laddaLabel.className = 'ladda-label';
416			wrapContent( button, laddaLabel );
417		}
418
419		// The spinner component
420		var spinner,
421			spinnerWrapper = button.querySelector( '.ladda-spinner' );
422
423		// Wrapper element for the spinner
424		if( !spinnerWrapper ) {
425			spinnerWrapper = document.createElement( 'span' );
426			spinnerWrapper.className = 'ladda-spinner';
427		}
428
429		button.appendChild( spinnerWrapper );
430
431		// Timer used to delay starting/stopping
432		var timer;
433
434		var instance = {
435
436			/**
437			 * Enter the loading state.
438			 */
439			start: function() {
440
441				// Create the spinner if it doesn't already exist
442				if( !spinner ) spinner = createSpinner( button );
443
444				button.setAttribute( 'disabled', '' );
445				button.setAttribute( 'data-loading', '' );
446
447				clearTimeout( timer );
448				spinner.spin( spinnerWrapper );
449
450				this.setProgress( 0 );
451
452				return this; // chain
453
454			},
455
456			/**
457			 * Enter the loading state, after a delay.
458			 */
459			startAfter: function( delay ) {
460
461				clearTimeout( timer );
462				timer = setTimeout( function() { instance.start(); }, delay );
463
464				return this; // chain
465
466			},
467
468			/**
469			 * Exit the loading state.
470			 */
471			stop: function() {
472
473				button.removeAttribute( 'disabled' );
474				button.removeAttribute( 'data-loading' );
475
476				// Kill the animation after a delay to make sure it
477				// runs for the duration of the button transition
478				clearTimeout( timer );
479
480				if( spinner ) {
481					timer = setTimeout( function() { spinner.stop(); }, 1000 );
482				}
483
484				return this; // chain
485
486			},
487
488			/**
489			 * Toggle the loading state on/off.
490			 */
491			toggle: function() {
492
493				if( this.isLoading() ) {
494					this.stop();
495				}
496				else {
497					this.start();
498				}
499
500				return this; // chain
501
502			},
503
504			/**
505			 * Sets the width of the visual progress bar inside of
506			 * this Ladda button
507			 *
508			 * @param {Number} progress in the range of 0-1
509			 */
510			setProgress: function( progress ) {
511
512				// Cap it
513				progress = Math.max( Math.min( progress, 1 ), 0 );
514
515				var progressElement = button.querySelector( '.ladda-progress' );
516
517				// Remove the progress bar if we're at 0 progress
518				if( progress === 0 && progressElement && progressElement.parentNode ) {
519					progressElement.parentNode.removeChild( progressElement );
520				}
521				else {
522					if( !progressElement ) {
523						progressElement = document.createElement( 'div' );
524						progressElement.className = 'ladda-progress';
525						button.appendChild( progressElement );
526					}
527
528					progressElement.style.width = ( ( progress || 0 ) * button.offsetWidth ) + 'px';
529				}
530
531			},
532
533			enable: function() {
534
535				this.stop();
536
537				return this; // chain
538
539			},
540
541			disable: function () {
542
543				this.stop();
544				button.setAttribute( 'disabled', '' );
545
546				return this; // chain
547
548			},
549
550			isLoading: function() {
551
552				return button.hasAttribute( 'data-loading' );
553
554			},
555
556			remove: function() {
557
558				clearTimeout( timer );
559
560				button.removeAttribute( 'disabled', '' );
561				button.removeAttribute( 'data-loading', '' );
562
563				if( spinner ) {
564					spinner.stop();
565					spinner = null;
566				}
567
568				for( var i = 0, len = ALL_INSTANCES.length; i < len; i++ ) {
569					if( instance === ALL_INSTANCES[i] ) {
570						ALL_INSTANCES.splice( i, 1 );
571						break;
572					}
573				}
574
575			}
576
577		};
578
579		ALL_INSTANCES.push( instance );
580
581		return instance;
582
583	}
584
585	/**
586	* Get the first ancestor node from an element, having a
587	* certain type.
588	*
589	* @param elem An HTML element
590	* @param type an HTML tag type (uppercased)
591	*
592	* @return An HTML element
593	*/
594	function getAncestorOfTagType( elem, type ) {
595
596		while ( elem.parentNode && elem.tagName !== type ) {
597			elem = elem.parentNode;
598		}
599
600		return ( type === elem.tagName ) ? elem : undefined;
601
602	}
603
604	/**
605	 * Returns a list of all inputs in the given form that
606	 * have their `required` attribute set.
607	 *
608	 * @param form The from HTML element to look in
609	 *
610	 * @return A list of elements
611	 */
612	function getRequiredFields( form ) {
613
614		var requirables = [ 'input', 'textarea', 'select' ];
615		var inputs = [];
616
617		for( var i = 0; i < requirables.length; i++ ) {
618			var candidates = form.getElementsByTagName( requirables[i] );
619			for( var j = 0; j < candidates.length; j++ ) {
620				if ( candidates[j].hasAttribute( 'required' ) ) {
621					inputs.push( candidates[j] );
622				}
623			}
624		}
625
626		return inputs;
627
628	}
629
630
631	/**
632	 * Binds the target buttons to automatically enter the
633	 * loading state when clicked.
634	 *
635	 * @param target Either an HTML element or a CSS selector.
636	 * @param options
637	 *          - timeout Number of milliseconds to wait before
638	 *            automatically cancelling the animation.
639	 */
640	function bind( target, options ) {
641
642		options = options || {};
643
644		var targets = [];
645
646		if( typeof target === 'string' ) {
647			targets = toArray( document.querySelectorAll( target ) );
648		}
649		else if( typeof target === 'object' && typeof target.nodeName === 'string' ) {
650			targets = [ target ];
651		}
652
653		for( var i = 0, len = targets.length; i < len; i++ ) {
654
655			(function() {
656				var element = targets[i];
657
658				// Make sure we're working with a DOM element
659				if( typeof element.addEventListener === 'function' ) {
660					var instance = create( element );
661					var timeout = -1;
662
663					element.addEventListener( 'click', function( event ) {
664
665						// If the button belongs to a form, make sure all the
666						// fields in that form are filled out
667						var valid = true;
668						var form = getAncestorOfTagType( element, 'FORM' );
669
670						if( typeof form !== 'undefined' ) {
671							var requireds = getRequiredFields( form );
672							for( var i = 0; i < requireds.length; i++ ) {
673
674								// Alternatively to this trim() check,
675								// we could have use .checkValidity() or .validity.valid
676								if( requireds[i].value.replace( /^\s+|\s+$/g, '' ) === '' ) {
677									valid = false;
678								}
679
680								// Radiobuttons and Checkboxes need to be checked for the "checked" attribute
681								if( (requireds[i].type === 'checkbox' || requireds[i].type === 'radio' ) && !requireds[i].checked ) {
682									valid = false;
683								}
684
685								// Email field validation, otherwise button starts spinning although field is not complete
686								if( requireds[i].type === 'email' ) {
687									valid = /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$/.test( requireds[i].value );
688								}
689
690							}
691						}
692
693						if( valid ) {
694							// This is asynchronous to avoid an issue where setting
695							// the disabled attribute on the button prevents forms
696							// from submitting
697							instance.startAfter( 1 );
698
699							// Set a loading timeout if one is specified
700							if( typeof options.timeout === 'number' ) {
701								clearTimeout( timeout );
702								timeout = setTimeout( instance.stop, options.timeout );
703							}
704
705							// Invoke callbacks
706							if( typeof options.callback === 'function' ) {
707								options.callback.apply( null, [ instance ] );
708							}
709						}
710
711					}, false );
712				}
713			})();
714
715		}
716
717	}
718
719	/**
720	 * Stops ALL current loading animations.
721	 */
722	function stopAll() {
723
724		for( var i = 0, len = ALL_INSTANCES.length; i < len; i++ ) {
725			ALL_INSTANCES[i].stop();
726		}
727
728	}
729
730	function createSpinner( button ) {
731
732		var height = button.offsetHeight,
733			spinnerColor,
734			spinnerLines;
735
736		if( height === 0 ) {
737			// We may have an element that is not visible so
738			// we attempt to get the height in a different way
739			height = parseFloat( window.getComputedStyle( button ).height );
740		}
741
742		// If the button is tall we can afford some padding
743		if( height > 32 ) {
744			height *= 0.8;
745		}
746
747		// Prefer an explicit height if one is defined
748		if( button.hasAttribute( 'data-spinner-size' ) ) {
749			height = parseInt( button.getAttribute( 'data-spinner-size' ), 10 );
750		}
751
752		// Allow buttons to specify the color of the spinner element
753		if( button.hasAttribute( 'data-spinner-color' ) ) {
754			spinnerColor = button.getAttribute( 'data-spinner-color' );
755		}
756
757		// Allow buttons to specify the number of lines of the spinner
758		if( button.hasAttribute( 'data-spinner-lines' ) ) {
759			spinnerLines = parseInt( button.getAttribute( 'data-spinner-lines' ), 10 );
760		}
761
762		var radius = height * 0.2,
763			length = radius * 0.6,
764			width = radius < 7 ? 2 : 3;
765
766		return new Spinner( {
767			color: spinnerColor || '#fff',
768			lines: spinnerLines || 12,
769			radius: radius,
770			length: length,
771			width: width,
772			zIndex: 'auto',
773			top: 'auto',
774			left: 'auto',
775			className: ''
776		} );
777
778	}
779
780	function toArray( nodes ) {
781
782		var a = [];
783
784		for ( var i = 0; i < nodes.length; i++ ) {
785			a.push( nodes[ i ] );
786		}
787
788		return a;
789
790	}
791
792	function wrapContent( node, wrapper ) {
793
794		var r = document.createRange();
795		r.selectNodeContents( node );
796		r.surroundContents( wrapper );
797		node.appendChild( wrapper );
798
799	}
800
801	// Public API
802	return {
803
804		bind: bind,
805		create: create,
806		stopAll: stopAll
807
808	};
809
810}));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.