mirror of
				https://github.com/mindoc-org/mindoc.git
				synced 2025-10-25 19:17:05 +08:00 
			
		
		
		
	
		
			
	
	
		
			477 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
		
		
			
		
	
	
			477 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
|   | /* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress | ||
|  |  * @license MIT */ | ||
|  | 
 | ||
|  | ;(function(root, factory) { | ||
|  | 
 | ||
|  |   if (typeof define === 'function' && define.amd) { | ||
|  |     define(factory); | ||
|  |   } else if (typeof exports === 'object') { | ||
|  |     module.exports = factory(); | ||
|  |   } else { | ||
|  |     root.NProgress = factory(); | ||
|  |   } | ||
|  | 
 | ||
|  | })(this, function() { | ||
|  |   var NProgress = {}; | ||
|  | 
 | ||
|  |   NProgress.version = '0.2.0'; | ||
|  | 
 | ||
|  |   var Settings = NProgress.settings = { | ||
|  |     minimum: 0.08, | ||
|  |     easing: 'ease', | ||
|  |     positionUsing: '', | ||
|  |     speed: 200, | ||
|  |     trickle: true, | ||
|  |     trickleRate: 0.02, | ||
|  |     trickleSpeed: 800, | ||
|  |     showSpinner: true, | ||
|  |     barSelector: '[role="bar"]', | ||
|  |     spinnerSelector: '[role="spinner"]', | ||
|  |     parent: 'body', | ||
|  |     template: '<div class="bar" role="bar"><div class="peg"></div></div><div class="spinner" role="spinner"><div class="spinner-icon"></div></div>' | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Updates configuration. | ||
|  |    * | ||
|  |    *     NProgress.configure({ | ||
|  |    *       minimum: 0.1 | ||
|  |    *     }); | ||
|  |    */ | ||
|  |   NProgress.configure = function(options) { | ||
|  |     var key, value; | ||
|  |     for (key in options) { | ||
|  |       value = options[key]; | ||
|  |       if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value; | ||
|  |     } | ||
|  | 
 | ||
|  |     return this; | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Last number. | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.status = null; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`. | ||
|  |    * | ||
|  |    *     NProgress.set(0.4); | ||
|  |    *     NProgress.set(1.0); | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.set = function(n) { | ||
|  |     var started = NProgress.isStarted(); | ||
|  | 
 | ||
|  |     n = clamp(n, Settings.minimum, 1); | ||
|  |     NProgress.status = (n === 1 ? null : n); | ||
|  | 
 | ||
|  |     var progress = NProgress.render(!started), | ||
|  |         bar      = progress.querySelector(Settings.barSelector), | ||
|  |         speed    = Settings.speed, | ||
|  |         ease     = Settings.easing; | ||
|  | 
 | ||
|  |     progress.offsetWidth; /* Repaint */ | ||
|  | 
 | ||
|  |     queue(function(next) { | ||
|  |       // Set positionUsing if it hasn't already been set | ||
|  |       if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS(); | ||
|  | 
 | ||
|  |       // Add transition | ||
|  |       css(bar, barPositionCSS(n, speed, ease)); | ||
|  | 
 | ||
|  |       if (n === 1) { | ||
|  |         // Fade out | ||
|  |         css(progress, {  | ||
|  |           transition: 'none',  | ||
|  |           opacity: 1  | ||
|  |         }); | ||
|  |         progress.offsetWidth; /* Repaint */ | ||
|  | 
 | ||
|  |         setTimeout(function() { | ||
|  |           css(progress, {  | ||
|  |             transition: 'all ' + speed + 'ms linear',  | ||
|  |             opacity: 0  | ||
|  |           }); | ||
|  |           setTimeout(function() { | ||
|  |             NProgress.remove(); | ||
|  |             next(); | ||
|  |           }, speed); | ||
|  |         }, speed); | ||
|  |       } else { | ||
|  |         setTimeout(next, speed); | ||
|  |       } | ||
|  |     }); | ||
|  | 
 | ||
|  |     return this; | ||
|  |   }; | ||
|  | 
 | ||
|  |   NProgress.isStarted = function() { | ||
|  |     return typeof NProgress.status === 'number'; | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Shows the progress bar. | ||
|  |    * This is the same as setting the status to 0%, except that it doesn't go backwards. | ||
|  |    * | ||
|  |    *     NProgress.start(); | ||
|  |    * | ||
|  |    */ | ||
|  |   NProgress.start = function() { | ||
|  |     if (!NProgress.status) NProgress.set(0); | ||
|  | 
 | ||
|  |     var work = function() { | ||
|  |       setTimeout(function() { | ||
|  |         if (!NProgress.status) return; | ||
|  |         NProgress.trickle(); | ||
|  |         work(); | ||
|  |       }, Settings.trickleSpeed); | ||
|  |     }; | ||
|  | 
 | ||
|  |     if (Settings.trickle) work(); | ||
|  | 
 | ||
|  |     return this; | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Hides the progress bar. | ||
|  |    * This is the *sort of* the same as setting the status to 100%, with the | ||
|  |    * difference being `done()` makes some placebo effect of some realistic motion. | ||
|  |    * | ||
|  |    *     NProgress.done(); | ||
|  |    * | ||
|  |    * If `true` is passed, it will show the progress bar even if its hidden. | ||
|  |    * | ||
|  |    *     NProgress.done(true); | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.done = function(force) { | ||
|  |     if (!force && !NProgress.status) return this; | ||
|  | 
 | ||
|  |     return NProgress.inc(0.3 + 0.5 * Math.random()).set(1); | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Increments by a random amount. | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.inc = function(amount) { | ||
|  |     var n = NProgress.status; | ||
|  | 
 | ||
|  |     if (!n) { | ||
|  |       return NProgress.start(); | ||
|  |     } else { | ||
|  |       if (typeof amount !== 'number') { | ||
|  |         amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95); | ||
|  |       } | ||
|  | 
 | ||
|  |       n = clamp(n + amount, 0, 0.994); | ||
|  |       return NProgress.set(n); | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   NProgress.trickle = function() { | ||
|  |     return NProgress.inc(Math.random() * Settings.trickleRate); | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Waits for all supplied jQuery promises and | ||
|  |    * increases the progress as the promises resolve. | ||
|  |    * | ||
|  |    * @param $promise jQUery Promise | ||
|  |    */ | ||
|  |   (function() { | ||
|  |     var initial = 0, current = 0; | ||
|  | 
 | ||
|  |     NProgress.promise = function($promise) { | ||
|  |       if (!$promise || $promise.state() === "resolved") { | ||
|  |         return this; | ||
|  |       } | ||
|  | 
 | ||
|  |       if (current === 0) { | ||
|  |         NProgress.start(); | ||
|  |       } | ||
|  | 
 | ||
|  |       initial++; | ||
|  |       current++; | ||
|  | 
 | ||
|  |       $promise.always(function() { | ||
|  |         current--; | ||
|  |         if (current === 0) { | ||
|  |             initial = 0; | ||
|  |             NProgress.done(); | ||
|  |         } else { | ||
|  |             NProgress.set((initial - current) / initial); | ||
|  |         } | ||
|  |       }); | ||
|  | 
 | ||
|  |       return this; | ||
|  |     }; | ||
|  | 
 | ||
|  |   })(); | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) renders the progress bar markup based on the `template` | ||
|  |    * setting. | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.render = function(fromStart) { | ||
|  |     if (NProgress.isRendered()) return document.getElementById('nprogress'); | ||
|  | 
 | ||
|  |     addClass(document.documentElement, 'nprogress-busy'); | ||
|  |      | ||
|  |     var progress = document.createElement('div'); | ||
|  |     progress.id = 'nprogress'; | ||
|  |     progress.innerHTML = Settings.template; | ||
|  | 
 | ||
|  |     var bar      = progress.querySelector(Settings.barSelector), | ||
|  |         perc     = fromStart ? '-100' : toBarPerc(NProgress.status || 0), | ||
|  |         parent   = document.querySelector(Settings.parent), | ||
|  |         spinner; | ||
|  |      | ||
|  |     css(bar, { | ||
|  |       transition: 'all 0 linear', | ||
|  |       transform: 'translate3d(' + perc + '%,0,0)' | ||
|  |     }); | ||
|  | 
 | ||
|  |     if (!Settings.showSpinner) { | ||
|  |       spinner = progress.querySelector(Settings.spinnerSelector); | ||
|  |       spinner && removeElement(spinner); | ||
|  |     } | ||
|  | 
 | ||
|  |     if (parent != document.body) { | ||
|  |       addClass(parent, 'nprogress-custom-parent'); | ||
|  |     } | ||
|  | 
 | ||
|  |     parent.appendChild(progress); | ||
|  |     return progress; | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Removes the element. Opposite of render(). | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.remove = function() { | ||
|  |     removeClass(document.documentElement, 'nprogress-busy'); | ||
|  |     removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent'); | ||
|  |     var progress = document.getElementById('nprogress'); | ||
|  |     progress && removeElement(progress); | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Checks if the progress bar is rendered. | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.isRendered = function() { | ||
|  |     return !!document.getElementById('nprogress'); | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Determine which positioning CSS rule to use. | ||
|  |    */ | ||
|  | 
 | ||
|  |   NProgress.getPositioningCSS = function() { | ||
|  |     // Sniff on document.body.style | ||
|  |     var bodyStyle = document.body.style; | ||
|  | 
 | ||
|  |     // Sniff prefixes | ||
|  |     var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' : | ||
|  |                        ('MozTransform' in bodyStyle) ? 'Moz' : | ||
|  |                        ('msTransform' in bodyStyle) ? 'ms' : | ||
|  |                        ('OTransform' in bodyStyle) ? 'O' : ''; | ||
|  | 
 | ||
|  |     if (vendorPrefix + 'Perspective' in bodyStyle) { | ||
|  |       // Modern browsers with 3D support, e.g. Webkit, IE10 | ||
|  |       return 'translate3d'; | ||
|  |     } else if (vendorPrefix + 'Transform' in bodyStyle) { | ||
|  |       // Browsers without 3D support, e.g. IE9 | ||
|  |       return 'translate'; | ||
|  |     } else { | ||
|  |       // Browsers without translate() support, e.g. IE7-8 | ||
|  |       return 'margin'; | ||
|  |     } | ||
|  |   }; | ||
|  | 
 | ||
|  |   /** | ||
|  |    * Helpers | ||
|  |    */ | ||
|  | 
 | ||
|  |   function clamp(n, min, max) { | ||
|  |     if (n < min) return min; | ||
|  |     if (n > max) return max; | ||
|  |     return n; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) converts a percentage (`0..1`) to a bar translateX | ||
|  |    * percentage (`-100%..0%`). | ||
|  |    */ | ||
|  | 
 | ||
|  |   function toBarPerc(n) { | ||
|  |     return (-1 + n) * 100; | ||
|  |   } | ||
|  | 
 | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) returns the correct CSS for changing the bar's | ||
|  |    * position given an n percentage, and speed and ease from Settings | ||
|  |    */ | ||
|  | 
 | ||
|  |   function barPositionCSS(n, speed, ease) { | ||
|  |     var barCSS; | ||
|  | 
 | ||
|  |     if (Settings.positionUsing === 'translate3d') { | ||
|  |       barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' }; | ||
|  |     } else if (Settings.positionUsing === 'translate') { | ||
|  |       barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' }; | ||
|  |     } else { | ||
|  |       barCSS = { 'margin-left': toBarPerc(n)+'%' }; | ||
|  |     } | ||
|  | 
 | ||
|  |     barCSS.transition = 'all '+speed+'ms '+ease; | ||
|  | 
 | ||
|  |     return barCSS; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) Queues a function to be executed. | ||
|  |    */ | ||
|  | 
 | ||
|  |   var queue = (function() { | ||
|  |     var pending = []; | ||
|  |      | ||
|  |     function next() { | ||
|  |       var fn = pending.shift(); | ||
|  |       if (fn) { | ||
|  |         fn(next); | ||
|  |       } | ||
|  |     } | ||
|  | 
 | ||
|  |     return function(fn) { | ||
|  |       pending.push(fn); | ||
|  |       if (pending.length == 1) next(); | ||
|  |     }; | ||
|  |   })(); | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) Applies css properties to an element, similar to the jQuery  | ||
|  |    * css method. | ||
|  |    * | ||
|  |    * While this helper does assist with vendor prefixed property names, it  | ||
|  |    * does not perform any manipulation of values prior to setting styles. | ||
|  |    */ | ||
|  | 
 | ||
|  |   var css = (function() { | ||
|  |     var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ], | ||
|  |         cssProps    = {}; | ||
|  | 
 | ||
|  |     function camelCase(string) { | ||
|  |       return string.replace(/^-ms-/, 'ms-').replace(/-([\da-z])/gi, function(match, letter) { | ||
|  |         return letter.toUpperCase(); | ||
|  |       }); | ||
|  |     } | ||
|  | 
 | ||
|  |     function getVendorProp(name) { | ||
|  |       var style = document.body.style; | ||
|  |       if (name in style) return name; | ||
|  | 
 | ||
|  |       var i = cssPrefixes.length, | ||
|  |           capName = name.charAt(0).toUpperCase() + name.slice(1), | ||
|  |           vendorName; | ||
|  |       while (i--) { | ||
|  |         vendorName = cssPrefixes[i] + capName; | ||
|  |         if (vendorName in style) return vendorName; | ||
|  |       } | ||
|  | 
 | ||
|  |       return name; | ||
|  |     } | ||
|  | 
 | ||
|  |     function getStyleProp(name) { | ||
|  |       name = camelCase(name); | ||
|  |       return cssProps[name] || (cssProps[name] = getVendorProp(name)); | ||
|  |     } | ||
|  | 
 | ||
|  |     function applyCss(element, prop, value) { | ||
|  |       prop = getStyleProp(prop); | ||
|  |       element.style[prop] = value; | ||
|  |     } | ||
|  | 
 | ||
|  |     return function(element, properties) { | ||
|  |       var args = arguments, | ||
|  |           prop,  | ||
|  |           value; | ||
|  | 
 | ||
|  |       if (args.length == 2) { | ||
|  |         for (prop in properties) { | ||
|  |           value = properties[prop]; | ||
|  |           if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value); | ||
|  |         } | ||
|  |       } else { | ||
|  |         applyCss(element, args[1], args[2]); | ||
|  |       } | ||
|  |     } | ||
|  |   })(); | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) Determines if an element or space separated list of class names contains a class name. | ||
|  |    */ | ||
|  | 
 | ||
|  |   function hasClass(element, name) { | ||
|  |     var list = typeof element == 'string' ? element : classList(element); | ||
|  |     return list.indexOf(' ' + name + ' ') >= 0; | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) Adds a class to an element. | ||
|  |    */ | ||
|  | 
 | ||
|  |   function addClass(element, name) { | ||
|  |     var oldList = classList(element), | ||
|  |         newList = oldList + name; | ||
|  | 
 | ||
|  |     if (hasClass(oldList, name)) return;  | ||
|  | 
 | ||
|  |     // Trim the opening space. | ||
|  |     element.className = newList.substring(1); | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) Removes a class from an element. | ||
|  |    */ | ||
|  | 
 | ||
|  |   function removeClass(element, name) { | ||
|  |     var oldList = classList(element), | ||
|  |         newList; | ||
|  | 
 | ||
|  |     if (!hasClass(element, name)) return; | ||
|  | 
 | ||
|  |     // Replace the class name. | ||
|  |     newList = oldList.replace(' ' + name + ' ', ' '); | ||
|  | 
 | ||
|  |     // Trim the opening and closing spaces. | ||
|  |     element.className = newList.substring(1, newList.length - 1); | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) Gets a space separated list of the class names on the element.  | ||
|  |    * The list is wrapped with a single space on each end to facilitate finding  | ||
|  |    * matches within the list. | ||
|  |    */ | ||
|  | 
 | ||
|  |   function classList(element) { | ||
|  |     return (' ' + (element.className || '') + ' ').replace(/\s+/gi, ' '); | ||
|  |   } | ||
|  | 
 | ||
|  |   /** | ||
|  |    * (Internal) Removes an element from the DOM. | ||
|  |    */ | ||
|  | 
 | ||
|  |   function removeElement(element) { | ||
|  |     element && element.parentNode && element.parentNode.removeChild(element); | ||
|  |   } | ||
|  | 
 | ||
|  |   return NProgress; | ||
|  | }); | ||
|  | 
 |