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) {