forked from OpenPDU/openpdu
first mockup in go
This commit is contained in:
755
static/bower_components/PACE/pace.coffee
vendored
Normal file
755
static/bower_components/PACE/pace.coffee
vendored
Normal file
@@ -0,0 +1,755 @@
|
||||
defaultOptions =
|
||||
# How long should it take for the bar to animate to a new
|
||||
# point after receiving it
|
||||
catchupTime: 100
|
||||
|
||||
# How quickly should the bar be moving before it has any progress
|
||||
# info from a new source in %/ms
|
||||
initialRate: .03
|
||||
|
||||
# What is the minimum amount of time the bar should be on the
|
||||
# screen. Irrespective of this number, the bar will always be on screen for
|
||||
# 33 * (100 / maxProgressPerFrame) + ghostTime ms.
|
||||
minTime: 250
|
||||
|
||||
# What is the minimum amount of time the bar should sit after the last
|
||||
# update before disappearing
|
||||
ghostTime: 100
|
||||
|
||||
# Its easy for a bunch of the bar to be eaten in the first few frames
|
||||
# before we know how much there is to load. This limits how much of
|
||||
# the bar can be used per frame
|
||||
maxProgressPerFrame: 20
|
||||
|
||||
# This tweaks the animation easing
|
||||
easeFactor: 1.25
|
||||
|
||||
# Should pace automatically start when the page is loaded, or should it wait for `start` to
|
||||
# be called? Always false if pace is loaded with AMD or CommonJS.
|
||||
startOnPageLoad: true
|
||||
|
||||
# Should we restart the browser when pushState or replaceState is called? (Generally
|
||||
# means ajax navigation has occured)
|
||||
restartOnPushState: true
|
||||
|
||||
# Should we show the progress bar for every ajax request (not just regular or ajax-y page
|
||||
# navigation)? Set to false to disable.
|
||||
#
|
||||
# If so, how many ms does the request have to be running for before we show the progress?
|
||||
restartOnRequestAfter: 500
|
||||
|
||||
# What element should the pace element be appended to on the page?
|
||||
target: 'body'
|
||||
|
||||
elements:
|
||||
# How frequently in ms should we check for the elements being tested for
|
||||
# using the element monitor?
|
||||
checkInterval: 100
|
||||
|
||||
# What elements should we wait for before deciding the page is fully loaded (not required)
|
||||
selectors: ['body']
|
||||
|
||||
eventLag:
|
||||
# When we first start measuring event lag, not much is going on in the browser yet, so it's
|
||||
# not uncommon for the numbers to be abnormally low for the first few samples. This configures
|
||||
# how many samples we need before we consider a low number to mean completion.
|
||||
minSamples: 10
|
||||
|
||||
# How many samples should we average to decide what the current lag is?
|
||||
sampleCount: 3
|
||||
|
||||
# Above how many ms of lag is the CPU considered busy?
|
||||
lagThreshold: 3
|
||||
|
||||
ajax:
|
||||
# Which HTTP methods should we track?
|
||||
trackMethods: ['GET']
|
||||
|
||||
# Should we track web socket connections?
|
||||
trackWebSockets: true
|
||||
|
||||
# A list of regular expressions or substrings of URLS we should ignore (for both tracking and restarting)
|
||||
ignoreURLs: []
|
||||
|
||||
now = ->
|
||||
performance?.now?() ? +new Date
|
||||
|
||||
requestAnimationFrame = window.requestAnimationFrame or window.mozRequestAnimationFrame or
|
||||
window.webkitRequestAnimationFrame or window.msRequestAnimationFrame
|
||||
|
||||
cancelAnimationFrame = window.cancelAnimationFrame or window.mozCancelAnimationFrame
|
||||
|
||||
if not requestAnimationFrame?
|
||||
requestAnimationFrame = (fn) ->
|
||||
setTimeout fn, 50
|
||||
|
||||
cancelAnimationFrame = (id) ->
|
||||
clearTimeout id
|
||||
|
||||
runAnimation = (fn) ->
|
||||
last = now()
|
||||
tick = ->
|
||||
diff = now() - last
|
||||
|
||||
if diff >= 33
|
||||
# Don't run faster than 30 fps
|
||||
|
||||
last = now()
|
||||
fn diff, ->
|
||||
requestAnimationFrame tick
|
||||
else
|
||||
setTimeout tick, (33 - diff)
|
||||
|
||||
tick()
|
||||
|
||||
result = (obj, key, args...) ->
|
||||
if typeof obj[key] is 'function'
|
||||
obj[key](args...)
|
||||
else
|
||||
obj[key]
|
||||
|
||||
extend = (out, sources...) ->
|
||||
for source in sources when source
|
||||
for own key, val of source
|
||||
if out[key]? and typeof out[key] is 'object' and val? and typeof val is 'object'
|
||||
extend(out[key], val)
|
||||
else
|
||||
out[key] = val
|
||||
out
|
||||
|
||||
avgAmplitude = (arr) ->
|
||||
sum = count = 0
|
||||
for v in arr
|
||||
sum += Math.abs(v)
|
||||
count++
|
||||
|
||||
sum / count
|
||||
|
||||
getFromDOM = (key='options', json=true) ->
|
||||
el = document.querySelector "[data-pace-#{ key }]"
|
||||
|
||||
return unless el
|
||||
|
||||
data = el.getAttribute "data-pace-#{ key }"
|
||||
|
||||
return data if not json
|
||||
|
||||
try
|
||||
return JSON.parse data
|
||||
catch e
|
||||
console?.error "Error parsing inline pace options", e
|
||||
|
||||
class Evented
|
||||
on: (event, handler, ctx, once=false) ->
|
||||
@bindings ?= {}
|
||||
@bindings[event] ?= []
|
||||
@bindings[event].push {handler, ctx, once}
|
||||
|
||||
once: (event, handler, ctx) ->
|
||||
@on(event, handler, ctx, true)
|
||||
|
||||
off: (event, handler) ->
|
||||
return unless @bindings?[event]?
|
||||
|
||||
if not handler?
|
||||
delete @bindings[event]
|
||||
else
|
||||
i = 0
|
||||
while i < @bindings[event].length
|
||||
if @bindings[event][i].handler is handler
|
||||
@bindings[event].splice i, 1
|
||||
else
|
||||
i++
|
||||
|
||||
trigger: (event, args...) ->
|
||||
if @bindings?[event]
|
||||
i = 0
|
||||
while i < @bindings[event].length
|
||||
{handler, ctx, once} = @bindings[event][i]
|
||||
|
||||
handler.apply(ctx ? @, args)
|
||||
|
||||
if once
|
||||
@bindings[event].splice i, 1
|
||||
else
|
||||
i++
|
||||
|
||||
Pace = window.Pace or {}
|
||||
window.Pace = Pace
|
||||
|
||||
extend Pace, Evented::
|
||||
|
||||
options = Pace.options = extend {}, defaultOptions, window.paceOptions, getFromDOM()
|
||||
|
||||
for source in ['ajax', 'document', 'eventLag', 'elements']
|
||||
# true enables them without configuration, so we grab the config from the defaults
|
||||
if options[source] is true
|
||||
options[source] = defaultOptions[source]
|
||||
|
||||
class NoTargetError extends Error
|
||||
|
||||
class Bar
|
||||
constructor: ->
|
||||
@progress = 0
|
||||
|
||||
getElement: ->
|
||||
if not @el?
|
||||
targetElement = document.querySelector options.target
|
||||
|
||||
if not targetElement
|
||||
throw new NoTargetError
|
||||
|
||||
@el = document.createElement 'div'
|
||||
@el.className = "pace pace-active"
|
||||
|
||||
document.body.className = document.body.className.replace /pace-done/g, ''
|
||||
document.body.className += ' pace-running'
|
||||
|
||||
@el.innerHTML = '''
|
||||
<div class="pace-progress">
|
||||
<div class="pace-progress-inner"></div>
|
||||
</div>
|
||||
<div class="pace-activity"></div>
|
||||
'''
|
||||
if targetElement.firstChild?
|
||||
targetElement.insertBefore @el, targetElement.firstChild
|
||||
else
|
||||
targetElement.appendChild @el
|
||||
|
||||
@el
|
||||
|
||||
finish: ->
|
||||
el = @getElement()
|
||||
|
||||
el.className = el.className.replace 'pace-active', ''
|
||||
el.className += ' pace-inactive'
|
||||
|
||||
document.body.className = document.body.className.replace 'pace-running', ''
|
||||
document.body.className += ' pace-done'
|
||||
|
||||
update: (prog) ->
|
||||
@progress = prog
|
||||
|
||||
do @render
|
||||
|
||||
destroy: ->
|
||||
try
|
||||
@getElement().parentNode.removeChild(@getElement())
|
||||
catch NoTargetError
|
||||
|
||||
@el = undefined
|
||||
|
||||
render: ->
|
||||
if not document.querySelector(options.target)?
|
||||
return false
|
||||
|
||||
el = @getElement()
|
||||
|
||||
transform = "translate3d(#{ @progress }%, 0, 0)"
|
||||
for key in ['webkitTransform', 'msTransform', 'transform']
|
||||
el.children[0].style[key] = transform
|
||||
|
||||
if not @lastRenderedProgress or @lastRenderedProgress|0 != @progress|0
|
||||
# The whole-part of the number has changed
|
||||
|
||||
el.children[0].setAttribute 'data-progress-text', "#{ @progress|0 }%"
|
||||
|
||||
if @progress >= 100
|
||||
# We cap it at 99 so we can use prefix-based attribute selectors
|
||||
progressStr = '99'
|
||||
else
|
||||
progressStr = if @progress < 10 then "0" else ""
|
||||
progressStr += @progress|0
|
||||
|
||||
el.children[0].setAttribute 'data-progress', "#{ progressStr }"
|
||||
|
||||
@lastRenderedProgress = @progress
|
||||
|
||||
done: ->
|
||||
@progress >= 100
|
||||
|
||||
class Events
|
||||
constructor: ->
|
||||
@bindings = {}
|
||||
|
||||
trigger: (name, val) ->
|
||||
if @bindings[name]?
|
||||
for binding in @bindings[name]
|
||||
binding.call @, val
|
||||
|
||||
on: (name, fn) ->
|
||||
@bindings[name] ?= []
|
||||
@bindings[name].push fn
|
||||
|
||||
_XMLHttpRequest = window.XMLHttpRequest
|
||||
_XDomainRequest = window.XDomainRequest
|
||||
_WebSocket = window.WebSocket
|
||||
|
||||
extendNative = (to, from) ->
|
||||
for key of from::
|
||||
try
|
||||
if not to[key]? and typeof from[key] isnt 'function'
|
||||
if typeof Object.defineProperty is 'function'
|
||||
Object.defineProperty(to, key, {
|
||||
get: ->
|
||||
return from::[key];
|
||||
,
|
||||
configurable: true,
|
||||
enumerable: true })
|
||||
else
|
||||
to[key] = from::[key]
|
||||
catch e
|
||||
|
||||
ignoreStack = []
|
||||
|
||||
Pace.ignore = (fn, args...) ->
|
||||
ignoreStack.unshift 'ignore'
|
||||
ret = fn(args...)
|
||||
ignoreStack.shift()
|
||||
ret
|
||||
|
||||
Pace.track = (fn, args...) ->
|
||||
ignoreStack.unshift 'track'
|
||||
ret = fn(args...)
|
||||
ignoreStack.shift()
|
||||
ret
|
||||
|
||||
shouldTrack = (method='GET') ->
|
||||
if ignoreStack[0] is 'track'
|
||||
return 'force'
|
||||
|
||||
if not ignoreStack.length and options.ajax
|
||||
if method is 'socket' and options.ajax.trackWebSockets
|
||||
return true
|
||||
else if method.toUpperCase() in options.ajax.trackMethods
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
# We should only ever instantiate one of these
|
||||
class RequestIntercept extends Events
|
||||
constructor: ->
|
||||
super
|
||||
|
||||
monitorXHR = (req) =>
|
||||
_open = req.open
|
||||
req.open = (type, url, async) =>
|
||||
if shouldTrack(type)
|
||||
@trigger 'request', {type, url, request: req}
|
||||
|
||||
_open.apply req, arguments
|
||||
|
||||
window.XMLHttpRequest = (flags) ->
|
||||
req = new _XMLHttpRequest(flags)
|
||||
|
||||
monitorXHR req
|
||||
|
||||
req
|
||||
|
||||
try
|
||||
extendNative window.XMLHttpRequest, _XMLHttpRequest
|
||||
|
||||
if _XDomainRequest?
|
||||
window.XDomainRequest = ->
|
||||
req = new _XDomainRequest
|
||||
|
||||
monitorXHR req
|
||||
|
||||
req
|
||||
|
||||
try
|
||||
extendNative window.XDomainRequest, _XDomainRequest
|
||||
|
||||
if _WebSocket? and options.ajax.trackWebSockets
|
||||
window.WebSocket = (url, protocols) =>
|
||||
if protocols?
|
||||
req = new _WebSocket(url, protocols)
|
||||
else
|
||||
req = new _WebSocket(url)
|
||||
|
||||
if shouldTrack('socket')
|
||||
@trigger 'request', {type: 'socket', url, protocols, request: req}
|
||||
|
||||
req
|
||||
|
||||
try
|
||||
extendNative window.WebSocket, _WebSocket
|
||||
|
||||
_intercept = null
|
||||
getIntercept = ->
|
||||
if not _intercept?
|
||||
_intercept = new RequestIntercept
|
||||
_intercept
|
||||
|
||||
shouldIgnoreURL = (url) ->
|
||||
for pattern in options.ajax.ignoreURLs
|
||||
if typeof pattern is 'string'
|
||||
if url.indexOf(pattern) isnt -1
|
||||
return true
|
||||
|
||||
else
|
||||
if pattern.test(url)
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
# If we want to start the progress bar
|
||||
# on every request, we need to hear the request
|
||||
# and then inject it into the new ajax monitor
|
||||
# start will have created.
|
||||
|
||||
getIntercept().on 'request', ({type, request, url}) ->
|
||||
return if shouldIgnoreURL(url)
|
||||
|
||||
if not Pace.running and (options.restartOnRequestAfter isnt false or shouldTrack(type) is 'force')
|
||||
args = arguments
|
||||
|
||||
after = options.restartOnRequestAfter or 0
|
||||
if typeof after is 'boolean'
|
||||
after = 0
|
||||
|
||||
setTimeout ->
|
||||
if type is 'socket'
|
||||
stillActive = request.readyState < 2
|
||||
else
|
||||
stillActive = 0 < request.readyState < 4
|
||||
|
||||
if stillActive
|
||||
Pace.restart()
|
||||
|
||||
for source in Pace.sources
|
||||
if source instanceof AjaxMonitor
|
||||
source.watch args...
|
||||
break
|
||||
, after
|
||||
|
||||
class AjaxMonitor
|
||||
constructor: ->
|
||||
@elements = []
|
||||
|
||||
getIntercept().on 'request', => @watch arguments...
|
||||
|
||||
watch: ({type, request, url}) ->
|
||||
return if shouldIgnoreURL(url)
|
||||
|
||||
if type is 'socket'
|
||||
tracker = new SocketRequestTracker(request)
|
||||
else
|
||||
tracker = new XHRRequestTracker(request)
|
||||
|
||||
@elements.push tracker
|
||||
|
||||
class XHRRequestTracker
|
||||
constructor: (request) ->
|
||||
@progress = 0
|
||||
|
||||
if window.ProgressEvent?
|
||||
# We're dealing with a modern browser with progress event support
|
||||
|
||||
size = null
|
||||
request.addEventListener 'progress', (evt) =>
|
||||
if evt.lengthComputable
|
||||
@progress = 100 * evt.loaded / evt.total
|
||||
else
|
||||
# If it's chunked encoding, we have no way of knowing the total length of the
|
||||
# response, all we can do is increment the progress with backoff such that we
|
||||
# never hit 100% until it's done.
|
||||
@progress = @progress + (100 - @progress) / 2
|
||||
, false
|
||||
|
||||
for event in ['load', 'abort', 'timeout', 'error']
|
||||
request.addEventListener event, =>
|
||||
@progress = 100
|
||||
, false
|
||||
|
||||
else
|
||||
_onreadystatechange = request.onreadystatechange
|
||||
request.onreadystatechange = =>
|
||||
if request.readyState in [0, 4]
|
||||
@progress = 100
|
||||
else if request.readyState is 3
|
||||
@progress = 50
|
||||
|
||||
_onreadystatechange?(arguments...)
|
||||
|
||||
class SocketRequestTracker
|
||||
constructor: (request) ->
|
||||
@progress = 0
|
||||
|
||||
for event in ['error', 'open']
|
||||
request.addEventListener event, =>
|
||||
@progress = 100
|
||||
, false
|
||||
|
||||
class ElementMonitor
|
||||
constructor: (options={}) ->
|
||||
@elements = []
|
||||
|
||||
options.selectors ?= []
|
||||
for selector in options.selectors
|
||||
@elements.push new ElementTracker selector
|
||||
|
||||
class ElementTracker
|
||||
constructor: (@selector) ->
|
||||
@progress = 0
|
||||
|
||||
@check()
|
||||
|
||||
check: ->
|
||||
if document.querySelector(@selector)
|
||||
@done()
|
||||
else
|
||||
setTimeout (=> @check()),
|
||||
options.elements.checkInterval
|
||||
|
||||
done: ->
|
||||
@progress = 100
|
||||
|
||||
class DocumentMonitor
|
||||
states:
|
||||
loading: 0
|
||||
interactive: 50
|
||||
complete: 100
|
||||
|
||||
constructor: ->
|
||||
@progress = @states[document.readyState] ? 100
|
||||
|
||||
_onreadystatechange = document.onreadystatechange
|
||||
document.onreadystatechange = =>
|
||||
if @states[document.readyState]?
|
||||
@progress = @states[document.readyState]
|
||||
|
||||
_onreadystatechange?(arguments...)
|
||||
|
||||
class EventLagMonitor
|
||||
constructor: ->
|
||||
@progress = 0
|
||||
|
||||
avg = 0
|
||||
|
||||
samples = []
|
||||
|
||||
points = 0
|
||||
last = now()
|
||||
interval = setInterval =>
|
||||
diff = now() - last - 50
|
||||
last = now()
|
||||
|
||||
samples.push diff
|
||||
|
||||
if samples.length > options.eventLag.sampleCount
|
||||
samples.shift()
|
||||
|
||||
avg = avgAmplitude samples
|
||||
|
||||
if ++points >= options.eventLag.minSamples and avg < options.eventLag.lagThreshold
|
||||
@progress = 100
|
||||
|
||||
clearInterval interval
|
||||
else
|
||||
@progress = 100 * (3 / (avg + 3))
|
||||
|
||||
, 50
|
||||
|
||||
class Scaler
|
||||
constructor: (@source) ->
|
||||
@last = @sinceLastUpdate = 0
|
||||
@rate = options.initialRate
|
||||
@catchup = 0
|
||||
@progress = @lastProgress = 0
|
||||
|
||||
if @source?
|
||||
@progress = result(@source, 'progress')
|
||||
|
||||
tick: (frameTime, val) ->
|
||||
val ?= result(@source, 'progress')
|
||||
|
||||
if val >= 100
|
||||
@done = true
|
||||
|
||||
if val == @last
|
||||
@sinceLastUpdate += frameTime
|
||||
else
|
||||
if @sinceLastUpdate
|
||||
@rate = (val - @last) / @sinceLastUpdate
|
||||
|
||||
@catchup = (val - @progress) / options.catchupTime
|
||||
|
||||
@sinceLastUpdate = 0
|
||||
@last = val
|
||||
|
||||
if val > @progress
|
||||
# After we've got a datapoint, we have catchupTime to
|
||||
# get the progress bar to reflect that new data
|
||||
@progress += @catchup * frameTime
|
||||
|
||||
scaling = (1 - Math.pow(@progress / 100, options.easeFactor))
|
||||
|
||||
# Based on the rate of the last update, we preemptively update
|
||||
# the progress bar, scaling it so it can never hit 100% until we
|
||||
# know it's done.
|
||||
@progress += scaling * @rate * frameTime
|
||||
|
||||
@progress = Math.min(@lastProgress + options.maxProgressPerFrame, @progress)
|
||||
|
||||
@progress = Math.max(0, @progress)
|
||||
@progress = Math.min(100, @progress)
|
||||
|
||||
@lastProgress = @progress
|
||||
|
||||
@progress
|
||||
|
||||
sources = null
|
||||
scalers = null
|
||||
bar = null
|
||||
uniScaler = null
|
||||
animation = null
|
||||
cancelAnimation = null
|
||||
Pace.running = false
|
||||
|
||||
handlePushState = ->
|
||||
if options.restartOnPushState
|
||||
Pace.restart()
|
||||
|
||||
# We reset the bar whenever it looks like an ajax navigation has occured.
|
||||
if window.history.pushState?
|
||||
_pushState = window.history.pushState
|
||||
window.history.pushState = ->
|
||||
handlePushState()
|
||||
|
||||
_pushState.apply window.history, arguments
|
||||
|
||||
if window.history.replaceState?
|
||||
_replaceState = window.history.replaceState
|
||||
window.history.replaceState = ->
|
||||
handlePushState()
|
||||
|
||||
_replaceState.apply window.history, arguments
|
||||
|
||||
SOURCE_KEYS =
|
||||
ajax: AjaxMonitor
|
||||
elements: ElementMonitor
|
||||
document: DocumentMonitor
|
||||
eventLag: EventLagMonitor
|
||||
|
||||
do init = ->
|
||||
Pace.sources = sources = []
|
||||
|
||||
for type in ['ajax', 'elements', 'document', 'eventLag']
|
||||
if options[type] isnt false
|
||||
sources.push new SOURCE_KEYS[type](options[type])
|
||||
|
||||
for source in options.extraSources ? []
|
||||
sources.push new source(options)
|
||||
|
||||
Pace.bar = bar = new Bar
|
||||
|
||||
# Each source of progress data has it's own scaler to smooth its output
|
||||
scalers = []
|
||||
|
||||
# We have an extra scaler for the final output to keep things looking nice as we add and
|
||||
# remove sources
|
||||
uniScaler = new Scaler
|
||||
|
||||
Pace.stop = ->
|
||||
Pace.trigger 'stop'
|
||||
Pace.running = false
|
||||
|
||||
bar.destroy()
|
||||
|
||||
# Not all browsers support cancelAnimationFrame
|
||||
cancelAnimation = true
|
||||
|
||||
if animation?
|
||||
cancelAnimationFrame? animation
|
||||
animation = null
|
||||
|
||||
init()
|
||||
|
||||
Pace.restart = ->
|
||||
Pace.trigger 'restart'
|
||||
Pace.stop()
|
||||
Pace.start()
|
||||
|
||||
Pace.go = ->
|
||||
Pace.running = true
|
||||
|
||||
bar.render()
|
||||
|
||||
start = now()
|
||||
|
||||
cancelAnimation = false
|
||||
animation = runAnimation (frameTime, enqueueNextFrame) ->
|
||||
# Every source gives us a progress number from 0 - 100
|
||||
# It's up to us to figure out how to turn that into a smoothly moving bar
|
||||
#
|
||||
# Their progress numbers can only increment. We try to interpolate
|
||||
# between the numbers.
|
||||
|
||||
remaining = 100 - bar.progress
|
||||
|
||||
count = sum = 0
|
||||
done = true
|
||||
# A source is composed of a bunch of elements, each with a raw, unscaled progress
|
||||
for source, i in sources
|
||||
scalerList = scalers[i] ?= []
|
||||
|
||||
elements = source.elements ? [source]
|
||||
|
||||
# Each element is given it's own scaler, which turns its value into something
|
||||
# smoothed for display
|
||||
for element, j in elements
|
||||
scaler = scalerList[j] ?= new Scaler element
|
||||
|
||||
done &= scaler.done
|
||||
|
||||
continue if scaler.done
|
||||
|
||||
count++
|
||||
sum += scaler.tick(frameTime)
|
||||
|
||||
avg = sum / count
|
||||
|
||||
bar.update uniScaler.tick(frameTime, avg)
|
||||
|
||||
if bar.done() or done or cancelAnimation
|
||||
bar.update 100
|
||||
|
||||
Pace.trigger 'done'
|
||||
|
||||
setTimeout ->
|
||||
bar.finish()
|
||||
|
||||
Pace.running = false
|
||||
|
||||
Pace.trigger 'hide'
|
||||
, Math.max(options.ghostTime, Math.max(options.minTime - (now() - start), 0))
|
||||
else
|
||||
enqueueNextFrame()
|
||||
|
||||
Pace.start = (_options) ->
|
||||
extend options, _options
|
||||
|
||||
Pace.running = true
|
||||
|
||||
try
|
||||
bar.render()
|
||||
catch NoTargetError
|
||||
|
||||
# It's usually possible to render a bit before the document declares itself ready
|
||||
if not document.querySelector('.pace')
|
||||
setTimeout Pace.start, 50
|
||||
else
|
||||
Pace.trigger 'start'
|
||||
Pace.go()
|
||||
|
||||
if typeof define is 'function' and define.amd
|
||||
# AMD
|
||||
define ['pace'], -> Pace
|
||||
else if typeof exports is 'object'
|
||||
# CommonJS
|
||||
module.exports = Pace
|
||||
else
|
||||
# Global
|
||||
if options.startOnPageLoad
|
||||
Pace.start()
|
||||
Reference in New Issue
Block a user