/*!
* Ladda
* http://lab.hakim.se/ladda
* MIT licensed
*
* Copyright (C) 2018 Hakim El Hattab, http://hakim.se
*/import{Spinner}from'spin.js';// All currently instantiated instances of LaddavarALL_INSTANCES=[];/**
* Creates a new instance of Ladda which wraps the
* target button element.
*
* @return An API object that can be used to control
* the loading animation state.
*/exportfunctioncreate( button ){if(typeof button ==='undefined'){
console.warn("Ladda button target must be defined.");return;}// The button must have the class "ladda-button"if(!button.classList.contains('ladda-button')){
button.classList.add('ladda-button');}// Style is required, default to "expand-right"if(!button.hasAttribute('data-style')){
button.setAttribute('data-style','expand-right');}// The text contents must be wrapped in a ladda-label// element, create one if it doesn't already existif(!button.querySelector('.ladda-label')){var laddaLabel = document.createElement('span');
laddaLabel.className ='ladda-label';wrapContent( button, laddaLabel );}// The spinner componentvar spinner,
spinnerWrapper = button.querySelector('.ladda-spinner');// Wrapper element for the spinnerif(!spinnerWrapper ){
spinnerWrapper = document.createElement('span');
spinnerWrapper.className ='ladda-spinner';}
button.appendChild( spinnerWrapper );// Timer used to delay starting/stoppingvar timer;var instance ={/**
* Enter the loading state.
*/
start:function(){// Create the spinner if it doesn't already existif(!spinner ){
spinner =createSpinner( button );}
button.disabled =true;
button.setAttribute('data-loading','');clearTimeout( timer );
spinner.spin( spinnerWrapper );this.setProgress(0);returnthis;// chain},/**
* Enter the loading state, after a delay.
*/
startAfter:function( delay ){clearTimeout( timer );
timer =setTimeout(function(){ instance.start();}, delay );returnthis;// chain},/**
* Exit the loading state.
*/
stop:function(){if(instance.isLoading()){
button.disabled =false;
button.removeAttribute('data-loading');}// Kill the animation after a delay to make sure it// runs for the duration of the button transitionclearTimeout( timer );if( spinner ){
timer =setTimeout(function(){ spinner.stop();},1000);}returnthis;// chain},/**
* Toggle the loading state on/off.
*/
toggle:function(){returnthis.isLoading()?this.stop():this.start();},/**
* Sets the width of the visual progress bar inside of
* this Ladda button
*
* @param {Number} progress in the range of 0-1
*/
setProgress:function( progress ){// Cap it
progress = Math.max( Math.min( progress,1),0);var progressElement = button.querySelector('.ladda-progress');// Remove the progress bar if we're at 0 progressif( progress ===0&& progressElement && progressElement.parentNode ){
progressElement.parentNode.removeChild( progressElement );}else{if(!progressElement ){
progressElement = document.createElement('div');
progressElement.className ='ladda-progress';
button.appendChild( progressElement );}
progressElement.style.width =(( progress ||0)* button.offsetWidth )+'px';}},
isLoading:function(){return button.hasAttribute('data-loading');},
remove:function(){clearTimeout( timer );
button.disabled =false;
button.removeAttribute('data-loading');if( spinner ){
spinner.stop();
spinner =null;}ALL_INSTANCES.splice(ALL_INSTANCES.indexOf(instance),1);}};ALL_INSTANCES.push( instance );return instance;}/**
* Binds the target buttons to automatically enter the
* loading state when clicked.
*
* @param target Either an HTML element or a CSS selector.
* @param options
* - timeout Number of milliseconds to wait before
* automatically cancelling the animation.
* - callback A function to be called with the Ladda
* instance when a target button is clicked.
*/exportfunctionbind( target, options ){var targets;if(typeof target ==='string'){
targets = document.querySelectorAll( target );}elseif(typeof target ==='object'){
targets =[ target ];}else{thrownewError('target must be string or object');}
options = options ||{};for(var i =0; i < targets.length; i++){bindElement(targets[i], options);}}/**
* Stops ALL current loading animations.
*/exportfunctionstopAll(){for(var i =0, len =ALL_INSTANCES.length; i < len; i++){ALL_INSTANCES[i].stop();}}/**
* Get the first ancestor node from an element, having a
* certain type.
*
* @param elem An HTML element
* @param type an HTML tag type (uppercased)
*
* @return An HTML element
*/functiongetAncestorOfTagType( elem, type ){while( elem.parentNode && elem.tagName !== type ){
elem = elem.parentNode;}return( type === elem.tagName )? elem : undefined;}functioncreateSpinner( button ){var height = button.offsetHeight,
spinnerColor,
spinnerLines;if( height ===0){// We may have an element that is not visible so// we attempt to get the height in a different way
height =parseFloat( window.getComputedStyle( button ).height );}// If the button is tall we can afford some paddingif( height >32){
height *=0.8;}// Prefer an explicit height if one is definedif( button.hasAttribute('data-spinner-size')){
height =parseInt( button.getAttribute('data-spinner-size'),10);}// Allow buttons to specify the color of the spinner elementif( button.hasAttribute('data-spinner-color')){
spinnerColor = button.getAttribute('data-spinner-color');}// Allow buttons to specify the number of lines of the spinnerif( button.hasAttribute('data-spinner-lines')){
spinnerLines =parseInt( button.getAttribute('data-spinner-lines'),10);}var radius = height *0.2,
length = radius *0.6,
width = radius <7?2:3;returnnewSpinner({
color: spinnerColor ||'#fff',
lines: spinnerLines ||12,
radius: radius,
length: length,
width: width,
animation:'ladda-spinner-line-fade',
zIndex:'auto',
top:'auto',
left:'auto',
className:''});}functionwrapContent( node, wrapper ){var r = document.createRange();
r.selectNodeContents( node );
r.surroundContents( wrapper );
node.appendChild( wrapper );}functionbindElement( element, options ){if(typeof element.addEventListener !=='function'){return;}var instance =create( element );var timeout =-1;
element.addEventListener('click',function(){// If the button belongs to a form, make sure all the// fields in that form are filled outvar valid =true;var form =getAncestorOfTagType( element,'FORM');if(typeof form !=='undefined'&&!form.hasAttribute('novalidate')){// Modern form validationif(typeof form.checkValidity ==='function'){
valid = form.checkValidity();}}if( valid ){// This is asynchronous to avoid an issue where disabling// the button prevents forms from submitting
instance.startAfter(1);// Set a loading timeout if one is specifiedif(typeof options.timeout ==='number'){clearTimeout( timeout );
timeout =setTimeout( instance.stop, options.timeout );}// Invoke callbacksif(typeof options.callback ==='function'){
options.callback.apply(null,[ instance ]);}}},false);}
ES2015語法
'use strict';
Object.defineProperty(exports,"__esModule",{
value:true});var _typeof =typeof Symbol ==="function"&&typeof Symbol.iterator ==="symbol"?function(obj){returntypeof obj;}:function(obj){return obj &&typeof Symbol ==="function"&& obj.constructor === Symbol && obj !== Symbol.prototype ?"symbol":typeof obj;};/*!
* Ladda
* http://lab.hakim.se/ladda
* MIT licensed
*
* Copyright (C) 2018 Hakim El Hattab, http://hakim.se
*/
exports.create = create;
exports.bind = bind;
exports.stopAll = stopAll;var _spin =require('spin.js');// All currently instantiated instances of LaddavarALL_INSTANCES=[];/**
* Creates a new instance of Ladda which wraps the
* target button element.
*
* @return An API object that can be used to control
* the loading animation state.
*/functioncreate(button){if(typeof button ==='undefined'){
console.warn("Ladda button target must be defined.");return;}// The button must have the class "ladda-button"if(!button.classList.contains('ladda-button')){
button.classList.add('ladda-button');}// Style is required, default to "expand-right"if(!button.hasAttribute('data-style')){
button.setAttribute('data-style','expand-right');}// The text contents must be wrapped in a ladda-label// element, create one if it doesn't already existif(!button.querySelector('.ladda-label')){var laddaLabel = document.createElement('span');
laddaLabel.className ='ladda-label';wrapContent(button, laddaLabel);}// The spinner componentvar spinner,
spinnerWrapper = button.querySelector('.ladda-spinner');// Wrapper element for the spinnerif(!spinnerWrapper){
spinnerWrapper = document.createElement('span');
spinnerWrapper.className ='ladda-spinner';}
button.appendChild(spinnerWrapper);// Timer used to delay starting/stoppingvar timer;var instance ={/**
* Enter the loading state.
*/
start:functionstart(){// Create the spinner if it doesn't already existif(!spinner){
spinner =createSpinner(button);}
button.disabled =true;
button.setAttribute('data-loading','');clearTimeout(timer);
spinner.spin(spinnerWrapper);this.setProgress(0);returnthis;// chain},/**
* Enter the loading state, after a delay.
*/
startAfter:functionstartAfter(delay){clearTimeout(timer);
timer =setTimeout(function(){
instance.start();}, delay);returnthis;// chain},/**
* Exit the loading state.
*/
stop:functionstop(){if(instance.isLoading()){
button.disabled =false;
button.removeAttribute('data-loading');}// Kill the animation after a delay to make sure it// runs for the duration of the button transitionclearTimeout(timer);if(spinner){
timer =setTimeout(function(){
spinner.stop();},1000);}returnthis;// chain},/**
* Toggle the loading state on/off.
*/
toggle:functiontoggle(){returnthis.isLoading()?this.stop():this.start();},/**
* Sets the width of the visual progress bar inside of
* this Ladda button
*
* @param {Number} progress in the range of 0-1
*/
setProgress:functionsetProgress(progress){// Cap it
progress = Math.max(Math.min(progress,1),0);var progressElement = button.querySelector('.ladda-progress');// Remove the progress bar if we're at 0 progressif(progress ===0&& progressElement && progressElement.parentNode){
progressElement.parentNode.removeChild(progressElement);}else{if(!progressElement){
progressElement = document.createElement('div');
progressElement.className ='ladda-progress';
button.appendChild(progressElement);}
progressElement.style.width =(progress ||0)* button.offsetWidth +'px';}},
isLoading:functionisLoading(){return button.hasAttribute('data-loading');},
remove:functionremove(){clearTimeout(timer);
button.disabled =false;
button.removeAttribute('data-loading');if(spinner){
spinner.stop();
spinner =null;}ALL_INSTANCES.splice(ALL_INSTANCES.indexOf(instance),1);}};ALL_INSTANCES.push(instance);return instance;}/**
* Binds the target buttons to automatically enter the
* loading state when clicked.
*
* @param target Either an HTML element or a CSS selector.
* @param options
* - timeout Number of milliseconds to wait before
* automatically cancelling the animation.
* - callback A function to be called with the Ladda
* instance when a target button is clicked.
*/functionbind(target, options){var targets;if(typeof target ==='string'){
targets = document.querySelectorAll(target);}elseif((typeof target ==='undefined'?'undefined':_typeof(target))==='object'){
targets =[target];}else{thrownewError('target must be string or object');}
options = options ||{};for(var i =0; i < targets.length; i++){bindElement(targets[i], options);}}/**
* Stops ALL current loading animations.
*/functionstopAll(){for(var i =0, len =ALL_INSTANCES.length; i < len; i++){ALL_INSTANCES[i].stop();}}/**
* Get the first ancestor node from an element, having a
* certain type.
*
* @param elem An HTML element
* @param type an HTML tag type (uppercased)
*
* @return An HTML element
*/functiongetAncestorOfTagType(elem, type){while(elem.parentNode && elem.tagName !== type){
elem = elem.parentNode;}return type === elem.tagName ? elem : undefined;}functioncreateSpinner(button){var height = button.offsetHeight,
spinnerColor,
spinnerLines;if(height ===0){// We may have an element that is not visible so// we attempt to get the height in a different way
height =parseFloat(window.getComputedStyle(button).height);}// If the button is tall we can afford some paddingif(height >32){
height *=0.8;}// Prefer an explicit height if one is definedif(button.hasAttribute('data-spinner-size')){
height =parseInt(button.getAttribute('data-spinner-size'),10);}// Allow buttons to specify the color of the spinner elementif(button.hasAttribute('data-spinner-color')){
spinnerColor = button.getAttribute('data-spinner-color');}// Allow buttons to specify the number of lines of the spinnerif(button.hasAttribute('data-spinner-lines')){
spinnerLines =parseInt(button.getAttribute('data-spinner-lines'),10);}var radius = height *0.2,
length = radius *0.6,
width = radius <7?2:3;returnnew_spin.Spinner({
color: spinnerColor ||'#fff',
lines: spinnerLines ||12,
radius: radius,
length: length,
width: width,
animation:'ladda-spinner-line-fade',
zIndex:'auto',
top:'auto',
left:'auto',
className:''});}functionwrapContent(node, wrapper){var r = document.createRange();
r.selectNodeContents(node);
r.surroundContents(wrapper);
node.appendChild(wrapper);}functionbindElement(element, options){if(typeof element.addEventListener !=='function'){return;}var instance =create(element);var timeout =-1;
element.addEventListener('click',function(){// If the button belongs to a form, make sure all the// fields in that form are filled outvar valid =true;var form =getAncestorOfTagType(element,'FORM');if(typeof form !=='undefined'&&!form.hasAttribute('novalidate')){// Modern form validationif(typeof form.checkValidity ==='function'){
valid = form.checkValidity();}}if(valid){// This is asynchronous to avoid an issue where disabling// the button prevents forms from submitting
instance.startAfter(1);// Set a loading timeout if one is specifiedif(typeof options.timeout ==='number'){clearTimeout(timeout);
timeout =setTimeout(instance.stop, options.timeout);}// Invoke callbacksif(typeof options.callback ==='function'){
options.callback.apply(null,[instance]);}}},false);}