app/assets/javascripts/pace/pace.js in pace-rails-0.0.5 vs app/assets/javascripts/pace/pace.js in pace-rails-0.0.6
- old
+ new
@@ -1,7 +1,7 @@
(function() {
- var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Events, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, animation, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, firstLoad, getFromDOM, handlePushState, init, intercept, now, options, requestAnimationFrame, result, runAnimation, scalers, sources, uniScaler, _WebSocket, _XDomainRequest, _XMLHttpRequest, _pushState, _replaceState,
+ var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Events, NoTargetError, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, animation, avgAmplitude, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept, handlePushState, init, now, options, requestAnimationFrame, result, runAnimation, scalers, sources, uniScaler, _WebSocket, _XDomainRequest, _XMLHttpRequest, _intercept, _pushState, _ref, _replaceState,
__slice = [].slice,
__hasProp = {}.hasOwnProperty,
__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; },
__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; };
@@ -12,22 +12,24 @@
ghostTime: 250,
maxProgressPerFrame: 10,
easeFactor: 1.25,
startOnPageLoad: true,
restartOnPushState: true,
- restartOnBackboneRoute: true,
+ restartOnRequestAfter: 500,
target: 'body',
elements: {
checkInterval: 100,
selectors: ['body']
},
eventLag: {
- minSamples: 10
+ minSamples: 10,
+ sampleCount: 3,
+ lagThreshold: 3
},
ajax: {
trackMethods: ['GET'],
- trackWebSockets: true
+ trackWebSockets: false
}
};
now = function() {
var _ref;
@@ -89,10 +91,21 @@
}
}
return out;
};
+ avgAmplitude = function(arr) {
+ var count, sum, v, _i, _len;
+ sum = count = 0;
+ for (_i = 0, _len = arr.length; _i < _len; _i++) {
+ v = arr[_i];
+ sum += Math.abs(v);
+ count++;
+ }
+ return sum / count;
+ };
+
getFromDOM = function(key, json) {
var data, e, el;
if (key == null) {
key = 'options';
}
@@ -119,22 +132,39 @@
window.Pace = {};
}
options = Pace.options = extend(defaultOptions, window.paceOptions, getFromDOM());
+ NoTargetError = (function(_super) {
+ __extends(NoTargetError, _super);
+
+ function NoTargetError() {
+ _ref = NoTargetError.__super__.constructor.apply(this, arguments);
+ return _ref;
+ }
+
+ return NoTargetError;
+
+ })(Error);
+
Bar = (function() {
function Bar() {
this.progress = 0;
}
Bar.prototype.getElement = function() {
var targetElement;
if (this.el == null) {
+ targetElement = document.querySelector(options.target);
+ if (!targetElement) {
+ throw new NoTargetError;
+ }
this.el = document.createElement('div');
this.el.className = "pace pace-active";
+ document.body.className = document.body.className.replace('pace-done', '');
+ document.body.className += ' pace-running';
this.el.innerHTML = '<div class="pace-progress">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>';
- targetElement = document.querySelector(options.target);
if (targetElement.firstChild != null) {
targetElement.insertBefore(this.el, targetElement.firstChild);
} else {
targetElement.appendChild(this.el);
}
@@ -144,20 +174,26 @@
Bar.prototype.finish = function() {
var el;
el = this.getElement();
el.className = el.className.replace('pace-active', '');
- return el.className += ' pace-inactive';
+ el.className += ' pace-inactive';
+ document.body.className = document.body.className.replace('pace-running', '');
+ return document.body.className += ' pace-done';
};
Bar.prototype.update = function(prog) {
this.progress = prog;
return this.render();
};
Bar.prototype.destroy = function() {
- this.getElement().parentNode.removeChild(this.getElement());
+ try {
+ this.getElement().parentNode.removeChild(this.getElement());
+ } catch (_error) {
+ NoTargetError = _error;
+ }
return this.el = void 0;
};
Bar.prototype.render = function() {
var el, progressStr;
@@ -165,18 +201,18 @@
return false;
}
el = this.getElement();
el.children[0].style.width = "" + this.progress + "%";
if (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) {
- el.setAttribute('data-progress-text', "" + (this.progress | 0) + "%");
+ el.children[0].setAttribute('data-progress-text', "" + (this.progress | 0) + "%");
if (this.progress >= 100) {
progressStr = '99';
} else {
progressStr = this.progress < 10 ? "0" : "";
progressStr += this.progress | 0;
}
- el.setAttribute('data-progress', "" + progressStr);
+ el.children[0].setAttribute('data-progress', "" + progressStr);
}
return this.lastRenderedProgress = this.progress;
};
Bar.prototype.done = function() {
@@ -191,16 +227,16 @@
function Events() {
this.bindings = {};
}
Events.prototype.trigger = function(name, val) {
- var binding, _i, _len, _ref, _results;
+ var binding, _i, _len, _ref1, _results;
if (this.bindings[name] != null) {
- _ref = this.bindings[name];
+ _ref1 = this.bindings[name];
_results = [];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- binding = _ref[_i];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ binding = _ref1[_i];
_results.push(binding.call(this, val));
}
return _results;
}
};
@@ -250,12 +286,12 @@
RequestIntercept.__super__.constructor.apply(this, arguments);
monitorXHR = function(req) {
var _open;
_open = req.open;
return req.open = function(type, url, async) {
- var _ref;
- if (_ref = (type != null ? type : 'GET').toUpperCase(), __indexOf.call(options.ajax.trackMethods, _ref) >= 0) {
+ var _ref1;
+ if (_ref1 = (type != null ? type : 'GET').toUpperCase(), __indexOf.call(options.ajax.trackMethods, _ref1) >= 0) {
_this.trigger('request', {
type: type,
url: url,
request: req
});
@@ -297,17 +333,57 @@
return RequestIntercept;
})(Events);
- intercept = new RequestIntercept;
+ _intercept = null;
+ getIntercept = function() {
+ if (_intercept == null) {
+ _intercept = new RequestIntercept;
+ }
+ return _intercept;
+ };
+
+ if (options.restartOnRequestAfter !== false) {
+ getIntercept().on('request', function(_arg) {
+ var args, request, type;
+ type = _arg.type, request = _arg.request;
+ if (!Pace.running) {
+ args = arguments;
+ return setTimeout(function() {
+ var source, stillActive, _i, _len, _ref1, _ref2, _results;
+ if (type === 'socket') {
+ stillActive = request.readyState < 2;
+ } else {
+ stillActive = (0 < (_ref1 = request.readyState) && _ref1 < 4);
+ }
+ if (stillActive) {
+ Pace.restart();
+ _ref2 = Pace.sources;
+ _results = [];
+ for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
+ source = _ref2[_i];
+ if (source instanceof AjaxMonitor) {
+ source.watch.apply(source, args);
+ break;
+ } else {
+ _results.push(void 0);
+ }
+ }
+ return _results;
+ }
+ }, options.restartOnRequestAfter);
+ }
+ });
+ }
+
AjaxMonitor = (function() {
function AjaxMonitor() {
var _this = this;
this.elements = [];
- intercept.on('request', function() {
+ getIntercept().on('request', function() {
return _this.watch.apply(_this, arguments);
});
}
AjaxMonitor.prototype.watch = function(_arg) {
@@ -325,11 +401,11 @@
})();
XHRRequestTracker = (function() {
function XHRRequestTracker(request) {
- var event, size, _i, _len, _onreadystatechange, _ref,
+ var event, size, _i, _len, _onreadystatechange, _ref1,
_this = this;
this.progress = 0;
if (window.ProgressEvent != null) {
size = null;
request.addEventListener('progress', function(evt) {
@@ -337,22 +413,22 @@
return _this.progress = 100 * evt.loaded / evt.total;
} else {
return _this.progress = _this.progress + (100 - _this.progress) / 2;
}
});
- _ref = ['load', 'abort', 'timeout', 'error'];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- event = _ref[_i];
+ _ref1 = ['load', 'abort', 'timeout', 'error'];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ event = _ref1[_i];
request.addEventListener(event, function() {
return _this.progress = 100;
});
}
} else {
_onreadystatechange = request.onreadystatechange;
request.onreadystatechange = function() {
- var _ref1;
- if ((_ref1 = request.readyState) === 0 || _ref1 === 4) {
+ var _ref2;
+ if ((_ref2 = request.readyState) === 0 || _ref2 === 4) {
_this.progress = 100;
} else if (request.readyState === 3) {
_this.progress = 50;
}
return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0;
@@ -364,16 +440,16 @@
})();
SocketRequestTracker = (function() {
function SocketRequestTracker(request) {
- var event, _i, _len, _ref,
+ var event, _i, _len, _ref1,
_this = this;
this.progress = 0;
- _ref = ['error', 'open'];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- event = _ref[_i];
+ _ref1 = ['error', 'open'];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ event = _ref1[_i];
request.addEventListener(event, function() {
return _this.progress = 100;
});
}
}
@@ -382,21 +458,21 @@
})();
ElementMonitor = (function() {
function ElementMonitor(options) {
- var selector, _i, _len, _ref;
+ var selector, _i, _len, _ref1;
if (options == null) {
options = {};
}
this.elements = [];
if (options.selectors == null) {
options.selectors = [];
}
- _ref = options.selectors;
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- selector = _ref[_i];
+ _ref1 = options.selectors;
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ selector = _ref1[_i];
this.elements.push(new ElementTracker(selector));
}
}
return ElementMonitor;
@@ -435,13 +511,13 @@
interactive: 50,
complete: 100
};
function DocumentMonitor() {
- var _onreadystatechange, _ref,
+ var _onreadystatechange, _ref1,
_this = this;
- this.progress = (_ref = this.states[document.readyState]) != null ? _ref : 100;
+ this.progress = (_ref1 = this.states[document.readyState]) != null ? _ref1 : 100;
_onreadystatechange = document.onreadystatechange;
document.onreadystatechange = function() {
if (_this.states[document.readyState] != null) {
_this.progress = _this.states[document.readyState];
}
@@ -453,25 +529,32 @@
})();
EventLagMonitor = (function() {
function EventLagMonitor() {
- var avg, last, points,
+ var avg, interval, last, points, samples,
_this = this;
this.progress = 0;
avg = 0;
+ samples = [];
points = 0;
last = now();
- setInterval(function() {
+ interval = setInterval(function() {
var diff;
diff = now() - last - 50;
last = now();
- avg = avg + (diff - avg) / 15;
- if (points++ > options.eventLag.minSamples && Math.abs(avg) < 3) {
- avg = 0;
+ samples.push(diff);
+ if (samples.length > options.eventLag.sampleCount) {
+ samples.shift();
}
- return _this.progress = 100 * (3 / (avg + 3));
+ avg = avgAmplitude(samples);
+ if (++points >= options.eventLag.minSamples && avg < options.eventLag.lagThreshold) {
+ _this.progress = 100;
+ return clearInterval(interval);
+ } else {
+ return _this.progress = 100 * (3 / (avg + 3));
+ }
}, 50);
}
return EventLagMonitor;
@@ -533,10 +616,12 @@
animation = null;
cancelAnimation = null;
+ Pace.running = false;
+
handlePushState = function() {
if (options.restartOnPushState) {
return Pace.restart();
}
};
@@ -555,72 +640,39 @@
handlePushState();
return _replaceState.apply(window.history, arguments);
};
}
- firstLoad = true;
-
- if (options.restartOnBackboneRoute) {
- setTimeout(function() {
- if (window.Backbone == null) {
- return;
- }
- return Backbone.history.on('route', function(router, name) {
- var routeName, rule, _i, _len, _results;
- if (!(rule = options.restartOnBackboneRoute)) {
- return;
- }
- if (firstLoad) {
- firstLoad = false;
- return;
- }
- if (typeof rule === 'object') {
- _results = [];
- for (_i = 0, _len = rule.length; _i < _len; _i++) {
- routeName = rule[_i];
- if (!(routeName === name)) {
- continue;
- }
- Pace.restart();
- break;
- }
- return _results;
- } else {
- return Pace.restart();
- }
- });
- }, 0);
- }
-
SOURCE_KEYS = {
ajax: AjaxMonitor,
elements: ElementMonitor,
document: DocumentMonitor,
eventLag: EventLagMonitor
};
(init = function() {
- var source, type, _i, _j, _len, _len1, _ref, _ref1, _ref2;
+ var source, type, _i, _j, _len, _len1, _ref1, _ref2, _ref3;
Pace.sources = sources = [];
- _ref = ['ajax', 'elements', 'document', 'eventLag'];
- for (_i = 0, _len = _ref.length; _i < _len; _i++) {
- type = _ref[_i];
+ _ref1 = ['ajax', 'elements', 'document', 'eventLag'];
+ for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
+ type = _ref1[_i];
if (options[type] !== false) {
sources.push(new SOURCE_KEYS[type](options[type]));
}
}
- _ref2 = (_ref1 = options.extraSources) != null ? _ref1 : [];
- for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {
- source = _ref2[_j];
+ _ref3 = (_ref2 = options.extraSources) != null ? _ref2 : [];
+ for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
+ source = _ref3[_j];
sources.push(new source(options));
}
Pace.bar = bar = new Bar;
scalers = [];
return uniScaler = new Scaler;
})();
Pace.stop = function() {
+ Pace.running = false;
bar.destroy();
cancelAnimation = true;
if (animation != null) {
if (typeof cancelAnimationFrame === "function") {
cancelAnimationFrame(animation);
@@ -630,25 +682,26 @@
return init();
};
Pace.restart = function() {
Pace.stop();
- return Pace.go();
+ return Pace.start();
};
Pace.go = function() {
+ Pace.running = true;
bar.render();
cancelAnimation = false;
return animation = runAnimation(function(frameTime, enqueueNextFrame) {
- var avg, count, done, element, elements, i, j, remaining, scaler, scalerList, source, start, sum, _i, _j, _len, _len1, _ref;
+ var avg, count, done, element, elements, i, j, remaining, scaler, scalerList, source, start, sum, _i, _j, _len, _len1, _ref1;
remaining = 100 - bar.progress;
count = sum = 0;
done = true;
for (i = _i = 0, _len = sources.length; _i < _len; i = ++_i) {
source = sources[i];
scalerList = scalers[i] != null ? scalers[i] : scalers[i] = [];
- elements = (_ref = source.elements) != null ? _ref : [source];
+ elements = (_ref1 = source.elements) != null ? _ref1 : [source];
for (j = _j = 0, _len1 = elements.length; _j < _len1; j = ++_j) {
element = elements[j];
scaler = scalerList[j] != null ? scalerList[j] : scalerList[j] = new Scaler(element);
done &= scaler.done;
if (scaler.done) {
@@ -662,20 +715,26 @@
bar.update(uniScaler.tick(frameTime, avg));
start = now();
if (bar.done() || done || cancelAnimation) {
bar.update(100);
return setTimeout(function() {
- return bar.finish();
+ bar.finish();
+ return Pace.running = false;
}, Math.max(options.ghostTime, Math.min(options.minTime, now() - start)));
} else {
return enqueueNextFrame();
}
});
};
Pace.start = function(_options) {
extend(options, _options);
- bar.render();
+ Pace.running = true;
+ try {
+ bar.render();
+ } catch (_error) {
+ NoTargetError = _error;
+ }
if (!document.querySelector('.pace')) {
return setTimeout(Pace.start, 50);
} else {
return Pace.go();
}
\ No newline at end of file