2 var AjaxMonitor
, Bar
, DocumentMonitor
, ElementMonitor
, ElementTracker
, EventLagMonitor
, Evented
, Events
, NoTargetError
, Pace
, RequestIntercept
, SOURCE_KEYS
, Scaler
, SocketRequestTracker
, XHRRequestTracker
, animation
, avgAmplitude
, bar
, cancelAnimation
, cancelAnimationFrame
, defaultOptions
, extend
, extendNative
, getFromDOM
, getIntercept
, handlePushState
, ignoreStack
, init
, now
, options
, requestAnimationFrame
, result
, runAnimation
, scalers
, shouldIgnoreURL
, shouldTrack
, source
, sources
, uniScaler
, _WebSocket
, _XDomainRequest
, _XMLHttpRequest
, _i
, _intercept
, _len
, _pushState
, _ref
, _ref1
, _replaceState
,
4 __hasProp
= {}.hasOwnProperty
,
5 __extends = function(child
, parent
) { for (var key
in parent
) { if (__hasProp
.call(parent
, key
)) child
[key
] = parent
[key
]; } function ctor() { this.constructor = child
; } ctor
.prototype = parent
.prototype; child
.prototype = new ctor(); child
.__super__
= parent
.prototype; return child
; },
6 __indexOf
= [].indexOf
|| function(item
) { for (var i
= 0, l
= this.length
; i
< l
; i
++) { if (i
in this && this[i
] === item
) return i
; } return -1; };
13 maxProgressPerFrame
: 20,
15 startOnPageLoad
: true,
16 restartOnPushState
: true,
17 restartOnRequestAfter
: 500,
29 trackMethods
: ['GET'],
30 trackWebSockets
: true,
37 return (_ref
= typeof performance
!== "undefined" && performance
!== null ? typeof performance
.now
=== "function" ? performance
.now() : void 0 : void 0) != null ? _ref
: +(new Date
);
40 requestAnimationFrame
= window
.requestAnimationFrame
|| window
.mozRequestAnimationFrame
|| window
.webkitRequestAnimationFrame
|| window
.msRequestAnimationFrame
;
42 cancelAnimationFrame
= window
.cancelAnimationFrame
|| window
.mozCancelAnimationFrame
;
44 if (requestAnimationFrame
== null) {
45 requestAnimationFrame = function(fn
) {
46 return setTimeout(fn
, 50);
48 cancelAnimationFrame = function(id
) {
49 return clearTimeout(id
);
53 runAnimation = function(fn
) {
61 return fn(diff
, function() {
62 return requestAnimationFrame(tick
);
65 return setTimeout(tick
, 33 - diff
);
73 obj
= arguments
[0], key
= arguments
[1], args
= 3 <= arguments
.length
? __slice
.call(arguments
, 2) : [];
74 if (typeof obj
[key
] === 'function') {
75 return obj
[key
].apply(obj
, args
);
82 var key
, out
, source
, sources
, val
, _i
, _len
;
83 out
= arguments
[0], sources
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
84 for (_i
= 0, _len
= sources
.length
; _i
< _len
; _i
++) {
88 if (!__hasProp
.call(source
, key
)) continue;
90 if ((out
[key
] != null) && typeof out
[key
] === 'object' && (val
!= null) && typeof val
=== 'object') {
91 extend(out
[key
], val
);
101 avgAmplitude = function(arr
) {
102 var count
, sum
, v
, _i
, _len
;
104 for (_i
= 0, _len
= arr
.length
; _i
< _len
; _i
++) {
112 getFromDOM = function(key
, json
) {
120 el
= document
.querySelector("[data-pace-" + key
+ "]");
124 data
= el
.getAttribute("data-pace-" + key
);
129 return JSON
.parse(data
);
132 return typeof console
!== "undefined" && console
!== null ? console
.error("Error parsing inline pace options", e
) : void 0;
136 Evented
= (function() {
137 function Evented() {}
139 Evented
.prototype.on = function(event
, handler
, ctx
, once
) {
144 if (this.bindings
== null) {
147 if ((_base
= this.bindings
)[event
] == null) {
150 return this.bindings
[event
].push({
157 Evented
.prototype.once = function(event
, handler
, ctx
) {
158 return this.on(event
, handler
, ctx
, true);
161 Evented
.prototype.off = function(event
, handler
) {
162 var i
, _ref
, _results
;
163 if (((_ref
= this.bindings
) != null ? _ref
[event
] : void 0) == null) {
166 if (handler
== null) {
167 return delete this.bindings
[event
];
171 while (i
< this.bindings
[event
].length
) {
172 if (this.bindings
[event
][i
].handler
=== handler
) {
173 _results
.push(this.bindings
[event
].splice(i
, 1));
182 Evented
.prototype.trigger = function() {
183 var args
, ctx
, event
, handler
, i
, once
, _ref
, _ref1
, _results
;
184 event
= arguments
[0], args
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
185 if ((_ref
= this.bindings
) != null ? _ref
[event
] : void 0) {
188 while (i
< this.bindings
[event
].length
) {
189 _ref1
= this.bindings
[event
][i
], handler
= _ref1
.handler
, ctx
= _ref1
.ctx
, once
= _ref1
.once
;
190 handler
.apply(ctx
!= null ? ctx
: this, args
);
192 _results
.push(this.bindings
[event
].splice(i
, 1));
205 Pace
= window
.Pace
|| {};
209 extend(Pace
, Evented
.prototype);
211 options
= Pace
.options
= extend({}, defaultOptions
, window
.paceOptions
, getFromDOM());
213 _ref
= ['ajax', 'document', 'eventLag', 'elements'];
214 for (_i
= 0, _len
= _ref
.length
; _i
< _len
; _i
++) {
216 if (options
[source
] === true) {
217 options
[source
] = defaultOptions
[source
];
221 NoTargetError
= (function(_super
) {
222 __extends(NoTargetError
, _super
);
224 function NoTargetError() {
225 _ref1
= NoTargetError
.__super__
.constructor.apply(this, arguments
);
229 return NoTargetError
;
238 Bar
.prototype.getElement = function() {
240 if (this.el
== null) {
241 targetElement
= document
.querySelector(options
.target
);
242 if (!targetElement
) {
243 throw new NoTargetError
;
245 this.el
= document
.createElement('div');
246 this.el
.className
= "pace pace-active";
247 document
.body
.className
= document
.body
.className
.replace(/pace-done/g, '');
248 document
.body
.className
+= ' pace-running';
249 this.el
.innerHTML
= '<div class="pace-progress">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>';
250 if (targetElement
.firstChild
!= null) {
251 targetElement
.insertBefore(this.el
, targetElement
.firstChild
);
253 targetElement
.appendChild(this.el
);
259 Bar
.prototype.finish = function() {
261 el
= this.getElement();
262 el
.className
= el
.className
.replace('pace-active', '');
263 el
.className
+= ' pace-inactive';
264 document
.body
.className
= document
.body
.className
.replace('pace-running', '');
265 return document
.body
.className
+= ' pace-done';
268 Bar
.prototype.update = function(prog
) {
269 this.progress
= prog
;
270 return this.render();
273 Bar
.prototype.destroy = function() {
275 this.getElement().parentNode
.removeChild(this.getElement());
277 NoTargetError
= _error
;
279 return this.el
= void 0;
282 Bar
.prototype.render = function() {
283 var el
, key
, progressStr
, transform
, _j
, _len1
, _ref2
;
284 if (document
.querySelector(options
.target
) == null) {
287 el
= this.getElement();
288 transform
= "translate3d(" + this.progress
+ "%, 0, 0)";
289 _ref2
= ['webkitTransform', 'msTransform', 'transform'];
290 for (_j
= 0, _len1
= _ref2
.length
; _j
< _len1
; _j
++) {
292 el
.children
[0].style
[key
] = transform
;
294 if (!this.lastRenderedProgress
|| this.lastRenderedProgress
| 0 !== this.progress
| 0) {
295 el
.children
[0].setAttribute('data-progress-text', "" + (this.progress
| 0) + "%");
296 if (this.progress
>= 100) {
299 progressStr
= this.progress
< 10 ? "0" : "";
300 progressStr
+= this.progress
| 0;
302 el
.children
[0].setAttribute('data-progress', "" + progressStr
);
304 return this.lastRenderedProgress
= this.progress
;
307 Bar
.prototype.done = function() {
308 return this.progress
>= 100;
315 Events
= (function() {
320 Events
.prototype.trigger = function(name
, val
) {
321 var binding
, _j
, _len1
, _ref2
, _results
;
322 if (this.bindings
[name
] != null) {
323 _ref2
= this.bindings
[name
];
325 for (_j
= 0, _len1
= _ref2
.length
; _j
< _len1
; _j
++) {
327 _results
.push(binding
.call(this, val
));
333 Events
.prototype.on = function(name
, fn
) {
335 if ((_base
= this.bindings
)[name
] == null) {
338 return this.bindings
[name
].push(fn
);
345 _XMLHttpRequest
= window
.XMLHttpRequest
;
347 _XDomainRequest
= window
.XDomainRequest
;
349 _WebSocket
= window
.WebSocket
;
351 extendNative = function(to
, from) {
352 var e
, key
, _results
;
354 for (key
in from.prototype) {
356 if ((to
[key
] == null) && typeof from[key
] !== 'function') {
357 if (typeof Object
.defineProperty
=== 'function') {
358 _results
.push(Object
.defineProperty(to
, key
, {
360 return from.prototype[key
];
366 _results
.push(to
[key
] = from.prototype[key
]);
369 _results
.push(void 0);
380 Pace
.ignore = function() {
382 fn
= arguments
[0], args
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
383 ignoreStack
.unshift('ignore');
384 ret
= fn
.apply(null, args
);
389 Pace
.track = function() {
391 fn
= arguments
[0], args
= 2 <= arguments
.length
? __slice
.call(arguments
, 1) : [];
392 ignoreStack
.unshift('track');
393 ret
= fn
.apply(null, args
);
398 shouldTrack = function(method
) {
400 if (method
== null) {
403 if (ignoreStack
[0] === 'track') {
406 if (!ignoreStack
.length
&& options
.ajax
) {
407 if (method
=== 'socket' && options
.ajax
.trackWebSockets
) {
409 } else if (_ref2
= method
.toUpperCase(), __indexOf
.call(options
.ajax
.trackMethods
, _ref2
) >= 0) {
416 RequestIntercept
= (function(_super
) {
417 __extends(RequestIntercept
, _super
);
419 function RequestIntercept() {
422 RequestIntercept
.__super__
.constructor.apply(this, arguments
);
423 monitorXHR = function(req
) {
426 return req
.open = function(type
, url
, async
) {
427 if (shouldTrack(type
)) {
428 _this
.trigger('request', {
434 return _open
.apply(req
, arguments
);
437 window
.XMLHttpRequest = function(flags
) {
439 req
= new _XMLHttpRequest(flags
);
444 extendNative(window
.XMLHttpRequest
, _XMLHttpRequest
);
446 if (_XDomainRequest
!= null) {
447 window
.XDomainRequest = function() {
449 req
= new _XDomainRequest
;
454 extendNative(window
.XDomainRequest
, _XDomainRequest
);
457 if ((_WebSocket
!= null) && options
.ajax
.trackWebSockets
) {
458 window
.WebSocket = function(url
, protocols
) {
460 if (protocols
!= null) {
461 req
= new _WebSocket(url
, protocols
);
463 req
= new _WebSocket(url
);
465 if (shouldTrack('socket')) {
466 _this
.trigger('request', {
469 protocols
: protocols
,
476 extendNative(window
.WebSocket
, _WebSocket
);
481 return RequestIntercept
;
487 getIntercept = function() {
488 if (_intercept
== null) {
489 _intercept
= new RequestIntercept
;
494 shouldIgnoreURL = function(url
) {
495 var pattern
, _j
, _len1
, _ref2
;
496 _ref2
= options
.ajax
.ignoreURLs
;
497 for (_j
= 0, _len1
= _ref2
.length
; _j
< _len1
; _j
++) {
499 if (typeof pattern
=== 'string') {
500 if (url
.indexOf(pattern
) !== -1) {
504 if (pattern
.test(url
)) {
512 getIntercept().on('request', function(_arg
) {
513 var after
, args
, request
, type
, url
;
514 type
= _arg
.type
, request
= _arg
.request
, url
= _arg
.url
;
515 if (shouldIgnoreURL(url
)) {
518 if (!Pace
.running
&& (options
.restartOnRequestAfter
!== false || shouldTrack(type
) === 'force')) {
520 after
= options
.restartOnRequestAfter
|| 0;
521 if (typeof after
=== 'boolean') {
524 return setTimeout(function() {
525 var stillActive
, _j
, _len1
, _ref2
, _ref3
, _results
;
526 if (type
=== 'socket') {
527 stillActive
= request
.readyState
< 2;
529 stillActive
= (0 < (_ref2
= request
.readyState
) && _ref2
< 4);
533 _ref3
= Pace
.sources
;
535 for (_j
= 0, _len1
= _ref3
.length
; _j
< _len1
; _j
++) {
537 if (source
instanceof AjaxMonitor
) {
538 source
.watch
.apply(source
, args
);
541 _results
.push(void 0);
550 AjaxMonitor
= (function() {
551 function AjaxMonitor() {
554 getIntercept().on('request', function() {
555 return _this
.watch
.apply(_this
, arguments
);
559 AjaxMonitor
.prototype.watch = function(_arg
) {
560 var request
, tracker
, type
, url
;
561 type
= _arg
.type
, request
= _arg
.request
, url
= _arg
.url
;
562 if (shouldIgnoreURL(url
)) {
565 if (type
=== 'socket') {
566 tracker
= new SocketRequestTracker(request
);
568 tracker
= new XHRRequestTracker(request
);
570 return this.elements
.push(tracker
);
577 XHRRequestTracker
= (function() {
578 function XHRRequestTracker(request
) {
579 var event
, size
, _j
, _len1
, _onreadystatechange
, _ref2
,
582 if (window
.ProgressEvent
!= null) {
584 request
.addEventListener('progress', function(evt
) {
585 if (evt
.lengthComputable
) {
586 return _this
.progress
= 100 * evt
.loaded
/ evt
.total
;
588 return _this
.progress
= _this
.progress
+ (100 - _this
.progress
) / 2;
591 _ref2
= ['load', 'abort', 'timeout', 'error'];
592 for (_j
= 0, _len1
= _ref2
.length
; _j
< _len1
; _j
++) {
594 request
.addEventListener(event
, function() {
595 return _this
.progress
= 100;
599 _onreadystatechange
= request
.onreadystatechange
;
600 request
.onreadystatechange = function() {
602 if ((_ref3
= request
.readyState
) === 0 || _ref3
=== 4) {
603 _this
.progress
= 100;
604 } else if (request
.readyState
=== 3) {
607 return typeof _onreadystatechange
=== "function" ? _onreadystatechange
.apply(null, arguments
) : void 0;
612 return XHRRequestTracker
;
616 SocketRequestTracker
= (function() {
617 function SocketRequestTracker(request
) {
618 var event
, _j
, _len1
, _ref2
,
621 _ref2
= ['error', 'open'];
622 for (_j
= 0, _len1
= _ref2
.length
; _j
< _len1
; _j
++) {
624 request
.addEventListener(event
, function() {
625 return _this
.progress
= 100;
630 return SocketRequestTracker
;
634 ElementMonitor
= (function() {
635 function ElementMonitor(options
) {
636 var selector
, _j
, _len1
, _ref2
;
637 if (options
== null) {
641 if (options
.selectors
== null) {
642 options
.selectors
= [];
644 _ref2
= options
.selectors
;
645 for (_j
= 0, _len1
= _ref2
.length
; _j
< _len1
; _j
++) {
646 selector
= _ref2
[_j
];
647 this.elements
.push(new ElementTracker(selector
));
651 return ElementMonitor
;
655 ElementTracker
= (function() {
656 function ElementTracker(selector
) {
657 this.selector
= selector
;
662 ElementTracker
.prototype.check = function() {
664 if (document
.querySelector(this.selector
)) {
667 return setTimeout((function() {
668 return _this
.check();
669 }), options
.elements
.checkInterval
);
673 ElementTracker
.prototype.done = function() {
674 return this.progress
= 100;
677 return ElementTracker
;
681 DocumentMonitor
= (function() {
682 DocumentMonitor
.prototype.states
= {
688 function DocumentMonitor() {
689 var _onreadystatechange
, _ref2
,
691 this.progress
= (_ref2
= this.states
[document
.readyState
]) != null ? _ref2
: 100;
692 _onreadystatechange
= document
.onreadystatechange
;
693 document
.onreadystatechange = function() {
694 if (_this
.states
[document
.readyState
] != null) {
695 _this
.progress
= _this
.states
[document
.readyState
];
697 return typeof _onreadystatechange
=== "function" ? _onreadystatechange
.apply(null, arguments
) : void 0;
701 return DocumentMonitor
;
705 EventLagMonitor
= (function() {
706 function EventLagMonitor() {
707 var avg
, interval
, last
, points
, samples
,
714 interval
= setInterval(function() {
716 diff
= now() - last
- 50;
719 if (samples
.length
> options
.eventLag
.sampleCount
) {
722 avg
= avgAmplitude(samples
);
723 if (++points
>= options
.eventLag
.minSamples
&& avg
< options
.eventLag
.lagThreshold
) {
724 _this
.progress
= 100;
725 return clearInterval(interval
);
727 return _this
.progress
= 100 * (3 / (avg
+ 3));
732 return EventLagMonitor
;
736 Scaler
= (function() {
737 function Scaler(source
) {
738 this.source
= source
;
739 this.last
= this.sinceLastUpdate
= 0;
740 this.rate
= options
.initialRate
;
742 this.progress
= this.lastProgress
= 0;
743 if (this.source
!= null) {
744 this.progress
= result(this.source
, 'progress');
748 Scaler
.prototype.tick = function(frameTime
, val
) {
751 val
= result(this.source
, 'progress');
756 if (val
=== this.last
) {
757 this.sinceLastUpdate
+= frameTime
;
759 if (this.sinceLastUpdate
) {
760 this.rate
= (val
- this.last
) / this.sinceLastUpdate
;
762 this.catchup
= (val
- this.progress
) / options
.catchupTime
;
763 this.sinceLastUpdate
= 0;
766 if (val
> this.progress
) {
767 this.progress
+= this.catchup
* frameTime
;
769 scaling
= 1 - Math
.pow(this.progress
/ 100, options
.easeFactor
);
770 this.progress
+= scaling
* this.rate
* frameTime
;
771 this.progress
= Math
.min(this.lastProgress
+ options
.maxProgressPerFrame
, this.progress
);
772 this.progress
= Math
.max(0, this.progress
);
773 this.progress
= Math
.min(100, this.progress
);
774 this.lastProgress
= this.progress
;
775 return this.progress
;
792 cancelAnimation
= null;
794 Pace
.running
= false;
796 handlePushState = function() {
797 if (options
.restartOnPushState
) {
798 return Pace
.restart();
802 if (window
.history
.pushState
!= null) {
803 _pushState
= window
.history
.pushState
;
804 window
.history
.pushState = function() {
806 return _pushState
.apply(window
.history
, arguments
);
810 if (window
.history
.replaceState
!= null) {
811 _replaceState
= window
.history
.replaceState
;
812 window
.history
.replaceState = function() {
814 return _replaceState
.apply(window
.history
, arguments
);
820 elements
: ElementMonitor
,
821 document
: DocumentMonitor
,
822 eventLag
: EventLagMonitor
826 var type
, _j
, _k
, _len1
, _len2
, _ref2
, _ref3
, _ref4
;
827 Pace
.sources
= sources
= [];
828 _ref2
= ['ajax', 'elements', 'document', 'eventLag'];
829 for (_j
= 0, _len1
= _ref2
.length
; _j
< _len1
; _j
++) {
831 if (options
[type
] !== false) {
832 sources
.push(new SOURCE_KEYS
[type
](options
[type
]));
835 _ref4
= (_ref3
= options
.extraSources
) != null ? _ref3
: [];
836 for (_k
= 0, _len2
= _ref4
.length
; _k
< _len2
; _k
++) {
838 sources
.push(new source(options
));
840 Pace
.bar
= bar
= new Bar
;
842 return uniScaler
= new Scaler
;
845 Pace
.stop = function() {
846 Pace
.trigger('stop');
847 Pace
.running
= false;
849 cancelAnimation
= true;
850 if (animation
!= null) {
851 if (typeof cancelAnimationFrame
=== "function") {
852 cancelAnimationFrame(animation
);
859 Pace
.restart = function() {
860 Pace
.trigger('restart');
865 Pace
.go = function() {
870 cancelAnimation
= false;
871 return animation
= runAnimation(function(frameTime
, enqueueNextFrame
) {
872 var avg
, count
, done
, element
, elements
, i
, j
, remaining
, scaler
, scalerList
, sum
, _j
, _k
, _len1
, _len2
, _ref2
;
873 remaining
= 100 - bar
.progress
;
876 for (i
= _j
= 0, _len1
= sources
.length
; _j
< _len1
; i
= ++_j
) {
878 scalerList
= scalers
[i
] != null ? scalers
[i
] : scalers
[i
] = [];
879 elements
= (_ref2
= source
.elements
) != null ? _ref2
: [source
];
880 for (j
= _k
= 0, _len2
= elements
.length
; _k
< _len2
; j
= ++_k
) {
881 element
= elements
[j
];
882 scaler
= scalerList
[j
] != null ? scalerList
[j
] : scalerList
[j
] = new Scaler(element
);
888 sum
+= scaler
.tick(frameTime
);
892 bar
.update(uniScaler
.tick(frameTime
, avg
));
893 if (bar
.done() || done
|| cancelAnimation
) {
895 Pace
.trigger('done');
896 return setTimeout(function() {
898 Pace
.running
= false;
899 return Pace
.trigger('hide');
900 }, Math
.max(options
.ghostTime
, Math
.max(options
.minTime
- (now() - start
), 0)));
902 return enqueueNextFrame();
907 Pace
.start = function(_options
) {
908 extend(options
, _options
);
913 NoTargetError
= _error
;
915 if (!document
.querySelector('.pace')) {
916 return setTimeout(Pace
.start
, 50);
918 Pace
.trigger('start');
923 if (typeof define
=== 'function' && define
.amd
) {
924 define(['pace'], function() {
927 } else if (typeof exports
=== 'object') {
928 module
.exports
= Pace
;
930 if (options
.startOnPageLoad
) {