You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

pace.js 32KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973
  1. (function () {
  2. var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Evented, Events,
  3. NoTargetError, Pace, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, _WebSocket,
  4. _XDomainRequest, _XMLHttpRequest, _intercept, _pushState, _replaceState, animation, avgAmplitude, bar,
  5. cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept,
  6. handlePushState, ignoreStack, init, k, len, now, options, ref, requestAnimationFrame, result, runAnimation,
  7. scalers, shouldIgnoreURL, shouldTrack, source, sources, uniScaler,
  8. slice = [].slice,
  9. hasProp = {}.hasOwnProperty,
  10. extend1 = function (child, parent) {
  11. for (var key in parent) {
  12. if (hasProp.call(parent, key)) child[key] = parent[key];
  13. }
  14. function ctor() {
  15. this.constructor = child;
  16. }
  17. ctor.prototype = parent.prototype;
  18. child.prototype = new ctor();
  19. child.__super__ = parent.prototype;
  20. return child;
  21. },
  22. indexOf = [].indexOf || function (item) {
  23. for (var i = 0, l = this.length; i < l; i++) {
  24. if (i in this && this[i] === item) return i;
  25. }
  26. return -1;
  27. };
  28. defaultOptions = {
  29. catchupTime: 100,
  30. initialRate: .03,
  31. minTime: 250,
  32. ghostTime: 100,
  33. maxProgressPerFrame: 20,
  34. easeFactor: 1.25,
  35. startOnPageLoad: true,
  36. restartOnPushState: true,
  37. restartOnRequestAfter: 500,
  38. target: 'body',
  39. elements: {
  40. checkInterval: 100,
  41. selectors: ['body']
  42. },
  43. eventLag: {
  44. minSamples: 10,
  45. sampleCount: 3,
  46. lagThreshold: 3
  47. },
  48. ajax: {
  49. trackMethods: ['GET'],
  50. trackWebSockets: true,
  51. ignoreURLs: []
  52. }
  53. };
  54. now = function () {
  55. var ref;
  56. return (ref = typeof performance !== "undefined" && performance !== null ? typeof performance.now === "function" ? performance.now() : void 0 : void 0) != null ? ref : +(new Date);
  57. };
  58. requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
  59. cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;
  60. if (requestAnimationFrame == null) {
  61. requestAnimationFrame = function (fn) {
  62. return setTimeout(fn, 50);
  63. };
  64. cancelAnimationFrame = function (id) {
  65. return clearTimeout(id);
  66. };
  67. }
  68. runAnimation = function (fn) {
  69. var last, tick;
  70. last = now();
  71. tick = function () {
  72. var diff;
  73. diff = now() - last;
  74. if (diff >= 33) {
  75. last = now();
  76. return fn(diff, function () {
  77. return requestAnimationFrame(tick);
  78. });
  79. } else {
  80. return setTimeout(tick, 33 - diff);
  81. }
  82. };
  83. return tick();
  84. };
  85. result = function () {
  86. var args, key, obj;
  87. obj = arguments[0], key = arguments[1], args = 3 <= arguments.length ? slice.call(arguments, 2) : [];
  88. if (typeof obj[key] === 'function') {
  89. return obj[key].apply(obj, args);
  90. } else {
  91. return obj[key];
  92. }
  93. };
  94. extend = function () {
  95. var k, key, len, out, source, sources, val;
  96. out = arguments[0], sources = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  97. for (k = 0, len = sources.length; k < len; k++) {
  98. source = sources[k];
  99. if (source) {
  100. for (key in source) {
  101. if (!hasProp.call(source, key)) continue;
  102. val = source[key];
  103. if ((out[key] != null) && typeof out[key] === 'object' && (val != null) && typeof val === 'object') {
  104. extend(out[key], val);
  105. } else {
  106. out[key] = val;
  107. }
  108. }
  109. }
  110. }
  111. return out;
  112. };
  113. avgAmplitude = function (arr) {
  114. var count, k, len, sum, v;
  115. sum = count = 0;
  116. for (k = 0, len = arr.length; k < len; k++) {
  117. v = arr[k];
  118. sum += Math.abs(v);
  119. count++;
  120. }
  121. return sum / count;
  122. };
  123. getFromDOM = function (key, json) {
  124. var data, e, el, error;
  125. if (key == null) {
  126. key = 'options';
  127. }
  128. if (json == null) {
  129. json = true;
  130. }
  131. el = document.querySelector("[data-pace-" + key + "]");
  132. if (!el) {
  133. return;
  134. }
  135. data = el.getAttribute("data-pace-" + key);
  136. if (!json) {
  137. return data;
  138. }
  139. try {
  140. return JSON.parse(data);
  141. } catch (error) {
  142. e = error;
  143. return typeof console !== "undefined" && console !== null ? console.error("Error parsing inline pace options", e) : void 0;
  144. }
  145. };
  146. Evented = (function () {
  147. function Evented() {
  148. }
  149. Evented.prototype.on = function (event, handler, ctx, once) {
  150. var base;
  151. if (once == null) {
  152. once = false;
  153. }
  154. if (this.bindings == null) {
  155. this.bindings = {};
  156. }
  157. if ((base = this.bindings)[event] == null) {
  158. base[event] = [];
  159. }
  160. return this.bindings[event].push({
  161. handler: handler,
  162. ctx: ctx,
  163. once: once
  164. });
  165. };
  166. Evented.prototype.once = function (event, handler, ctx) {
  167. return this.on(event, handler, ctx, true);
  168. };
  169. Evented.prototype.off = function (event, handler) {
  170. var i, ref, results;
  171. if (((ref = this.bindings) != null ? ref[event] : void 0) == null) {
  172. return;
  173. }
  174. if (handler == null) {
  175. return delete this.bindings[event];
  176. } else {
  177. i = 0;
  178. results = [];
  179. while (i < this.bindings[event].length) {
  180. if (this.bindings[event][i].handler === handler) {
  181. results.push(this.bindings[event].splice(i, 1));
  182. } else {
  183. results.push(i++);
  184. }
  185. }
  186. return results;
  187. }
  188. };
  189. Evented.prototype.trigger = function () {
  190. var args, ctx, event, handler, i, once, ref, ref1, results;
  191. event = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  192. if ((ref = this.bindings) != null ? ref[event] : void 0) {
  193. i = 0;
  194. results = [];
  195. while (i < this.bindings[event].length) {
  196. ref1 = this.bindings[event][i], handler = ref1.handler, ctx = ref1.ctx, once = ref1.once;
  197. handler.apply(ctx != null ? ctx : this, args);
  198. if (once) {
  199. results.push(this.bindings[event].splice(i, 1));
  200. } else {
  201. results.push(i++);
  202. }
  203. }
  204. return results;
  205. }
  206. };
  207. return Evented;
  208. })();
  209. Pace = window.Pace || {};
  210. window.Pace = Pace;
  211. extend(Pace, Evented.prototype);
  212. options = Pace.options = extend({}, defaultOptions, window.paceOptions, getFromDOM());
  213. ref = ['ajax', 'document', 'eventLag', 'elements'];
  214. for (k = 0, len = ref.length; k < len; k++) {
  215. source = ref[k];
  216. if (options[source] === true) {
  217. options[source] = defaultOptions[source];
  218. }
  219. }
  220. NoTargetError = (function (superClass) {
  221. extend1(NoTargetError, superClass);
  222. function NoTargetError() {
  223. return NoTargetError.__super__.constructor.apply(this, arguments);
  224. }
  225. return NoTargetError;
  226. })(Error);
  227. Bar = (function () {
  228. function Bar() {
  229. this.progress = 0;
  230. }
  231. Bar.prototype.getElement = function () {
  232. var targetElement;
  233. if (this.el == null) {
  234. targetElement = document.querySelector(options.target);
  235. if (!targetElement) {
  236. throw new NoTargetError;
  237. }
  238. this.el = document.createElement('div');
  239. this.el.classList.add('pace');
  240. this.el.classList.add('pace-active');
  241. document.body.classList.remove('pace-done');
  242. document.body.classList.add('pace-running');
  243. this.el.innerHTML = '<div class="pace-progress">\n <div class="pace-progress-inner"></div>\n</div>\n<div class="pace-activity"></div>';
  244. if (targetElement.firstChild != null) {
  245. targetElement.insertBefore(this.el, targetElement.firstChild);
  246. } else {
  247. targetElement.appendChild(this.el);
  248. }
  249. }
  250. return this.el;
  251. };
  252. Bar.prototype.finish = function () {
  253. var el;
  254. el = this.getElement();
  255. el.classList.remove('pace-active');
  256. el.classList.add('pace-inactive');
  257. document.body.classList.remove('pace-running');
  258. return document.body.classList.add('pace-done');
  259. };
  260. Bar.prototype.update = function (prog) {
  261. this.progress = prog;
  262. return this.render();
  263. };
  264. Bar.prototype.destroy = function () {
  265. var error;
  266. try {
  267. this.getElement().parentNode.removeChild(this.getElement());
  268. } catch (error) {
  269. NoTargetError = error;
  270. }
  271. return this.el = void 0;
  272. };
  273. Bar.prototype.render = function () {
  274. var el, key, l, len1, progressStr, ref1, transform;
  275. if (document.querySelector(options.target) == null) {
  276. return false;
  277. }
  278. el = this.getElement();
  279. transform = "translate3d(" + this.progress + "%, 0, 0)";
  280. ref1 = ['webkitTransform', 'msTransform', 'transform'];
  281. for (l = 0, len1 = ref1.length; l < len1; l++) {
  282. key = ref1[l];
  283. el.children[0].style[key] = transform;
  284. }
  285. if (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) {
  286. el.children[0].setAttribute('data-progress-text', (this.progress | 0) + "%");
  287. if (this.progress >= 100) {
  288. progressStr = '99';
  289. } else {
  290. progressStr = this.progress < 10 ? "0" : "";
  291. progressStr += this.progress | 0;
  292. }
  293. el.children[0].setAttribute('data-progress', "" + progressStr);
  294. }
  295. return this.lastRenderedProgress = this.progress;
  296. };
  297. Bar.prototype.done = function () {
  298. return this.progress >= 100;
  299. };
  300. return Bar;
  301. })();
  302. Events = (function () {
  303. function Events() {
  304. this.bindings = {};
  305. }
  306. Events.prototype.trigger = function (name, val) {
  307. var binding, l, len1, ref1, results;
  308. if (this.bindings[name] != null) {
  309. ref1 = this.bindings[name];
  310. results = [];
  311. for (l = 0, len1 = ref1.length; l < len1; l++) {
  312. binding = ref1[l];
  313. results.push(binding.call(this, val));
  314. }
  315. return results;
  316. }
  317. };
  318. Events.prototype.on = function (name, fn) {
  319. var base;
  320. if ((base = this.bindings)[name] == null) {
  321. base[name] = [];
  322. }
  323. return this.bindings[name].push(fn);
  324. };
  325. return Events;
  326. })();
  327. _XMLHttpRequest = window.XMLHttpRequest;
  328. _XDomainRequest = window.XDomainRequest;
  329. _WebSocket = window.WebSocket;
  330. extendNative = function (to, from) {
  331. var e, error, key, results;
  332. results = [];
  333. for (key in from.prototype) {
  334. try {
  335. if ((to[key] == null) && typeof from[key] !== 'function') {
  336. if (typeof Object.defineProperty === 'function') {
  337. results.push(Object.defineProperty(to, key, {
  338. get: function () {
  339. return from.prototype[key];
  340. },
  341. configurable: true,
  342. enumerable: true
  343. }));
  344. } else {
  345. results.push(to[key] = from.prototype[key]);
  346. }
  347. } else {
  348. results.push(void 0);
  349. }
  350. } catch (error) {
  351. e = error;
  352. }
  353. }
  354. return results;
  355. };
  356. ignoreStack = [];
  357. Pace.ignore = function () {
  358. var args, fn, ret;
  359. fn = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  360. ignoreStack.unshift('ignore');
  361. ret = fn.apply(null, args);
  362. ignoreStack.shift();
  363. return ret;
  364. };
  365. Pace.track = function () {
  366. var args, fn, ret;
  367. fn = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  368. ignoreStack.unshift('track');
  369. ret = fn.apply(null, args);
  370. ignoreStack.shift();
  371. return ret;
  372. };
  373. shouldTrack = function (method) {
  374. var ref1;
  375. if (method == null) {
  376. method = 'GET';
  377. }
  378. if (ignoreStack[0] === 'track') {
  379. return 'force';
  380. }
  381. if (!ignoreStack.length && options.ajax) {
  382. if (method === 'socket' && options.ajax.trackWebSockets) {
  383. return true;
  384. } else if (ref1 = method.toUpperCase(), indexOf.call(options.ajax.trackMethods, ref1) >= 0) {
  385. return true;
  386. }
  387. }
  388. return false;
  389. };
  390. RequestIntercept = (function (superClass) {
  391. extend1(RequestIntercept, superClass);
  392. function RequestIntercept() {
  393. var monitorXHR;
  394. RequestIntercept.__super__.constructor.apply(this, arguments);
  395. monitorXHR = (function (_this) {
  396. return function (req) {
  397. var _open;
  398. _open = req.open;
  399. return req.open = function (type, url, async) {
  400. if (shouldTrack(type)) {
  401. _this.trigger('request', {
  402. type: type,
  403. url: url,
  404. request: req
  405. });
  406. }
  407. return _open.apply(req, arguments);
  408. };
  409. };
  410. })(this);
  411. window.XMLHttpRequest = function (flags) {
  412. var req;
  413. req = new _XMLHttpRequest(flags);
  414. monitorXHR(req);
  415. return req;
  416. };
  417. try {
  418. extendNative(window.XMLHttpRequest, _XMLHttpRequest);
  419. } catch (undefined) {
  420. }
  421. if (_XDomainRequest != null) {
  422. window.XDomainRequest = function () {
  423. var req;
  424. req = new _XDomainRequest;
  425. monitorXHR(req);
  426. return req;
  427. };
  428. try {
  429. extendNative(window.XDomainRequest, _XDomainRequest);
  430. } catch (undefined) {
  431. }
  432. }
  433. if ((_WebSocket != null) && options.ajax.trackWebSockets) {
  434. window.WebSocket = (function (_this) {
  435. return function (url, protocols) {
  436. var req;
  437. if (protocols != null) {
  438. req = new _WebSocket(url, protocols);
  439. } else {
  440. req = new _WebSocket(url);
  441. }
  442. if (shouldTrack('socket')) {
  443. _this.trigger('request', {
  444. type: 'socket',
  445. url: url,
  446. protocols: protocols,
  447. request: req
  448. });
  449. }
  450. return req;
  451. };
  452. })(this);
  453. try {
  454. extendNative(window.WebSocket, _WebSocket);
  455. } catch (undefined) {
  456. }
  457. }
  458. }
  459. return RequestIntercept;
  460. })(Events);
  461. _intercept = null;
  462. getIntercept = function () {
  463. if (_intercept == null) {
  464. _intercept = new RequestIntercept;
  465. }
  466. return _intercept;
  467. };
  468. shouldIgnoreURL = function (url) {
  469. var l, len1, pattern, ref1;
  470. ref1 = options.ajax.ignoreURLs;
  471. for (l = 0, len1 = ref1.length; l < len1; l++) {
  472. pattern = ref1[l];
  473. if (typeof pattern === 'string') {
  474. if (url.indexOf(pattern) !== -1) {
  475. return true;
  476. }
  477. } else {
  478. if (pattern.test(url)) {
  479. return true;
  480. }
  481. }
  482. }
  483. return false;
  484. };
  485. getIntercept().on('request', function (arg) {
  486. var after, args, request, type, url;
  487. type = arg.type, request = arg.request, url = arg.url;
  488. if (shouldIgnoreURL(url)) {
  489. return;
  490. }
  491. if (!Pace.running && (options.restartOnRequestAfter !== false || shouldTrack(type) === 'force')) {
  492. args = arguments;
  493. after = options.restartOnRequestAfter || 0;
  494. if (typeof after === 'boolean') {
  495. after = 0;
  496. }
  497. return setTimeout(function () {
  498. var l, len1, ref1, ref2, results, stillActive;
  499. if (type === 'socket') {
  500. stillActive = request.readyState < 2;
  501. } else {
  502. stillActive = (0 < (ref1 = request.readyState) && ref1 < 4);
  503. }
  504. if (stillActive) {
  505. Pace.restart();
  506. ref2 = Pace.sources;
  507. results = [];
  508. for (l = 0, len1 = ref2.length; l < len1; l++) {
  509. source = ref2[l];
  510. if (source instanceof AjaxMonitor) {
  511. source.watch.apply(source, args);
  512. break;
  513. } else {
  514. results.push(void 0);
  515. }
  516. }
  517. return results;
  518. }
  519. }, after);
  520. }
  521. });
  522. AjaxMonitor = (function () {
  523. function AjaxMonitor() {
  524. this.elements = [];
  525. getIntercept().on('request', (function (_this) {
  526. return function () {
  527. return _this.watch.apply(_this, arguments);
  528. };
  529. })(this));
  530. }
  531. AjaxMonitor.prototype.watch = function (arg) {
  532. var request, tracker, type, url;
  533. type = arg.type, request = arg.request, url = arg.url;
  534. if (shouldIgnoreURL(url)) {
  535. return;
  536. }
  537. if (type === 'socket') {
  538. tracker = new SocketRequestTracker(request);
  539. } else {
  540. tracker = new XHRRequestTracker(request);
  541. }
  542. return this.elements.push(tracker);
  543. };
  544. return AjaxMonitor;
  545. })();
  546. XHRRequestTracker = (function () {
  547. function XHRRequestTracker(request) {
  548. var _onreadystatechange, event, l, len1, ref1, size;
  549. this.progress = 0;
  550. if (window.ProgressEvent != null) {
  551. size = null;
  552. request.addEventListener('progress', (function (_this) {
  553. return function (evt) {
  554. if (evt.lengthComputable) {
  555. return _this.progress = 100 * evt.loaded / evt.total;
  556. } else {
  557. return _this.progress = _this.progress + (100 - _this.progress) / 2;
  558. }
  559. };
  560. })(this), false);
  561. ref1 = ['load', 'abort', 'timeout', 'error'];
  562. for (l = 0, len1 = ref1.length; l < len1; l++) {
  563. event = ref1[l];
  564. request.addEventListener(event, (function (_this) {
  565. return function () {
  566. return _this.progress = 100;
  567. };
  568. })(this), false);
  569. }
  570. } else {
  571. _onreadystatechange = request.onreadystatechange;
  572. request.onreadystatechange = (function (_this) {
  573. return function () {
  574. var ref2;
  575. if ((ref2 = request.readyState) === 0 || ref2 === 4) {
  576. _this.progress = 100;
  577. } else if (request.readyState === 3) {
  578. _this.progress = 50;
  579. }
  580. return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0;
  581. };
  582. })(this);
  583. }
  584. }
  585. return XHRRequestTracker;
  586. })();
  587. SocketRequestTracker = (function () {
  588. function SocketRequestTracker(request) {
  589. var event, l, len1, ref1;
  590. this.progress = 0;
  591. ref1 = ['error', 'open'];
  592. for (l = 0, len1 = ref1.length; l < len1; l++) {
  593. event = ref1[l];
  594. request.addEventListener(event, (function (_this) {
  595. return function () {
  596. return _this.progress = 100;
  597. };
  598. })(this), false);
  599. }
  600. }
  601. return SocketRequestTracker;
  602. })();
  603. ElementMonitor = (function () {
  604. function ElementMonitor(options) {
  605. var l, len1, ref1, selector;
  606. if (options == null) {
  607. options = {};
  608. }
  609. this.elements = [];
  610. if (options.selectors == null) {
  611. options.selectors = [];
  612. }
  613. ref1 = options.selectors;
  614. for (l = 0, len1 = ref1.length; l < len1; l++) {
  615. selector = ref1[l];
  616. this.elements.push(new ElementTracker(selector));
  617. }
  618. }
  619. return ElementMonitor;
  620. })();
  621. ElementTracker = (function () {
  622. function ElementTracker(selector1) {
  623. this.selector = selector1;
  624. this.progress = 0;
  625. this.check();
  626. }
  627. ElementTracker.prototype.check = function () {
  628. if (document.querySelector(this.selector)) {
  629. return this.done();
  630. } else {
  631. return setTimeout(((function (_this) {
  632. return function () {
  633. return _this.check();
  634. };
  635. })(this)), options.elements.checkInterval);
  636. }
  637. };
  638. ElementTracker.prototype.done = function () {
  639. return this.progress = 100;
  640. };
  641. return ElementTracker;
  642. })();
  643. DocumentMonitor = (function () {
  644. DocumentMonitor.prototype.states = {
  645. loading: 0,
  646. interactive: 50,
  647. complete: 100
  648. };
  649. function DocumentMonitor() {
  650. var _onreadystatechange, ref1;
  651. this.progress = (ref1 = this.states[document.readyState]) != null ? ref1 : 100;
  652. _onreadystatechange = document.onreadystatechange;
  653. document.onreadystatechange = (function (_this) {
  654. return function () {
  655. if (_this.states[document.readyState] != null) {
  656. _this.progress = _this.states[document.readyState];
  657. }
  658. return typeof _onreadystatechange === "function" ? _onreadystatechange.apply(null, arguments) : void 0;
  659. };
  660. })(this);
  661. }
  662. return DocumentMonitor;
  663. })();
  664. EventLagMonitor = (function () {
  665. function EventLagMonitor() {
  666. var avg, interval, last, points, samples;
  667. this.progress = 0;
  668. avg = 0;
  669. samples = [];
  670. points = 0;
  671. last = now();
  672. interval = setInterval((function (_this) {
  673. return function () {
  674. var diff;
  675. diff = now() - last - 50;
  676. last = now();
  677. samples.push(diff);
  678. if (samples.length > options.eventLag.sampleCount) {
  679. samples.shift();
  680. }
  681. avg = avgAmplitude(samples);
  682. if (++points >= options.eventLag.minSamples && avg < options.eventLag.lagThreshold) {
  683. _this.progress = 100;
  684. return clearInterval(interval);
  685. } else {
  686. return _this.progress = 100 * (3 / (avg + 3));
  687. }
  688. };
  689. })(this), 50);
  690. }
  691. return EventLagMonitor;
  692. })();
  693. Scaler = (function () {
  694. function Scaler(source1) {
  695. this.source = source1;
  696. this.last = this.sinceLastUpdate = 0;
  697. this.rate = options.initialRate;
  698. this.catchup = 0;
  699. this.progress = this.lastProgress = 0;
  700. if (this.source != null) {
  701. this.progress = result(this.source, 'progress');
  702. }
  703. }
  704. Scaler.prototype.tick = function (frameTime, val) {
  705. var scaling;
  706. if (val == null) {
  707. val = result(this.source, 'progress');
  708. }
  709. if (val >= 100) {
  710. this.done = true;
  711. }
  712. if (val === this.last) {
  713. this.sinceLastUpdate += frameTime;
  714. } else {
  715. if (this.sinceLastUpdate) {
  716. this.rate = (val - this.last) / this.sinceLastUpdate;
  717. }
  718. this.catchup = (val - this.progress) / options.catchupTime;
  719. this.sinceLastUpdate = 0;
  720. this.last = val;
  721. }
  722. if (val > this.progress) {
  723. this.progress += this.catchup * frameTime;
  724. }
  725. scaling = 1 - Math.pow(this.progress / 100, options.easeFactor);
  726. this.progress += scaling * this.rate * frameTime;
  727. this.progress = Math.min(this.lastProgress + options.maxProgressPerFrame, this.progress);
  728. this.progress = Math.max(0, this.progress);
  729. this.progress = Math.min(100, this.progress);
  730. this.lastProgress = this.progress;
  731. return this.progress;
  732. };
  733. return Scaler;
  734. })();
  735. sources = null;
  736. scalers = null;
  737. bar = null;
  738. uniScaler = null;
  739. animation = null;
  740. cancelAnimation = null;
  741. Pace.running = false;
  742. handlePushState = function () {
  743. if (options.restartOnPushState) {
  744. return Pace.restart();
  745. }
  746. };
  747. if (window.history.pushState != null) {
  748. _pushState = window.history.pushState;
  749. window.history.pushState = function () {
  750. handlePushState();
  751. return _pushState.apply(window.history, arguments);
  752. };
  753. }
  754. if (window.history.replaceState != null) {
  755. _replaceState = window.history.replaceState;
  756. window.history.replaceState = function () {
  757. handlePushState();
  758. return _replaceState.apply(window.history, arguments);
  759. };
  760. }
  761. SOURCE_KEYS = {
  762. ajax: AjaxMonitor,
  763. elements: ElementMonitor,
  764. document: DocumentMonitor,
  765. eventLag: EventLagMonitor
  766. };
  767. (init = function () {
  768. var l, len1, len2, m, ref1, ref2, ref3, type;
  769. Pace.sources = sources = [];
  770. ref1 = ['ajax', 'elements', 'document', 'eventLag'];
  771. for (l = 0, len1 = ref1.length; l < len1; l++) {
  772. type = ref1[l];
  773. if (options[type] !== false) {
  774. sources.push(new SOURCE_KEYS[type](options[type]));
  775. }
  776. }
  777. ref3 = (ref2 = options.extraSources) != null ? ref2 : [];
  778. for (m = 0, len2 = ref3.length; m < len2; m++) {
  779. source = ref3[m];
  780. sources.push(new source(options));
  781. }
  782. Pace.bar = bar = new Bar;
  783. scalers = [];
  784. return uniScaler = new Scaler;
  785. })();
  786. Pace.stop = function () {
  787. Pace.trigger('stop');
  788. Pace.running = false;
  789. bar.destroy();
  790. cancelAnimation = true;
  791. if (animation != null) {
  792. if (typeof cancelAnimationFrame === "function") {
  793. cancelAnimationFrame(animation);
  794. }
  795. animation = null;
  796. }
  797. return init();
  798. };
  799. Pace.restart = function () {
  800. Pace.trigger('restart');
  801. Pace.stop();
  802. return Pace.start();
  803. };
  804. Pace.go = function () {
  805. var start;
  806. Pace.running = true;
  807. bar.render();
  808. start = now();
  809. cancelAnimation = false;
  810. return animation = runAnimation(function (frameTime, enqueueNextFrame) {
  811. var avg, count, done, element, elements, i, j, l, len1, len2, m, ref1, remaining, scaler, scalerList, sum;
  812. remaining = 100 - bar.progress;
  813. count = sum = 0;
  814. done = true;
  815. for (i = l = 0, len1 = sources.length; l < len1; i = ++l) {
  816. source = sources[i];
  817. scalerList = scalers[i] != null ? scalers[i] : scalers[i] = [];
  818. elements = (ref1 = source.elements) != null ? ref1 : [source];
  819. for (j = m = 0, len2 = elements.length; m < len2; j = ++m) {
  820. element = elements[j];
  821. scaler = scalerList[j] != null ? scalerList[j] : scalerList[j] = new Scaler(element);
  822. done &= scaler.done;
  823. if (scaler.done) {
  824. continue;
  825. }
  826. count++;
  827. sum += scaler.tick(frameTime);
  828. }
  829. }
  830. avg = sum / count;
  831. bar.update(uniScaler.tick(frameTime, avg));
  832. if (bar.done() || done || cancelAnimation) {
  833. bar.update(100);
  834. Pace.trigger('done');
  835. return setTimeout(function () {
  836. bar.finish();
  837. Pace.running = false;
  838. return Pace.trigger('hide');
  839. }, Math.max(options.ghostTime, Math.max(options.minTime - (now() - start), 0)));
  840. } else {
  841. return enqueueNextFrame();
  842. }
  843. });
  844. };
  845. Pace.start = function (_options) {
  846. var error;
  847. extend(options, _options);
  848. Pace.running = true;
  849. try {
  850. bar.render();
  851. } catch (error) {
  852. NoTargetError = error;
  853. }
  854. if (!document.querySelector('.pace')) {
  855. return setTimeout(Pace.start, 50);
  856. } else {
  857. Pace.trigger('start');
  858. return Pace.go();
  859. }
  860. };
  861. if (typeof exports === 'object') {
  862. module.exports = Pace;
  863. }
  864. if (options.startOnPageLoad) {
  865. Pace.start();
  866. }
  867. }).call(this);