From 8c7853c8419a891ced7d5fb5cdea01c926f692b2 Mon Sep 17 00:00:00 2001 From: "MANITOULIN\\amathiasen" Date: Thu, 25 May 2017 12:02:38 -0400 Subject: [PATCH 1/7] update all dev dependencies updated all dev dependencies to current added jasmine-core to satisfy peer dependencies updated syntax in unit tests due to breaking changes in jasmine 2.x syntax --- package.json | 23 +++++++------- test/loading-bar-interceptor-config.coffee | 35 +++++++++++----------- test/loading-bar-interceptor.coffee | 22 +++++++++----- 3 files changed, 44 insertions(+), 36 deletions(-) diff --git a/package.json b/package.json index 6529008..9942ee7 100644 --- a/package.json +++ b/package.json @@ -31,16 +31,17 @@ }, "homepage": "https://chieffancypants.github.io/angular-loading-bar", "devDependencies": { - "karma-jasmine": "^0.1.3", - "karma-coffee-preprocessor": "^0.2.0", - "karma-phantomjs-launcher": "^0.1.0", - "karma": "~0.12.0", - "karma-coverage": "^0.1.0", - "grunt": "~0.4.1", - "grunt-contrib-jshint": "~0.6.4", - "grunt-contrib-uglify": "^0.9.1", - "grunt-contrib-cssmin": "~0.12.0", - "grunt-karma": "~0.11.0", - "grunt-contrib-concat": "^0.5.0" + "grunt": "^1.0.1", + "grunt-contrib-concat": "^1.0.1", + "grunt-contrib-cssmin": "^2.2.0", + "grunt-contrib-jshint": "^1.1.0", + "grunt-contrib-uglify": "^3.0.0", + "grunt-karma": "^2.0.0", + "jasmine-core": "^2.6.2", + "karma": "^1.7.0", + "karma-coffee-preprocessor": "^1.0.1", + "karma-coverage": "^1.1.1", + "karma-jasmine": "^1.1.0", + "karma-phantomjs-launcher": "^1.0.4" } } diff --git a/test/loading-bar-interceptor-config.coffee b/test/loading-bar-interceptor-config.coffee index f29ab1e..b33cd8d 100644 --- a/test/loading-bar-interceptor-config.coffee +++ b/test/loading-bar-interceptor-config.coffee @@ -44,28 +44,27 @@ describe 'loadingBarInterceptor Service - config options', -> cfpLoadingBar.complete() $timeout.flush() - it 'should not auto increment loadingBar if configured', (done) -> - module 'chieffancypants.loadingBar', (cfpLoadingBarProvider) -> - cfpLoadingBarProvider.autoIncrement = false - return - inject ($timeout, cfpLoadingBar) -> - flag = false - cfpLoadingBar.start() - cfpLoadingBar.set(.5) - runs -> + describe 'loadingBarInterceptor Service - config options, async tests', -> + beforeEach (done) -> + module 'chieffancypants.loadingBar', (cfpLoadingBarProvider) -> + cfpLoadingBarProvider.autoIncrement = false + return + inject ($timeout, cfpLoadingBar) -> + cfpLoadingBar.start() + cfpLoadingBar.set(.5) setTimeout -> - flag = true + done() , 500 - waitsFor -> - return flag - , "500ms timeout" - , 1000 + it 'should not auto increment loadingBar if configured', (done) -> + inject ($timeout, cfpLoadingBar) -> + setTimeout -> + expect(cfpLoadingBar.status()).toBe .5; + cfpLoadingBar.complete(); + $timeout.flush(); + done(); + , 500 - runs -> - expect(cfpLoadingBar.status()).toBe .5; - cfpLoadingBar.complete() - $timeout.flush() it 'should auto increment loadingBar if configured', -> module 'chieffancypants.loadingBar', (cfpLoadingBarProvider) -> diff --git a/test/loading-bar-interceptor.coffee b/test/loading-bar-interceptor.coffee index 241967f..e3026fe 100644 --- a/test/loading-bar-interceptor.coffee +++ b/test/loading-bar-interceptor.coffee @@ -34,13 +34,21 @@ describe 'loadingBarInterceptor Service', -> $animate.triggerCallbacks && $animate.triggerCallbacks() beforeEach -> - this.addMatchers - toBeBetween: (high, low) -> - if low > high - temp = low - low = high - high = temp - return this.actual > low && this.actual < high + jasmine.addMatchers + toBeBetween: () -> + return compare: (actual, high, low) -> + if low > high + temp = low + low = high + high = temp + passed = actual > low && actual < high + result = + pass: + passed + message: + 'expected ' + actual + ' to ' + (if passed then 'not ' else '') + 'be between ' + low + ' and ' + high + return result + afterEach -> From ba064b94f576cb9677d7f6b4da744ddc715f9ab1 Mon Sep 17 00:00:00 2001 From: "MANITOULIN\\amathiasen" Date: Thu, 25 May 2017 14:06:55 -0400 Subject: [PATCH 2/7] add push and pop methods exposes functionality so that loading bar progress can be customized more easily added unit tests for this new functionlity added push and pop functionality to the description of the service API in the readme added setting autoIncrement to the configuration section of the readme --- README.md | 20 +- src/loading-bar.js | 551 ++++++++++++++-------------- test/loading-bar-interceptor.coffee | 22 ++ 3 files changed, 318 insertions(+), 275 deletions(-) diff --git a/README.md b/README.md index cb409bd..3ef4355 100644 --- a/README.md +++ b/README.md @@ -152,7 +152,15 @@ $http.post('/save', data, { ``` +#### Auto Increment +By default, the loading bar will increment by a random amount that get's smaller as the bar fills, you can disable this: +```js +angular.module('myApp', ['angular-loading-bar']) + .config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) { + cfpLoadingBarProvider.autoIncrement = false; + }]) +``` ## How it works: @@ -190,7 +198,17 @@ cfpLoadingBar.status() // Returns the loading bar's progress. cfpLoadingBar.complete() // Set the loading bar's progress to 100%, and then remove it from the DOM. - +// +// Alternatively, you can us push() and pop() to control the loading bar +// It is suggested that you turn off autoIncrement if you plan on using this +cfpLoadingBar.push(x) +// starts the loading bar if it hasn't been already, and adds to number of 'requests' for this loading bar +// it will broadcast x on the 'cfpLoadingBar:loading' event when called +cfpLoadingBar.pop(y) +// increments the number of requests that have been completed +// then, if the number of 'requests completed' is greater or equal to the number of 'requests' on this bar, it calls complete +// and broadcasts y on the 'cfpLoadingBar:loaded' event +// otherwise, it sets the bar's progress to the number of 'requests completed' divided by the number of 'requests' on this loading bar ``` ## Events diff --git a/src/loading-bar.js b/src/loading-bar.js index 44e092a..d9c1a99 100644 --- a/src/loading-bar.js +++ b/src/loading-bar.js @@ -18,317 +18,320 @@ angular.module('angular-loading-bar', ['cfp.loadingBarInterceptor']); angular.module('chieffancypants.loadingBar', ['cfp.loadingBarInterceptor']); -/** - * loadingBarInterceptor service - * - * Registers itself as an Angular interceptor and listens for XHR requests. - */ -angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) - .config(['$httpProvider', function ($httpProvider) { - - var interceptor = ['$q', '$cacheFactory', '$timeout', '$rootScope', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $timeout, $rootScope, $log, cfpLoadingBar) { - - /** - * The total number of requests made - */ - var reqsTotal = 0; - - /** - * The number of requests completed (either successfully or not) - */ - var reqsCompleted = 0; - - /** - * The amount of time spent fetching before showing the loading bar - */ - var latencyThreshold = cfpLoadingBar.latencyThreshold; - - /** - * $timeout handle for latencyThreshold - */ - var startTimeout; - - - /** - * calls cfpLoadingBar.complete() which removes the - * loading bar from the DOM. - */ - function setComplete() { - $timeout.cancel(startTimeout); - cfpLoadingBar.complete(); - reqsCompleted = 0; - reqsTotal = 0; - } - - /** - * Determine if the response has already been cached - * @param {Object} config the config option from the request - * @return {Boolean} retrns true if cached, otherwise false - */ - function isCached(config) { - var cache; - var defaultCache = $cacheFactory.get('$http'); - var defaults = $httpProvider.defaults; - - // Choose the proper cache source. Borrowed from angular: $http service - if ((config.cache || defaults.cache) && config.cache !== false && - (config.method === 'GET' || config.method === 'JSONP')) { + /** + * loadingBarInterceptor service + * + * Registers itself as an Angular interceptor and listens for XHR requests. + */ + angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) + .config(['$httpProvider', function ($httpProvider) { + + var interceptor = ['$q', '$cacheFactory', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $log, cfpLoadingBar) { + + /** + * Determine if the response has already been cached + * @param {Object} config the config option from the request + * @return {Boolean} retrns true if cached, otherwise false + */ + function isCached(config) { + var cache; + var defaultCache = $cacheFactory.get('$http'); + var defaults = $httpProvider.defaults; + + // Choose the proper cache source. Borrowed from angular: $http service + if ((config.cache || defaults.cache) && config.cache !== false && + (config.method === 'GET' || config.method === 'JSONP')) { cache = angular.isObject(config.cache) ? config.cache : angular.isObject(defaults.cache) ? defaults.cache - : defaultCache; - } + : defaultCache; + } - var cached = cache !== undefined ? - cache.get(config.url) !== undefined : false; + var cached = cache !== undefined ? + cache.get(config.url) !== undefined : false; - if (config.cached !== undefined && cached !== config.cached) { - return config.cached; + if (config.cached !== undefined && cached !== config.cached) { + return config.cached; + } + config.cached = cached; + return cached; } - config.cached = cached; - return cached; - } - - - return { - 'request': function(config) { - // Check to make sure this request hasn't already been cached and that - // the requester didn't explicitly ask us to ignore this request: - if (!config.ignoreLoadingBar && !isCached(config)) { - $rootScope.$broadcast('cfpLoadingBar:loading', {url: config.url}); - if (reqsTotal === 0) { - startTimeout = $timeout(function() { - cfpLoadingBar.start(); - }, latencyThreshold); + + + return { + 'request': function(config) { + // Check to make sure this request hasn't already been cached and that + // the requester didn't explicitly ask us to ignore this request: + if (!config.ignoreLoadingBar && !isCached(config)) { + cfpLoadingBar.push({url: config.url}); } - reqsTotal++; - cfpLoadingBar.set(reqsCompleted / reqsTotal); - } - return config; - }, + return config; + }, - 'response': function(response) { - if (!response || !response.config) { - $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return response; - } + 'response': function(response) { + if (!response || !response.config) { + $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return response; + } - if (!response.config.ignoreLoadingBar && !isCached(response.config)) { - reqsCompleted++; - if (reqsCompleted >= reqsTotal) { - $rootScope.$broadcast('cfpLoadingBar:loaded', {url: response.config.url, result: response}); - setComplete(); - } else { - cfpLoadingBar.set(reqsCompleted / reqsTotal); + if (!response.config.ignoreLoadingBar && !isCached(response.config)) { + cfpLoadingBar.pop({url: response.config.url, result: response}); } - } - return response; - }, + return response; + }, - 'responseError': function(rejection) { - if (!rejection || !rejection.config) { - $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return $q.reject(rejection); - } + 'responseError': function(rejection) { + if (!rejection || !rejection.config) { + $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return $q.reject(rejection); + } - if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { - reqsCompleted++; - if (reqsCompleted >= reqsTotal) { - $rootScope.$broadcast('cfpLoadingBar:loaded', {url: rejection.config.url, result: rejection}); - setComplete(); - } else { - cfpLoadingBar.set(reqsCompleted / reqsTotal); + if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { + cfpLoadingBar.pop({url: rejection.config.url, result: rejection}); } + return $q.reject(rejection); } - return $q.reject(rejection); + }; + }]; + + $httpProvider.interceptors.push(interceptor); + }]); + + + /** + * Loading Bar + * + * This service handles adding and removing the actual element in the DOM. + * Generally, best practices for DOM manipulation is to take place in a + * directive, but because the element itself is injected in the DOM only upon + * XHR requests, and it's likely needed on every view, the best option is to + * use a service. + */ + angular.module('cfp.loadingBar', []) + .provider('cfpLoadingBar', function() { + + this.autoIncrement = true; + this.includeSpinner = true; + this.includeBar = true; + this.latencyThreshold = 100; + this.startSize = 0.02; + this.parentSelector = 'body'; + this.spinnerTemplate = '
'; + this.loadingBarTemplate = '
'; + + this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { + var $animate; + var $parentSelector = this.parentSelector, + loadingBarContainer = angular.element(this.loadingBarTemplate), + loadingBar = loadingBarContainer.find('div').eq(0), + spinner = angular.element(this.spinnerTemplate); + + var incTimeout, + completeTimeout, + started = false, + status = 0; + + var autoIncrement = this.autoIncrement; + var includeSpinner = this.includeSpinner; + var includeBar = this.includeBar; + var startSize = this.startSize; + + /** + * The total number of requests made + */ + var reqsTotal = 0; + + /** + * The number of requests completed (either successfully or not) + */ + var reqsCompleted = 0; + + /** + * The amount of time spent fetching before showing the loading bar + */ + var latencyThreshold = this.latencyThreshold; + + /** + * $timeout handle for latencyThreshold + */ + var startTimeout; + + /** + * calls cfpLoadingBar.complete() which removes the + * loading bar from the DOM. + */ + function setComplete() { + $timeout.cancel(startTimeout); + _complete(); + reqsCompleted = 0; + reqsTotal = 0; } - }; - }]; - $httpProvider.interceptors.push(interceptor); - }]); + /** + * Inserts the loading bar element into the dom, and sets it to 2% + */ + function _start() { + if (!$animate) { + $animate = $injector.get('$animate'); + } + $timeout.cancel(completeTimeout); -/** - * Loading Bar - * - * This service handles adding and removing the actual element in the DOM. - * Generally, best practices for DOM manipulation is to take place in a - * directive, but because the element itself is injected in the DOM only upon - * XHR requests, and it's likely needed on every view, the best option is to - * use a service. - */ -angular.module('cfp.loadingBar', []) - .provider('cfpLoadingBar', function() { - - this.autoIncrement = true; - this.includeSpinner = true; - this.includeBar = true; - this.latencyThreshold = 100; - this.startSize = 0.02; - this.parentSelector = 'body'; - this.spinnerTemplate = '
'; - this.loadingBarTemplate = '
'; - - this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { - var $animate; - var $parentSelector = this.parentSelector, - loadingBarContainer = angular.element(this.loadingBarTemplate), - loadingBar = loadingBarContainer.find('div').eq(0), - spinner = angular.element(this.spinnerTemplate); - - var incTimeout, - completeTimeout, - started = false, - status = 0; - - var autoIncrement = this.autoIncrement; - var includeSpinner = this.includeSpinner; - var includeBar = this.includeBar; - var startSize = this.startSize; - - /** - * Inserts the loading bar element into the dom, and sets it to 2% - */ - function _start() { - if (!$animate) { - $animate = $injector.get('$animate'); - } + // do not continually broadcast the started event: + if (started) { + return; + } - $timeout.cancel(completeTimeout); + var document = $document[0]; + var parent = document.querySelector ? + document.querySelector($parentSelector) + : $document.find($parentSelector)[0] + ; - // do not continually broadcast the started event: - if (started) { - return; - } + if (! parent) { + parent = document.getElementsByTagName('body')[0]; + } - var document = $document[0]; - var parent = document.querySelector ? - document.querySelector($parentSelector) - : $document.find($parentSelector)[0] - ; + var $parent = angular.element(parent); + var $after = parent.lastChild && angular.element(parent.lastChild); - if (! parent) { - parent = document.getElementsByTagName('body')[0]; - } + $rootScope.$broadcast('cfpLoadingBar:started'); + started = true; - var $parent = angular.element(parent); - var $after = parent.lastChild && angular.element(parent.lastChild); + if (includeBar) { + $animate.enter(loadingBarContainer, $parent, $after); + } - $rootScope.$broadcast('cfpLoadingBar:started'); - started = true; + if (includeSpinner) { + $animate.enter(spinner, $parent, loadingBarContainer); + } - if (includeBar) { - $animate.enter(loadingBarContainer, $parent, $after); + _set(startSize); } - if (includeSpinner) { - $animate.enter(spinner, $parent, loadingBarContainer); + /** + * Set the loading bar's width to a certain percent. + * + * @param n any value between 0 and 1 + */ + function _set(n) { + if (!started) { + return; + } + var pct = (n * 100) + '%'; + loadingBar.css('width', pct); + status = n; + + // increment loadingbar to give the illusion that there is always + // progress but make sure to cancel the previous timeouts so we don't + // have multiple incs running at the same time. + if (autoIncrement) { + $timeout.cancel(incTimeout); + incTimeout = $timeout(function() { + _inc(); + }, 250); + } } - _set(startSize); - } - - /** - * Set the loading bar's width to a certain percent. - * - * @param n any value between 0 and 1 - */ - function _set(n) { - if (!started) { - return; - } - var pct = (n * 100) + '%'; - loadingBar.css('width', pct); - status = n; - - // increment loadingbar to give the illusion that there is always - // progress but make sure to cancel the previous timeouts so we don't - // have multiple incs running at the same time. - if (autoIncrement) { - $timeout.cancel(incTimeout); - incTimeout = $timeout(function() { - _inc(); - }, 250); - } - } - - /** - * Increments the loading bar by a random amount - * but slows down as it progresses - */ - function _inc() { - if (_status() >= 1) { - return; + /** + * Increments the loading bar by a random amount + * but slows down as it progresses + */ + function _inc() { + if (_status() >= 1) { + return; + } + + var rnd = 0; + + // TODO: do this mathmatically instead of through conditions + + var stat = _status(); + if (stat >= 0 && stat < 0.25) { + // Start out between 3 - 6% increments + rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; + } else if (stat >= 0.25 && stat < 0.65) { + // increment between 0 - 3% + rnd = (Math.random() * 3) / 100; + } else if (stat >= 0.65 && stat < 0.9) { + // increment between 0 - 2% + rnd = (Math.random() * 2) / 100; + } else if (stat >= 0.9 && stat < 0.99) { + // finally, increment it .5 % + rnd = 0.005; + } else { + // after 99%, don't increment: + rnd = 0; + } + + var pct = _status() + rnd; + _set(pct); } - var rnd = 0; - - // TODO: do this mathmatically instead of through conditions - - var stat = _status(); - if (stat >= 0 && stat < 0.25) { - // Start out between 3 - 6% increments - rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; - } else if (stat >= 0.25 && stat < 0.65) { - // increment between 0 - 3% - rnd = (Math.random() * 3) / 100; - } else if (stat >= 0.65 && stat < 0.9) { - // increment between 0 - 2% - rnd = (Math.random() * 2) / 100; - } else if (stat >= 0.9 && stat < 0.99) { - // finally, increment it .5 % - rnd = 0.005; - } else { - // after 99%, don't increment: - rnd = 0; + function _status() { + return status; } - var pct = _status() + rnd; - _set(pct); - } + function _completeAnimation() { + status = 0; + started = false; + } - function _status() { - return status; - } + function _complete() { + if (!$animate) { + $animate = $injector.get('$animate'); + } - function _completeAnimation() { - status = 0; - started = false; - } + _set(1); + $timeout.cancel(completeTimeout); - function _complete() { - if (!$animate) { - $animate = $injector.get('$animate'); + // Attempt to aggregate any start/complete calls within 500ms: + completeTimeout = $timeout(function() { + var promise = $animate.leave(loadingBarContainer, _completeAnimation); + if (promise && promise.then) { + promise.then(_completeAnimation); + } + $animate.leave(spinner); + $rootScope.$broadcast('cfpLoadingBar:completed'); + }, 500); } - _set(1); - $timeout.cancel(completeTimeout); + function _push(info) { + $rootScope.$broadcast('cfpLoadingBar:loading', info); + if (reqsTotal === 0) { + startTimeout = $timeout(function() { + _start(); + }, latencyThreshold); + } + reqsTotal++; + _set(reqsCompleted / reqsTotal); + } - // Attempt to aggregate any start/complete calls within 500ms: - completeTimeout = $timeout(function() { - var promise = $animate.leave(loadingBarContainer, _completeAnimation); - if (promise && promise.then) { - promise.then(_completeAnimation); + function _pop(info) { + reqsCompleted++; + if (reqsCompleted >= reqsTotal) { + $rootScope.$broadcast('cfpLoadingBar:loaded', info); + setComplete(); + } else { + _set(reqsCompleted / reqsTotal); } - $animate.leave(spinner); - $rootScope.$broadcast('cfpLoadingBar:completed'); - }, 500); - } - - return { - start : _start, - set : _set, - status : _status, - inc : _inc, - complete : _complete, - autoIncrement : this.autoIncrement, - includeSpinner : this.includeSpinner, - latencyThreshold : this.latencyThreshold, - parentSelector : this.parentSelector, - startSize : this.startSize - }; - - - }]; // - }); // wtf javascript. srsly + } + + return { + start : _start, + set : _set, + status : _status, + inc : _inc, + complete : _complete, + push : _push, + pop : _pop, + autoIncrement : this.autoIncrement, + includeSpinner : this.includeSpinner, + latencyThreshold : this.latencyThreshold, + parentSelector : this.parentSelector, + startSize : this.startSize + }; + + + }]; // + }); // wtf javascript. srsly })(); // diff --git a/test/loading-bar-interceptor.coffee b/test/loading-bar-interceptor.coffee index e3026fe..cf0ab64 100644 --- a/test/loading-bar-interceptor.coffee +++ b/test/loading-bar-interceptor.coffee @@ -502,6 +502,28 @@ describe 'LoadingBar only', -> expect(isLoadingBarInjected($document.find(cfpLoadingBar.parentSelector))).toBe false + it 'should allow for explicit calls to push and pop', -> + cfpLoadingBar.start() + $timeout.flush() + + # pushing adds only to reqsTotal, and shouldn't set the status above 0, even with multiple calls + cfpLoadingBar.push({}) + expect(cfpLoadingBar.status()).toBe(0) + cfpLoadingBar.push({}) + cfpLoadingBar.push({}) + cfpLoadingBar.push({}) + expect(cfpLoadingBar.status()).toBe(0) + + # pushing adds to reqsCompleted, and should set the status to reqsCompleted/reqsTotal + cfpLoadingBar.pop({}) + expect(cfpLoadingBar.status()).toBe(0.25) + cfpLoadingBar.pop({}) + expect(cfpLoadingBar.status()).toBe(0.5) + cfpLoadingBar.pop({}) + expect(cfpLoadingBar.status()).toBe(0.75) + cfpLoadingBar.pop({}) + expect(cfpLoadingBar.status()).toBe(1) + describe 'Interceptor tests', -> provider = $http = $httpBackend = $log = null From 11326e011d52f9ef20cf4387fd41bb6ac80ec9fa Mon Sep 17 00:00:00 2001 From: "MANITOULIN\\amathiasen" Date: Fri, 26 May 2017 11:25:26 -0400 Subject: [PATCH 3/7] comitting build --- build/loading-bar.css | 2 +- build/loading-bar.js | 553 +++++++++++++++++++------------------- build/loading-bar.min.css | 2 +- build/loading-bar.min.js | 5 +- 4 files changed, 283 insertions(+), 279 deletions(-) diff --git a/build/loading-bar.css b/build/loading-bar.css index 72408d1..d547f5b 100644 --- a/build/loading-bar.css +++ b/build/loading-bar.css @@ -1,7 +1,7 @@ /*! * angular-loading-bar v0.9.0 * https://chieffancypants.github.io/angular-loading-bar - * Copyright (c) 2016 Wes Cruver + * Copyright (c) 2017 Wes Cruver * License: MIT */ diff --git a/build/loading-bar.js b/build/loading-bar.js index 01630c0..5912f1f 100644 --- a/build/loading-bar.js +++ b/build/loading-bar.js @@ -1,7 +1,7 @@ /*! * angular-loading-bar v0.9.0 * https://chieffancypants.github.io/angular-loading-bar - * Copyright (c) 2016 Wes Cruver + * Copyright (c) 2017 Wes Cruver * License: MIT */ /* @@ -24,317 +24,320 @@ angular.module('angular-loading-bar', ['cfp.loadingBarInterceptor']); angular.module('chieffancypants.loadingBar', ['cfp.loadingBarInterceptor']); -/** - * loadingBarInterceptor service - * - * Registers itself as an Angular interceptor and listens for XHR requests. - */ -angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) - .config(['$httpProvider', function ($httpProvider) { - - var interceptor = ['$q', '$cacheFactory', '$timeout', '$rootScope', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $timeout, $rootScope, $log, cfpLoadingBar) { - - /** - * The total number of requests made - */ - var reqsTotal = 0; - - /** - * The number of requests completed (either successfully or not) - */ - var reqsCompleted = 0; - - /** - * The amount of time spent fetching before showing the loading bar - */ - var latencyThreshold = cfpLoadingBar.latencyThreshold; - - /** - * $timeout handle for latencyThreshold - */ - var startTimeout; - - - /** - * calls cfpLoadingBar.complete() which removes the - * loading bar from the DOM. - */ - function setComplete() { - $timeout.cancel(startTimeout); - cfpLoadingBar.complete(); - reqsCompleted = 0; - reqsTotal = 0; - } - - /** - * Determine if the response has already been cached - * @param {Object} config the config option from the request - * @return {Boolean} retrns true if cached, otherwise false - */ - function isCached(config) { - var cache; - var defaultCache = $cacheFactory.get('$http'); - var defaults = $httpProvider.defaults; - - // Choose the proper cache source. Borrowed from angular: $http service - if ((config.cache || defaults.cache) && config.cache !== false && - (config.method === 'GET' || config.method === 'JSONP')) { + /** + * loadingBarInterceptor service + * + * Registers itself as an Angular interceptor and listens for XHR requests. + */ + angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) + .config(['$httpProvider', function ($httpProvider) { + + var interceptor = ['$q', '$cacheFactory', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $log, cfpLoadingBar) { + + /** + * Determine if the response has already been cached + * @param {Object} config the config option from the request + * @return {Boolean} retrns true if cached, otherwise false + */ + function isCached(config) { + var cache; + var defaultCache = $cacheFactory.get('$http'); + var defaults = $httpProvider.defaults; + + // Choose the proper cache source. Borrowed from angular: $http service + if ((config.cache || defaults.cache) && config.cache !== false && + (config.method === 'GET' || config.method === 'JSONP')) { cache = angular.isObject(config.cache) ? config.cache : angular.isObject(defaults.cache) ? defaults.cache - : defaultCache; - } + : defaultCache; + } - var cached = cache !== undefined ? - cache.get(config.url) !== undefined : false; + var cached = cache !== undefined ? + cache.get(config.url) !== undefined : false; - if (config.cached !== undefined && cached !== config.cached) { - return config.cached; + if (config.cached !== undefined && cached !== config.cached) { + return config.cached; + } + config.cached = cached; + return cached; } - config.cached = cached; - return cached; - } - - - return { - 'request': function(config) { - // Check to make sure this request hasn't already been cached and that - // the requester didn't explicitly ask us to ignore this request: - if (!config.ignoreLoadingBar && !isCached(config)) { - $rootScope.$broadcast('cfpLoadingBar:loading', {url: config.url}); - if (reqsTotal === 0) { - startTimeout = $timeout(function() { - cfpLoadingBar.start(); - }, latencyThreshold); + + + return { + 'request': function(config) { + // Check to make sure this request hasn't already been cached and that + // the requester didn't explicitly ask us to ignore this request: + if (!config.ignoreLoadingBar && !isCached(config)) { + cfpLoadingBar.push({url: config.url}); } - reqsTotal++; - cfpLoadingBar.set(reqsCompleted / reqsTotal); - } - return config; - }, + return config; + }, - 'response': function(response) { - if (!response || !response.config) { - $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return response; - } + 'response': function(response) { + if (!response || !response.config) { + $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return response; + } - if (!response.config.ignoreLoadingBar && !isCached(response.config)) { - reqsCompleted++; - if (reqsCompleted >= reqsTotal) { - $rootScope.$broadcast('cfpLoadingBar:loaded', {url: response.config.url, result: response}); - setComplete(); - } else { - cfpLoadingBar.set(reqsCompleted / reqsTotal); + if (!response.config.ignoreLoadingBar && !isCached(response.config)) { + cfpLoadingBar.pop({url: response.config.url, result: response}); } - } - return response; - }, + return response; + }, - 'responseError': function(rejection) { - if (!rejection || !rejection.config) { - $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return $q.reject(rejection); - } + 'responseError': function(rejection) { + if (!rejection || !rejection.config) { + $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return $q.reject(rejection); + } - if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { - reqsCompleted++; - if (reqsCompleted >= reqsTotal) { - $rootScope.$broadcast('cfpLoadingBar:loaded', {url: rejection.config.url, result: rejection}); - setComplete(); - } else { - cfpLoadingBar.set(reqsCompleted / reqsTotal); + if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { + cfpLoadingBar.pop({url: rejection.config.url, result: rejection}); } + return $q.reject(rejection); } - return $q.reject(rejection); + }; + }]; + + $httpProvider.interceptors.push(interceptor); + }]); + + + /** + * Loading Bar + * + * This service handles adding and removing the actual element in the DOM. + * Generally, best practices for DOM manipulation is to take place in a + * directive, but because the element itself is injected in the DOM only upon + * XHR requests, and it's likely needed on every view, the best option is to + * use a service. + */ + angular.module('cfp.loadingBar', []) + .provider('cfpLoadingBar', function() { + + this.autoIncrement = true; + this.includeSpinner = true; + this.includeBar = true; + this.latencyThreshold = 100; + this.startSize = 0.02; + this.parentSelector = 'body'; + this.spinnerTemplate = '
'; + this.loadingBarTemplate = '
'; + + this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { + var $animate; + var $parentSelector = this.parentSelector, + loadingBarContainer = angular.element(this.loadingBarTemplate), + loadingBar = loadingBarContainer.find('div').eq(0), + spinner = angular.element(this.spinnerTemplate); + + var incTimeout, + completeTimeout, + started = false, + status = 0; + + var autoIncrement = this.autoIncrement; + var includeSpinner = this.includeSpinner; + var includeBar = this.includeBar; + var startSize = this.startSize; + + /** + * The total number of requests made + */ + var reqsTotal = 0; + + /** + * The number of requests completed (either successfully or not) + */ + var reqsCompleted = 0; + + /** + * The amount of time spent fetching before showing the loading bar + */ + var latencyThreshold = this.latencyThreshold; + + /** + * $timeout handle for latencyThreshold + */ + var startTimeout; + + /** + * calls cfpLoadingBar.complete() which removes the + * loading bar from the DOM. + */ + function setComplete() { + $timeout.cancel(startTimeout); + _complete(); + reqsCompleted = 0; + reqsTotal = 0; } - }; - }]; - $httpProvider.interceptors.push(interceptor); - }]); + /** + * Inserts the loading bar element into the dom, and sets it to 2% + */ + function _start() { + if (!$animate) { + $animate = $injector.get('$animate'); + } + $timeout.cancel(completeTimeout); -/** - * Loading Bar - * - * This service handles adding and removing the actual element in the DOM. - * Generally, best practices for DOM manipulation is to take place in a - * directive, but because the element itself is injected in the DOM only upon - * XHR requests, and it's likely needed on every view, the best option is to - * use a service. - */ -angular.module('cfp.loadingBar', []) - .provider('cfpLoadingBar', function() { - - this.autoIncrement = true; - this.includeSpinner = true; - this.includeBar = true; - this.latencyThreshold = 100; - this.startSize = 0.02; - this.parentSelector = 'body'; - this.spinnerTemplate = '
'; - this.loadingBarTemplate = '
'; - - this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { - var $animate; - var $parentSelector = this.parentSelector, - loadingBarContainer = angular.element(this.loadingBarTemplate), - loadingBar = loadingBarContainer.find('div').eq(0), - spinner = angular.element(this.spinnerTemplate); - - var incTimeout, - completeTimeout, - started = false, - status = 0; - - var autoIncrement = this.autoIncrement; - var includeSpinner = this.includeSpinner; - var includeBar = this.includeBar; - var startSize = this.startSize; - - /** - * Inserts the loading bar element into the dom, and sets it to 2% - */ - function _start() { - if (!$animate) { - $animate = $injector.get('$animate'); - } + // do not continually broadcast the started event: + if (started) { + return; + } - $timeout.cancel(completeTimeout); + var document = $document[0]; + var parent = document.querySelector ? + document.querySelector($parentSelector) + : $document.find($parentSelector)[0] + ; - // do not continually broadcast the started event: - if (started) { - return; - } + if (! parent) { + parent = document.getElementsByTagName('body')[0]; + } - var document = $document[0]; - var parent = document.querySelector ? - document.querySelector($parentSelector) - : $document.find($parentSelector)[0] - ; + var $parent = angular.element(parent); + var $after = parent.lastChild && angular.element(parent.lastChild); - if (! parent) { - parent = document.getElementsByTagName('body')[0]; - } + $rootScope.$broadcast('cfpLoadingBar:started'); + started = true; - var $parent = angular.element(parent); - var $after = parent.lastChild && angular.element(parent.lastChild); + if (includeBar) { + $animate.enter(loadingBarContainer, $parent, $after); + } - $rootScope.$broadcast('cfpLoadingBar:started'); - started = true; + if (includeSpinner) { + $animate.enter(spinner, $parent, loadingBarContainer); + } - if (includeBar) { - $animate.enter(loadingBarContainer, $parent, $after); + _set(startSize); } - if (includeSpinner) { - $animate.enter(spinner, $parent, loadingBarContainer); + /** + * Set the loading bar's width to a certain percent. + * + * @param n any value between 0 and 1 + */ + function _set(n) { + if (!started) { + return; + } + var pct = (n * 100) + '%'; + loadingBar.css('width', pct); + status = n; + + // increment loadingbar to give the illusion that there is always + // progress but make sure to cancel the previous timeouts so we don't + // have multiple incs running at the same time. + if (autoIncrement) { + $timeout.cancel(incTimeout); + incTimeout = $timeout(function() { + _inc(); + }, 250); + } } - _set(startSize); - } - - /** - * Set the loading bar's width to a certain percent. - * - * @param n any value between 0 and 1 - */ - function _set(n) { - if (!started) { - return; - } - var pct = (n * 100) + '%'; - loadingBar.css('width', pct); - status = n; - - // increment loadingbar to give the illusion that there is always - // progress but make sure to cancel the previous timeouts so we don't - // have multiple incs running at the same time. - if (autoIncrement) { - $timeout.cancel(incTimeout); - incTimeout = $timeout(function() { - _inc(); - }, 250); - } - } - - /** - * Increments the loading bar by a random amount - * but slows down as it progresses - */ - function _inc() { - if (_status() >= 1) { - return; + /** + * Increments the loading bar by a random amount + * but slows down as it progresses + */ + function _inc() { + if (_status() >= 1) { + return; + } + + var rnd = 0; + + // TODO: do this mathmatically instead of through conditions + + var stat = _status(); + if (stat >= 0 && stat < 0.25) { + // Start out between 3 - 6% increments + rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; + } else if (stat >= 0.25 && stat < 0.65) { + // increment between 0 - 3% + rnd = (Math.random() * 3) / 100; + } else if (stat >= 0.65 && stat < 0.9) { + // increment between 0 - 2% + rnd = (Math.random() * 2) / 100; + } else if (stat >= 0.9 && stat < 0.99) { + // finally, increment it .5 % + rnd = 0.005; + } else { + // after 99%, don't increment: + rnd = 0; + } + + var pct = _status() + rnd; + _set(pct); } - var rnd = 0; - - // TODO: do this mathmatically instead of through conditions - - var stat = _status(); - if (stat >= 0 && stat < 0.25) { - // Start out between 3 - 6% increments - rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; - } else if (stat >= 0.25 && stat < 0.65) { - // increment between 0 - 3% - rnd = (Math.random() * 3) / 100; - } else if (stat >= 0.65 && stat < 0.9) { - // increment between 0 - 2% - rnd = (Math.random() * 2) / 100; - } else if (stat >= 0.9 && stat < 0.99) { - // finally, increment it .5 % - rnd = 0.005; - } else { - // after 99%, don't increment: - rnd = 0; + function _status() { + return status; } - var pct = _status() + rnd; - _set(pct); - } + function _completeAnimation() { + status = 0; + started = false; + } - function _status() { - return status; - } + function _complete() { + if (!$animate) { + $animate = $injector.get('$animate'); + } - function _completeAnimation() { - status = 0; - started = false; - } + _set(1); + $timeout.cancel(completeTimeout); - function _complete() { - if (!$animate) { - $animate = $injector.get('$animate'); + // Attempt to aggregate any start/complete calls within 500ms: + completeTimeout = $timeout(function() { + var promise = $animate.leave(loadingBarContainer, _completeAnimation); + if (promise && promise.then) { + promise.then(_completeAnimation); + } + $animate.leave(spinner); + $rootScope.$broadcast('cfpLoadingBar:completed'); + }, 500); } - _set(1); - $timeout.cancel(completeTimeout); + function _push(info) { + $rootScope.$broadcast('cfpLoadingBar:loading', info); + if (reqsTotal === 0) { + startTimeout = $timeout(function() { + _start(); + }, latencyThreshold); + } + reqsTotal++; + _set(reqsCompleted / reqsTotal); + } - // Attempt to aggregate any start/complete calls within 500ms: - completeTimeout = $timeout(function() { - var promise = $animate.leave(loadingBarContainer, _completeAnimation); - if (promise && promise.then) { - promise.then(_completeAnimation); + function _pop(info) { + reqsCompleted++; + if (reqsCompleted >= reqsTotal) { + $rootScope.$broadcast('cfpLoadingBar:loaded', info); + setComplete(); + } else { + _set(reqsCompleted / reqsTotal); } - $animate.leave(spinner); - $rootScope.$broadcast('cfpLoadingBar:completed'); - }, 500); - } - - return { - start : _start, - set : _set, - status : _status, - inc : _inc, - complete : _complete, - autoIncrement : this.autoIncrement, - includeSpinner : this.includeSpinner, - latencyThreshold : this.latencyThreshold, - parentSelector : this.parentSelector, - startSize : this.startSize - }; - - - }]; // - }); // wtf javascript. srsly + } + + return { + start : _start, + set : _set, + status : _status, + inc : _inc, + complete : _complete, + push : _push, + pop : _pop, + autoIncrement : this.autoIncrement, + includeSpinner : this.includeSpinner, + latencyThreshold : this.latencyThreshold, + parentSelector : this.parentSelector, + startSize : this.startSize + }; + + + }]; // + }); // wtf javascript. srsly })(); // diff --git a/build/loading-bar.min.css b/build/loading-bar.min.css index 0f9f106..75bfc7c 100644 --- a/build/loading-bar.min.css +++ b/build/loading-bar.min.css @@ -1 +1 @@ -#loading-bar,#loading-bar-spinner{pointer-events:none;-webkit-pointer-events:none;-webkit-transition:350ms linear all;-moz-transition:350ms linear all;-o-transition:350ms linear all;transition:350ms linear all}#loading-bar-spinner.ng-enter,#loading-bar-spinner.ng-leave.ng-leave-active,#loading-bar.ng-enter,#loading-bar.ng-leave.ng-leave-active{opacity:0}#loading-bar-spinner.ng-enter.ng-enter-active,#loading-bar-spinner.ng-leave,#loading-bar.ng-enter.ng-enter-active,#loading-bar.ng-leave{opacity:1}#loading-bar .bar{-webkit-transition:width 350ms;-moz-transition:width 350ms;-o-transition:width 350ms;transition:width 350ms;background:#29d;position:fixed;z-index:10002;top:0;left:0;width:100%;height:2px;border-bottom-right-radius:1px;border-top-right-radius:1px}#loading-bar .peg{position:absolute;width:70px;right:0;top:0;height:2px;opacity:.45;-moz-box-shadow:#29d 1px 0 6px 1px;-ms-box-shadow:#29d 1px 0 6px 1px;-webkit-box-shadow:#29d 1px 0 6px 1px;box-shadow:#29d 1px 0 6px 1px;-moz-border-radius:100%;-webkit-border-radius:100%;border-radius:100%}#loading-bar-spinner{display:block;position:fixed;z-index:10002;top:10px;left:10px}#loading-bar-spinner .spinner-icon{width:14px;height:14px;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:loading-bar-spinner 400ms linear infinite;-moz-animation:loading-bar-spinner 400ms linear infinite;-ms-animation:loading-bar-spinner 400ms linear infinite;-o-animation:loading-bar-spinner 400ms linear infinite;animation:loading-bar-spinner 400ms linear infinite}@-webkit-keyframes loading-bar-spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes loading-bar-spinner{0%{-moz-transform:rotate(0);transform:rotate(0)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes loading-bar-spinner{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes loading-bar-spinner{0%{-ms-transform:rotate(0);transform:rotate(0)}100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-bar-spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} \ No newline at end of file +#loading-bar,#loading-bar-spinner{pointer-events:none;-webkit-pointer-events:none;-webkit-transition:350ms linear all;-moz-transition:350ms linear all;-o-transition:350ms linear all;transition:350ms linear all}#loading-bar-spinner.ng-enter,#loading-bar-spinner.ng-leave.ng-leave-active,#loading-bar.ng-enter,#loading-bar.ng-leave.ng-leave-active{opacity:0}#loading-bar-spinner.ng-enter.ng-enter-active,#loading-bar-spinner.ng-leave,#loading-bar.ng-enter.ng-enter-active,#loading-bar.ng-leave{opacity:1}#loading-bar .bar{-webkit-transition:width 350ms;-moz-transition:width 350ms;-o-transition:width 350ms;transition:width 350ms;background:#29d;position:fixed;z-index:10002;top:0;left:0;width:100%;height:2px;border-bottom-right-radius:1px;border-top-right-radius:1px}#loading-bar .peg{position:absolute;width:70px;right:0;top:0;height:2px;opacity:.45;-moz-box-shadow:#29d 1px 0 6px 1px;-ms-box-shadow:#29d 1px 0 6px 1px;-webkit-box-shadow:#29d 1px 0 6px 1px;box-shadow:#29d 1px 0 6px 1px;-moz-border-radius:100%;-webkit-border-radius:100%;border-radius:100%}#loading-bar-spinner{display:block;position:fixed;z-index:10002;top:10px;left:10px}#loading-bar-spinner .spinner-icon{width:14px;height:14px;border:solid 2px transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:loading-bar-spinner .4s linear infinite;-moz-animation:loading-bar-spinner .4s linear infinite;-ms-animation:loading-bar-spinner .4s linear infinite;-o-animation:loading-bar-spinner .4s linear infinite;animation:loading-bar-spinner .4s linear infinite}@-webkit-keyframes loading-bar-spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes loading-bar-spinner{0%{-moz-transform:rotate(0);transform:rotate(0)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes loading-bar-spinner{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes loading-bar-spinner{0%{-ms-transform:rotate(0);transform:rotate(0)}100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-bar-spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} \ No newline at end of file diff --git a/build/loading-bar.min.js b/build/loading-bar.min.js index e4b18ad..06c97f6 100644 --- a/build/loading-bar.min.js +++ b/build/loading-bar.min.js @@ -1,7 +1,8 @@ /*! * angular-loading-bar v0.9.0 * https://chieffancypants.github.io/angular-loading-bar - * Copyright (c) 2016 Wes Cruver + * Copyright (c) 2017 Wes Cruver * License: MIT */ -!function(){"use strict";angular.module("angular-loading-bar",["cfp.loadingBarInterceptor"]),angular.module("chieffancypants.loadingBar",["cfp.loadingBarInterceptor"]),angular.module("cfp.loadingBarInterceptor",["cfp.loadingBar"]).config(["$httpProvider",function(a){var b=["$q","$cacheFactory","$timeout","$rootScope","$log","cfpLoadingBar",function(b,c,d,e,f,g){function h(){d.cancel(j),g.complete(),l=0,k=0}function i(b){var d,e=c.get("$http"),f=a.defaults;!b.cache&&!f.cache||b.cache===!1||"GET"!==b.method&&"JSONP"!==b.method||(d=angular.isObject(b.cache)?b.cache:angular.isObject(f.cache)?f.cache:e);var g=void 0!==d?void 0!==d.get(b.url):!1;return void 0!==b.cached&&g!==b.cached?b.cached:(b.cached=g,g)}var j,k=0,l=0,m=g.latencyThreshold;return{request:function(a){return a.ignoreLoadingBar||i(a)||(e.$broadcast("cfpLoadingBar:loading",{url:a.url}),0===k&&(j=d(function(){g.start()},m)),k++,g.set(l/k)),a},response:function(a){return a&&a.config?(a.config.ignoreLoadingBar||i(a.config)||(l++,l>=k?(e.$broadcast("cfpLoadingBar:loaded",{url:a.config.url,result:a}),h()):g.set(l/k)),a):(f.error("Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),a)},responseError:function(a){return a&&a.config?(a.config.ignoreLoadingBar||i(a.config)||(l++,l>=k?(e.$broadcast("cfpLoadingBar:loaded",{url:a.config.url,result:a}),h()):g.set(l/k)),b.reject(a)):(f.error("Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),b.reject(a))}}}];a.interceptors.push(b)}]),angular.module("cfp.loadingBar",[]).provider("cfpLoadingBar",function(){this.autoIncrement=!0,this.includeSpinner=!0,this.includeBar=!0,this.latencyThreshold=100,this.startSize=.02,this.parentSelector="body",this.spinnerTemplate='
',this.loadingBarTemplate='
',this.$get=["$injector","$document","$timeout","$rootScope",function(a,b,c,d){function e(){if(k||(k=a.get("$animate")),c.cancel(m),!r){var e=b[0],g=e.querySelector?e.querySelector(n):b.find(n)[0];g||(g=e.getElementsByTagName("body")[0]);var h=angular.element(g),i=g.lastChild&&angular.element(g.lastChild);d.$broadcast("cfpLoadingBar:started"),r=!0,v&&k.enter(o,h,i),u&&k.enter(q,h,o),f(w)}}function f(a){if(r){var b=100*a+"%";p.css("width",b),s=a,t&&(c.cancel(l),l=c(function(){g()},250))}}function g(){if(!(h()>=1)){var a=0,b=h();a=b>=0&&.25>b?(3*Math.random()+3)/100:b>=.25&&.65>b?3*Math.random()/100:b>=.65&&.9>b?2*Math.random()/100:b>=.9&&.99>b?.005:0;var c=h()+a;f(c)}}function h(){return s}function i(){s=0,r=!1}function j(){k||(k=a.get("$animate")),f(1),c.cancel(m),m=c(function(){var a=k.leave(o,i);a&&a.then&&a.then(i),k.leave(q),d.$broadcast("cfpLoadingBar:completed")},500)}var k,l,m,n=this.parentSelector,o=angular.element(this.loadingBarTemplate),p=o.find("div").eq(0),q=angular.element(this.spinnerTemplate),r=!1,s=0,t=this.autoIncrement,u=this.includeSpinner,v=this.includeBar,w=this.startSize;return{start:e,set:f,status:h,inc:g,complete:j,autoIncrement:this.autoIncrement,includeSpinner:this.includeSpinner,latencyThreshold:this.latencyThreshold,parentSelector:this.parentSelector,startSize:this.startSize}}]})}(); \ No newline at end of file + +!function(){"use strict";angular.module("angular-loading-bar",["cfp.loadingBarInterceptor"]),angular.module("chieffancypants.loadingBar",["cfp.loadingBarInterceptor"]),angular.module("cfp.loadingBarInterceptor",["cfp.loadingBar"]).config(["$httpProvider",function(e){var n=["$q","$cacheFactory","$log","cfpLoadingBar",function(n,t,a,r){function i(n){var a,r=t.get("$http"),i=e.defaults;!n.cache&&!i.cache||!1===n.cache||"GET"!==n.method&&"JSONP"!==n.method||(a=angular.isObject(n.cache)?n.cache:angular.isObject(i.cache)?i.cache:r);var c=void 0!==a&&void 0!==a.get(n.url);return void 0!==n.cached&&c!==n.cached?n.cached:(n.cached=c,c)}return{request:function(e){return e.ignoreLoadingBar||i(e)||r.push({url:e.url}),e},response:function(e){return e&&e.config?(e.config.ignoreLoadingBar||i(e.config)||r.pop({url:e.config.url,result:e}),e):(a.error("Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),e)},responseError:function(e){return e&&e.config?(e.config.ignoreLoadingBar||i(e.config)||r.pop({url:e.config.url,result:e}),n.reject(e)):(a.error("Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),n.reject(e))}}}];e.interceptors.push(n)}]),angular.module("cfp.loadingBar",[]).provider("cfpLoadingBar",function(){this.autoIncrement=!0,this.includeSpinner=!0,this.includeBar=!0,this.latencyThreshold=100,this.startSize=.02,this.parentSelector="body",this.spinnerTemplate='
',this.loadingBarTemplate='
',this.$get=["$injector","$document","$timeout","$rootScope",function(e,n,t,a){function r(){t.cancel(m),u(),z=0,q=0}function i(){if(p||(p=e.get("$animate")),t.cancel(f),!$){var r=n[0],i=r.querySelector?r.querySelector(v):n.find(v)[0];i||(i=r.getElementsByTagName("body")[0]);var o=angular.element(i),l=i.lastChild&&angular.element(i.lastChild);a.$broadcast("cfpLoadingBar:started"),$=!0,j&&p.enter(B,o,l),L&&p.enter(S,o,B),c(I)}}function c(e){if($){var n=100*e+"%";b.css("width",n),y=e,T&&(t.cancel(g),g=t(function(){o()},250))}}function o(){if(!(l()>=1)){var e=0,n=l();e=n>=0&&n<.25?(3*Math.random()+3)/100:n>=.25&&n<.65?3*Math.random()/100:n>=.65&&n<.9?2*Math.random()/100:n>=.9&&n<.99?.005:0,c(l()+e)}}function l(){return y}function d(){y=0,$=!1}function u(){p||(p=e.get("$animate")),c(1),t.cancel(f),f=t(function(){var e=p.leave(B,d);e&&e.then&&e.then(d),p.leave(S),a.$broadcast("cfpLoadingBar:completed")},500)}function s(e){a.$broadcast("cfpLoadingBar:loading",e),0===q&&(m=t(function(){i()},C)),c(z/++q)}function h(e){++z>=q?(a.$broadcast("cfpLoadingBar:loaded",e),r()):c(z/q)}var p,g,f,m,v=this.parentSelector,B=angular.element(this.loadingBarTemplate),b=B.find("div").eq(0),S=angular.element(this.spinnerTemplate),$=!1,y=0,T=this.autoIncrement,L=this.includeSpinner,j=this.includeBar,I=this.startSize,q=0,z=0,C=this.latencyThreshold;return{start:i,set:c,status:l,inc:o,complete:u,push:s,pop:h,autoIncrement:this.autoIncrement,includeSpinner:this.includeSpinner,latencyThreshold:this.latencyThreshold,parentSelector:this.parentSelector,startSize:this.startSize}}]})}(); \ No newline at end of file From 4939bb2b851bf791bac54369fc4074f8552e4872 Mon Sep 17 00:00:00 2001 From: "MANITOULIN\\amathiasen" Date: Fri, 26 May 2017 13:18:52 -0400 Subject: [PATCH 4/7] whitespace --- src/loading-bar.js | 560 ++++++++++++++++++++++----------------------- 1 file changed, 280 insertions(+), 280 deletions(-) diff --git a/src/loading-bar.js b/src/loading-bar.js index d9c1a99..9fbd09d 100644 --- a/src/loading-bar.js +++ b/src/loading-bar.js @@ -18,320 +18,320 @@ angular.module('angular-loading-bar', ['cfp.loadingBarInterceptor']); angular.module('chieffancypants.loadingBar', ['cfp.loadingBarInterceptor']); - /** - * loadingBarInterceptor service - * - * Registers itself as an Angular interceptor and listens for XHR requests. - */ - angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) - .config(['$httpProvider', function ($httpProvider) { - - var interceptor = ['$q', '$cacheFactory', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $log, cfpLoadingBar) { - - /** - * Determine if the response has already been cached - * @param {Object} config the config option from the request - * @return {Boolean} retrns true if cached, otherwise false - */ - function isCached(config) { - var cache; - var defaultCache = $cacheFactory.get('$http'); - var defaults = $httpProvider.defaults; - - // Choose the proper cache source. Borrowed from angular: $http service - if ((config.cache || defaults.cache) && config.cache !== false && - (config.method === 'GET' || config.method === 'JSONP')) { - cache = angular.isObject(config.cache) ? config.cache - : angular.isObject(defaults.cache) ? defaults.cache - : defaultCache; - } - - var cached = cache !== undefined ? - cache.get(config.url) !== undefined : false; - - if (config.cached !== undefined && cached !== config.cached) { - return config.cached; - } - config.cached = cached; - return cached; +/** + * loadingBarInterceptor service + * + * Registers itself as an Angular interceptor and listens for XHR requests. + */ +angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) + .config(['$httpProvider', function ($httpProvider) { + + var interceptor = ['$q', '$cacheFactory', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $log, cfpLoadingBar) { + + /** + * Determine if the response has already been cached + * @param {Object} config the config option from the request + * @return {Boolean} retrns true if cached, otherwise false + */ + function isCached(config) { + var cache; + var defaultCache = $cacheFactory.get('$http'); + var defaults = $httpProvider.defaults; + + // Choose the proper cache source. Borrowed from angular: $http service + if ((config.cache || defaults.cache) && config.cache !== false && + (config.method === 'GET' || config.method === 'JSONP')) { + cache = angular.isObject(config.cache) ? config.cache + : angular.isObject(defaults.cache) ? defaults.cache + : defaultCache; } + var cached = cache !== undefined ? + cache.get(config.url) !== undefined : false; - return { - 'request': function(config) { - // Check to make sure this request hasn't already been cached and that - // the requester didn't explicitly ask us to ignore this request: - if (!config.ignoreLoadingBar && !isCached(config)) { - cfpLoadingBar.push({url: config.url}); - } - return config; - }, - - 'response': function(response) { - if (!response || !response.config) { - $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return response; - } - - if (!response.config.ignoreLoadingBar && !isCached(response.config)) { - cfpLoadingBar.pop({url: response.config.url, result: response}); - } - return response; - }, + if (config.cached !== undefined && cached !== config.cached) { + return config.cached; + } + config.cached = cached; + return cached; + } - 'responseError': function(rejection) { - if (!rejection || !rejection.config) { - $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return $q.reject(rejection); - } - if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { - cfpLoadingBar.pop({url: rejection.config.url, result: rejection}); - } - return $q.reject(rejection); + return { + 'request': function(config) { + // Check to make sure this request hasn't already been cached and that + // the requester didn't explicitly ask us to ignore this request: + if (!config.ignoreLoadingBar && !isCached(config)) { + cfpLoadingBar.push({url: config.url}); } - }; - }]; - - $httpProvider.interceptors.push(interceptor); - }]); - - - /** - * Loading Bar - * - * This service handles adding and removing the actual element in the DOM. - * Generally, best practices for DOM manipulation is to take place in a - * directive, but because the element itself is injected in the DOM only upon - * XHR requests, and it's likely needed on every view, the best option is to - * use a service. - */ - angular.module('cfp.loadingBar', []) - .provider('cfpLoadingBar', function() { - - this.autoIncrement = true; - this.includeSpinner = true; - this.includeBar = true; - this.latencyThreshold = 100; - this.startSize = 0.02; - this.parentSelector = 'body'; - this.spinnerTemplate = '
'; - this.loadingBarTemplate = '
'; - - this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { - var $animate; - var $parentSelector = this.parentSelector, - loadingBarContainer = angular.element(this.loadingBarTemplate), - loadingBar = loadingBarContainer.find('div').eq(0), - spinner = angular.element(this.spinnerTemplate); - - var incTimeout, - completeTimeout, - started = false, - status = 0; - - var autoIncrement = this.autoIncrement; - var includeSpinner = this.includeSpinner; - var includeBar = this.includeBar; - var startSize = this.startSize; - - /** - * The total number of requests made - */ - var reqsTotal = 0; - - /** - * The number of requests completed (either successfully or not) - */ - var reqsCompleted = 0; - - /** - * The amount of time spent fetching before showing the loading bar - */ - var latencyThreshold = this.latencyThreshold; - - /** - * $timeout handle for latencyThreshold - */ - var startTimeout; - - /** - * calls cfpLoadingBar.complete() which removes the - * loading bar from the DOM. - */ - function setComplete() { - $timeout.cancel(startTimeout); - _complete(); - reqsCompleted = 0; - reqsTotal = 0; - } + return config; + }, - /** - * Inserts the loading bar element into the dom, and sets it to 2% - */ - function _start() { - if (!$animate) { - $animate = $injector.get('$animate'); + 'response': function(response) { + if (!response || !response.config) { + $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return response; } - $timeout.cancel(completeTimeout); - - // do not continually broadcast the started event: - if (started) { - return; + if (!response.config.ignoreLoadingBar && !isCached(response.config)) { + cfpLoadingBar.pop({url: response.config.url, result: response}); } + return response; + }, - var document = $document[0]; - var parent = document.querySelector ? - document.querySelector($parentSelector) - : $document.find($parentSelector)[0] - ; + 'responseError': function(rejection) { + if (!rejection || !rejection.config) { + $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return $q.reject(rejection); + } - if (! parent) { - parent = document.getElementsByTagName('body')[0]; + if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { + cfpLoadingBar.pop({url: rejection.config.url, result: rejection}); } + return $q.reject(rejection); + } + }; + }]; - var $parent = angular.element(parent); - var $after = parent.lastChild && angular.element(parent.lastChild); + $httpProvider.interceptors.push(interceptor); + }]); - $rootScope.$broadcast('cfpLoadingBar:started'); - started = true; - if (includeBar) { - $animate.enter(loadingBarContainer, $parent, $after); - } +/** + * Loading Bar + * + * This service handles adding and removing the actual element in the DOM. + * Generally, best practices for DOM manipulation is to take place in a + * directive, but because the element itself is injected in the DOM only upon + * XHR requests, and it's likely needed on every view, the best option is to + * use a service. + */ +angular.module('cfp.loadingBar', []) + .provider('cfpLoadingBar', function() { + + this.autoIncrement = true; + this.includeSpinner = true; + this.includeBar = true; + this.latencyThreshold = 100; + this.startSize = 0.02; + this.parentSelector = 'body'; + this.spinnerTemplate = '
'; + this.loadingBarTemplate = '
'; + + this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { + var $animate; + var $parentSelector = this.parentSelector, + loadingBarContainer = angular.element(this.loadingBarTemplate), + loadingBar = loadingBarContainer.find('div').eq(0), + spinner = angular.element(this.spinnerTemplate); + + var incTimeout, + completeTimeout, + started = false, + status = 0; + + var autoIncrement = this.autoIncrement; + var includeSpinner = this.includeSpinner; + var includeBar = this.includeBar; + var startSize = this.startSize; + + /** + * The total number of requests made + */ + var reqsTotal = 0; + + /** + * The number of requests completed (either successfully or not) + */ + var reqsCompleted = 0; + + /** + * The amount of time spent fetching before showing the loading bar + */ + var latencyThreshold = this.latencyThreshold; + + /** + * $timeout handle for latencyThreshold + */ + var startTimeout; + + /** + * calls cfpLoadingBar.complete() which removes the + * loading bar from the DOM. + */ + function setComplete() { + $timeout.cancel(startTimeout); + _complete(); + reqsCompleted = 0; + reqsTotal = 0; + } + + /** + * Inserts the loading bar element into the dom, and sets it to 2% + */ + function _start() { + if (!$animate) { + $animate = $injector.get('$animate'); + } - if (includeSpinner) { - $animate.enter(spinner, $parent, loadingBarContainer); - } + $timeout.cancel(completeTimeout); - _set(startSize); + // do not continually broadcast the started event: + if (started) { + return; } - /** - * Set the loading bar's width to a certain percent. - * - * @param n any value between 0 and 1 - */ - function _set(n) { - if (!started) { - return; - } - var pct = (n * 100) + '%'; - loadingBar.css('width', pct); - status = n; - - // increment loadingbar to give the illusion that there is always - // progress but make sure to cancel the previous timeouts so we don't - // have multiple incs running at the same time. - if (autoIncrement) { - $timeout.cancel(incTimeout); - incTimeout = $timeout(function() { - _inc(); - }, 250); - } + var document = $document[0]; + var parent = document.querySelector ? + document.querySelector($parentSelector) + : $document.find($parentSelector)[0] + ; + + if (! parent) { + parent = document.getElementsByTagName('body')[0]; } - /** - * Increments the loading bar by a random amount - * but slows down as it progresses - */ - function _inc() { - if (_status() >= 1) { - return; - } + var $parent = angular.element(parent); + var $after = parent.lastChild && angular.element(parent.lastChild); - var rnd = 0; - - // TODO: do this mathmatically instead of through conditions - - var stat = _status(); - if (stat >= 0 && stat < 0.25) { - // Start out between 3 - 6% increments - rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; - } else if (stat >= 0.25 && stat < 0.65) { - // increment between 0 - 3% - rnd = (Math.random() * 3) / 100; - } else if (stat >= 0.65 && stat < 0.9) { - // increment between 0 - 2% - rnd = (Math.random() * 2) / 100; - } else if (stat >= 0.9 && stat < 0.99) { - // finally, increment it .5 % - rnd = 0.005; - } else { - // after 99%, don't increment: - rnd = 0; - } + $rootScope.$broadcast('cfpLoadingBar:started'); + started = true; - var pct = _status() + rnd; - _set(pct); + if (includeBar) { + $animate.enter(loadingBarContainer, $parent, $after); } - function _status() { - return status; + if (includeSpinner) { + $animate.enter(spinner, $parent, loadingBarContainer); } - function _completeAnimation() { - status = 0; - started = false; + _set(startSize); + } + + /** + * Set the loading bar's width to a certain percent. + * + * @param n any value between 0 and 1 + */ + function _set(n) { + if (!started) { + return; + } + var pct = (n * 100) + '%'; + loadingBar.css('width', pct); + status = n; + + // increment loadingbar to give the illusion that there is always + // progress but make sure to cancel the previous timeouts so we don't + // have multiple incs running at the same time. + if (autoIncrement) { + $timeout.cancel(incTimeout); + incTimeout = $timeout(function() { + _inc(); + }, 250); + } + } + + /** + * Increments the loading bar by a random amount + * but slows down as it progresses + */ + function _inc() { + if (_status() >= 1) { + return; } - function _complete() { - if (!$animate) { - $animate = $injector.get('$animate'); - } - - _set(1); - $timeout.cancel(completeTimeout); - - // Attempt to aggregate any start/complete calls within 500ms: - completeTimeout = $timeout(function() { - var promise = $animate.leave(loadingBarContainer, _completeAnimation); - if (promise && promise.then) { - promise.then(_completeAnimation); - } - $animate.leave(spinner); - $rootScope.$broadcast('cfpLoadingBar:completed'); - }, 500); + var rnd = 0; + + // TODO: do this mathmatically instead of through conditions + + var stat = _status(); + if (stat >= 0 && stat < 0.25) { + // Start out between 3 - 6% increments + rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; + } else if (stat >= 0.25 && stat < 0.65) { + // increment between 0 - 3% + rnd = (Math.random() * 3) / 100; + } else if (stat >= 0.65 && stat < 0.9) { + // increment between 0 - 2% + rnd = (Math.random() * 2) / 100; + } else if (stat >= 0.9 && stat < 0.99) { + // finally, increment it .5 % + rnd = 0.005; + } else { + // after 99%, don't increment: + rnd = 0; } - function _push(info) { - $rootScope.$broadcast('cfpLoadingBar:loading', info); - if (reqsTotal === 0) { - startTimeout = $timeout(function() { - _start(); - }, latencyThreshold); - } - reqsTotal++; - _set(reqsCompleted / reqsTotal); + var pct = _status() + rnd; + _set(pct); + } + + function _status() { + return status; + } + + function _completeAnimation() { + status = 0; + started = false; + } + + function _complete() { + if (!$animate) { + $animate = $injector.get('$animate'); } - function _pop(info) { - reqsCompleted++; - if (reqsCompleted >= reqsTotal) { - $rootScope.$broadcast('cfpLoadingBar:loaded', info); - setComplete(); - } else { - _set(reqsCompleted / reqsTotal); + _set(1); + $timeout.cancel(completeTimeout); + + // Attempt to aggregate any start/complete calls within 500ms: + completeTimeout = $timeout(function() { + var promise = $animate.leave(loadingBarContainer, _completeAnimation); + if (promise && promise.then) { + promise.then(_completeAnimation); } + $animate.leave(spinner); + $rootScope.$broadcast('cfpLoadingBar:completed'); + }, 500); + } + + function _push(info) { + $rootScope.$broadcast('cfpLoadingBar:loading', info); + if (reqsTotal === 0) { + startTimeout = $timeout(function() { + _start(); + }, latencyThreshold); } - - return { - start : _start, - set : _set, - status : _status, - inc : _inc, - complete : _complete, - push : _push, - pop : _pop, - autoIncrement : this.autoIncrement, - includeSpinner : this.includeSpinner, - latencyThreshold : this.latencyThreshold, - parentSelector : this.parentSelector, - startSize : this.startSize - }; - - - }]; // - }); // wtf javascript. srsly + reqsTotal++; + _set(reqsCompleted / reqsTotal); + } + + function _pop(info) { + reqsCompleted++; + if (reqsCompleted >= reqsTotal) { + $rootScope.$broadcast('cfpLoadingBar:loaded', info); + setComplete(); + } else { + _set(reqsCompleted / reqsTotal); + } + } + + return { + start : _start, + set : _set, + status : _status, + inc : _inc, + complete : _complete, + push : _push, + pop : _pop, + autoIncrement : this.autoIncrement, + includeSpinner : this.includeSpinner, + latencyThreshold : this.latencyThreshold, + parentSelector : this.parentSelector, + startSize : this.startSize + }; + + + }]; // + }); // wtf javascript. srsly })(); // From 5ad2c7f15d2aa9f146e53f188f40cdbe342ecf76 Mon Sep 17 00:00:00 2001 From: "MANITOULIN\\amathiasen" Date: Fri, 26 May 2017 13:25:07 -0400 Subject: [PATCH 5/7] whitespace change and build --- build/loading-bar.js | 560 +++++++++++++++++++++---------------------- src/loading-bar.js | 2 +- 2 files changed, 281 insertions(+), 281 deletions(-) diff --git a/build/loading-bar.js b/build/loading-bar.js index 5912f1f..38d9c36 100644 --- a/build/loading-bar.js +++ b/build/loading-bar.js @@ -24,320 +24,320 @@ angular.module('angular-loading-bar', ['cfp.loadingBarInterceptor']); angular.module('chieffancypants.loadingBar', ['cfp.loadingBarInterceptor']); - /** - * loadingBarInterceptor service - * - * Registers itself as an Angular interceptor and listens for XHR requests. - */ - angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) - .config(['$httpProvider', function ($httpProvider) { - - var interceptor = ['$q', '$cacheFactory', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $log, cfpLoadingBar) { - - /** - * Determine if the response has already been cached - * @param {Object} config the config option from the request - * @return {Boolean} retrns true if cached, otherwise false - */ - function isCached(config) { - var cache; - var defaultCache = $cacheFactory.get('$http'); - var defaults = $httpProvider.defaults; - - // Choose the proper cache source. Borrowed from angular: $http service - if ((config.cache || defaults.cache) && config.cache !== false && - (config.method === 'GET' || config.method === 'JSONP')) { - cache = angular.isObject(config.cache) ? config.cache - : angular.isObject(defaults.cache) ? defaults.cache - : defaultCache; - } - - var cached = cache !== undefined ? - cache.get(config.url) !== undefined : false; - - if (config.cached !== undefined && cached !== config.cached) { - return config.cached; - } - config.cached = cached; - return cached; +/** + * loadingBarInterceptor service + * + * Registers itself as an Angular interceptor and listens for XHR requests. + */ +angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) + .config(['$httpProvider', function ($httpProvider) { + + var interceptor = ['$q', '$cacheFactory', '$log', 'cfpLoadingBar', function ($q, $cacheFactory, $log, cfpLoadingBar) { + + /** + * Determine if the response has already been cached + * @param {Object} config the config option from the request + * @return {Boolean} retrns true if cached, otherwise false + */ + function isCached(config) { + var cache; + var defaultCache = $cacheFactory.get('$http'); + var defaults = $httpProvider.defaults; + + // Choose the proper cache source. Borrowed from angular: $http service + if ((config.cache || defaults.cache) && config.cache !== false && + (config.method === 'GET' || config.method === 'JSONP')) { + cache = angular.isObject(config.cache) ? config.cache + : angular.isObject(defaults.cache) ? defaults.cache + : defaultCache; } + var cached = cache !== undefined ? + cache.get(config.url) !== undefined : false; - return { - 'request': function(config) { - // Check to make sure this request hasn't already been cached and that - // the requester didn't explicitly ask us to ignore this request: - if (!config.ignoreLoadingBar && !isCached(config)) { - cfpLoadingBar.push({url: config.url}); - } - return config; - }, - - 'response': function(response) { - if (!response || !response.config) { - $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return response; - } - - if (!response.config.ignoreLoadingBar && !isCached(response.config)) { - cfpLoadingBar.pop({url: response.config.url, result: response}); - } - return response; - }, + if (config.cached !== undefined && cached !== config.cached) { + return config.cached; + } + config.cached = cached; + return cached; + } - 'responseError': function(rejection) { - if (!rejection || !rejection.config) { - $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); - return $q.reject(rejection); - } - if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { - cfpLoadingBar.pop({url: rejection.config.url, result: rejection}); - } - return $q.reject(rejection); + return { + 'request': function(config) { + // Check to make sure this request hasn't already been cached and that + // the requester didn't explicitly ask us to ignore this request: + if (!config.ignoreLoadingBar && !isCached(config)) { + cfpLoadingBar.push({url: config.url}); } - }; - }]; - - $httpProvider.interceptors.push(interceptor); - }]); - - - /** - * Loading Bar - * - * This service handles adding and removing the actual element in the DOM. - * Generally, best practices for DOM manipulation is to take place in a - * directive, but because the element itself is injected in the DOM only upon - * XHR requests, and it's likely needed on every view, the best option is to - * use a service. - */ - angular.module('cfp.loadingBar', []) - .provider('cfpLoadingBar', function() { - - this.autoIncrement = true; - this.includeSpinner = true; - this.includeBar = true; - this.latencyThreshold = 100; - this.startSize = 0.02; - this.parentSelector = 'body'; - this.spinnerTemplate = '
'; - this.loadingBarTemplate = '
'; - - this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { - var $animate; - var $parentSelector = this.parentSelector, - loadingBarContainer = angular.element(this.loadingBarTemplate), - loadingBar = loadingBarContainer.find('div').eq(0), - spinner = angular.element(this.spinnerTemplate); - - var incTimeout, - completeTimeout, - started = false, - status = 0; - - var autoIncrement = this.autoIncrement; - var includeSpinner = this.includeSpinner; - var includeBar = this.includeBar; - var startSize = this.startSize; - - /** - * The total number of requests made - */ - var reqsTotal = 0; - - /** - * The number of requests completed (either successfully or not) - */ - var reqsCompleted = 0; - - /** - * The amount of time spent fetching before showing the loading bar - */ - var latencyThreshold = this.latencyThreshold; - - /** - * $timeout handle for latencyThreshold - */ - var startTimeout; - - /** - * calls cfpLoadingBar.complete() which removes the - * loading bar from the DOM. - */ - function setComplete() { - $timeout.cancel(startTimeout); - _complete(); - reqsCompleted = 0; - reqsTotal = 0; - } + return config; + }, - /** - * Inserts the loading bar element into the dom, and sets it to 2% - */ - function _start() { - if (!$animate) { - $animate = $injector.get('$animate'); + 'response': function(response) { + if (!response || !response.config) { + $log.error('Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return response; } - $timeout.cancel(completeTimeout); - - // do not continually broadcast the started event: - if (started) { - return; + if (!response.config.ignoreLoadingBar && !isCached(response.config)) { + cfpLoadingBar.pop({url: response.config.url, result: response}); } + return response; + }, - var document = $document[0]; - var parent = document.querySelector ? - document.querySelector($parentSelector) - : $document.find($parentSelector)[0] - ; + 'responseError': function(rejection) { + if (!rejection || !rejection.config) { + $log.error('Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50'); + return $q.reject(rejection); + } - if (! parent) { - parent = document.getElementsByTagName('body')[0]; + if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) { + cfpLoadingBar.pop({url: rejection.config.url, result: rejection}); } + return $q.reject(rejection); + } + }; + }]; - var $parent = angular.element(parent); - var $after = parent.lastChild && angular.element(parent.lastChild); + $httpProvider.interceptors.push(interceptor); + }]); - $rootScope.$broadcast('cfpLoadingBar:started'); - started = true; - if (includeBar) { - $animate.enter(loadingBarContainer, $parent, $after); - } +/** + * Loading Bar + * + * This service handles adding and removing the actual element in the DOM. + * Generally, best practices for DOM manipulation is to take place in a + * directive, but because the element itself is injected in the DOM only upon + * XHR requests, and it's likely needed on every view, the best option is to + * use a service. + */ +angular.module('cfp.loadingBar', []) + .provider('cfpLoadingBar', function() { + + this.autoIncrement = true; + this.includeSpinner = true; + this.includeBar = true; + this.latencyThreshold = 100; + this.startSize = 0.02; + this.parentSelector = 'body'; + this.spinnerTemplate = '
'; + this.loadingBarTemplate = '
'; + + this.$get = ['$injector', '$document', '$timeout', '$rootScope', function ($injector, $document, $timeout, $rootScope) { + var $animate; + var $parentSelector = this.parentSelector, + loadingBarContainer = angular.element(this.loadingBarTemplate), + loadingBar = loadingBarContainer.find('div').eq(0), + spinner = angular.element(this.spinnerTemplate); + + var incTimeout, + completeTimeout, + started = false, + status = 0; + + var autoIncrement = this.autoIncrement; + var includeSpinner = this.includeSpinner; + var includeBar = this.includeBar; + var startSize = this.startSize; + + /** + * The total number of requests made + */ + var reqsTotal = 0; + + /** + * The number of requests completed (either successfully or not) + */ + var reqsCompleted = 0; + + /** + * The amount of time spent fetching before showing the loading bar + */ + var latencyThreshold = this.latencyThreshold; + + /** + * $timeout handle for latencyThreshold + */ + var startTimeout; + + /** + * calls cfpLoadingBar.complete() which removes the + * loading bar from the DOM. + */ + function setComplete() { + $timeout.cancel(startTimeout); + _complete(); + reqsCompleted = 0; + reqsTotal = 0; + } + + /** + * Inserts the loading bar element into the dom, and sets it to 2% + */ + function _start() { + if (!$animate) { + $animate = $injector.get('$animate'); + } - if (includeSpinner) { - $animate.enter(spinner, $parent, loadingBarContainer); - } + $timeout.cancel(completeTimeout); - _set(startSize); + // do not continually broadcast the started event: + if (started) { + return; } - /** - * Set the loading bar's width to a certain percent. - * - * @param n any value between 0 and 1 - */ - function _set(n) { - if (!started) { - return; - } - var pct = (n * 100) + '%'; - loadingBar.css('width', pct); - status = n; - - // increment loadingbar to give the illusion that there is always - // progress but make sure to cancel the previous timeouts so we don't - // have multiple incs running at the same time. - if (autoIncrement) { - $timeout.cancel(incTimeout); - incTimeout = $timeout(function() { - _inc(); - }, 250); - } + var document = $document[0]; + var parent = document.querySelector ? + document.querySelector($parentSelector) + : $document.find($parentSelector)[0] + ; + + if (! parent) { + parent = document.getElementsByTagName('body')[0]; } - /** - * Increments the loading bar by a random amount - * but slows down as it progresses - */ - function _inc() { - if (_status() >= 1) { - return; - } + var $parent = angular.element(parent); + var $after = parent.lastChild && angular.element(parent.lastChild); - var rnd = 0; - - // TODO: do this mathmatically instead of through conditions - - var stat = _status(); - if (stat >= 0 && stat < 0.25) { - // Start out between 3 - 6% increments - rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; - } else if (stat >= 0.25 && stat < 0.65) { - // increment between 0 - 3% - rnd = (Math.random() * 3) / 100; - } else if (stat >= 0.65 && stat < 0.9) { - // increment between 0 - 2% - rnd = (Math.random() * 2) / 100; - } else if (stat >= 0.9 && stat < 0.99) { - // finally, increment it .5 % - rnd = 0.005; - } else { - // after 99%, don't increment: - rnd = 0; - } + $rootScope.$broadcast('cfpLoadingBar:started'); + started = true; - var pct = _status() + rnd; - _set(pct); + if (includeBar) { + $animate.enter(loadingBarContainer, $parent, $after); } - function _status() { - return status; + if (includeSpinner) { + $animate.enter(spinner, $parent, loadingBarContainer); } - function _completeAnimation() { - status = 0; - started = false; + _set(startSize); + } + + /** + * Set the loading bar's width to a certain percent. + * + * @param n any value between 0 and 1 + */ + function _set(n) { + if (!started) { + return; + } + var pct = (n * 100) + '%'; + loadingBar.css('width', pct); + status = n; + + // increment loadingbar to give the illusion that there is always + // progress but make sure to cancel the previous timeouts so we don't + // have multiple incs running at the same time. + if (autoIncrement) { + $timeout.cancel(incTimeout); + incTimeout = $timeout(function() { + _inc(); + }, 250); + } + } + + /** + * Increments the loading bar by a random amount + * but slows down as it progresses + */ + function _inc() { + if (_status() >= 1) { + return; } - function _complete() { - if (!$animate) { - $animate = $injector.get('$animate'); - } - - _set(1); - $timeout.cancel(completeTimeout); - - // Attempt to aggregate any start/complete calls within 500ms: - completeTimeout = $timeout(function() { - var promise = $animate.leave(loadingBarContainer, _completeAnimation); - if (promise && promise.then) { - promise.then(_completeAnimation); - } - $animate.leave(spinner); - $rootScope.$broadcast('cfpLoadingBar:completed'); - }, 500); + var rnd = 0; + + // TODO: do this mathmatically instead of through conditions + + var stat = _status(); + if (stat >= 0 && stat < 0.25) { + // Start out between 3 - 6% increments + rnd = (Math.random() * (5 - 3 + 1) + 3) / 100; + } else if (stat >= 0.25 && stat < 0.65) { + // increment between 0 - 3% + rnd = (Math.random() * 3) / 100; + } else if (stat >= 0.65 && stat < 0.9) { + // increment between 0 - 2% + rnd = (Math.random() * 2) / 100; + } else if (stat >= 0.9 && stat < 0.99) { + // finally, increment it .5 % + rnd = 0.005; + } else { + // after 99%, don't increment: + rnd = 0; } - function _push(info) { - $rootScope.$broadcast('cfpLoadingBar:loading', info); - if (reqsTotal === 0) { - startTimeout = $timeout(function() { - _start(); - }, latencyThreshold); - } - reqsTotal++; - _set(reqsCompleted / reqsTotal); + var pct = _status() + rnd; + _set(pct); + } + + function _status() { + return status; + } + + function _completeAnimation() { + status = 0; + started = false; + } + + function _complete() { + if (!$animate) { + $animate = $injector.get('$animate'); } - function _pop(info) { - reqsCompleted++; - if (reqsCompleted >= reqsTotal) { - $rootScope.$broadcast('cfpLoadingBar:loaded', info); - setComplete(); - } else { - _set(reqsCompleted / reqsTotal); + _set(1); + $timeout.cancel(completeTimeout); + + // Attempt to aggregate any start/complete calls within 500ms: + completeTimeout = $timeout(function() { + var promise = $animate.leave(loadingBarContainer, _completeAnimation); + if (promise && promise.then) { + promise.then(_completeAnimation); } + $animate.leave(spinner); + $rootScope.$broadcast('cfpLoadingBar:completed'); + }, 500); + } + + function _push(info) { + $rootScope.$broadcast('cfpLoadingBar:loading', info); + if (reqsTotal === 0) { + startTimeout = $timeout(function() { + _start(); + }, latencyThreshold); } - - return { - start : _start, - set : _set, - status : _status, - inc : _inc, - complete : _complete, - push : _push, - pop : _pop, - autoIncrement : this.autoIncrement, - includeSpinner : this.includeSpinner, - latencyThreshold : this.latencyThreshold, - parentSelector : this.parentSelector, - startSize : this.startSize - }; - - - }]; // - }); // wtf javascript. srsly + reqsTotal++; + _set(reqsCompleted / reqsTotal); + } + + function _pop(info) { + reqsCompleted++; + if (reqsCompleted >= reqsTotal) { + $rootScope.$broadcast('cfpLoadingBar:loaded', info); + setComplete(); + } else { + _set(reqsCompleted / reqsTotal); + } + } + + return { + start : _start, + set : _set, + status : _status, + inc : _inc, + complete : _complete, + push : _push, + pop : _pop, + autoIncrement : this.autoIncrement, + includeSpinner : this.includeSpinner, + latencyThreshold : this.latencyThreshold, + parentSelector : this.parentSelector, + startSize : this.startSize + }; + + + }]; // + }); // wtf javascript. srsly })(); // diff --git a/src/loading-bar.js b/src/loading-bar.js index 9fbd09d..3ce1734 100644 --- a/src/loading-bar.js +++ b/src/loading-bar.js @@ -43,7 +43,7 @@ angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) (config.method === 'GET' || config.method === 'JSONP')) { cache = angular.isObject(config.cache) ? config.cache : angular.isObject(defaults.cache) ? defaults.cache - : defaultCache; + : defaultCache; } var cached = cache !== undefined ? From 09c88b54a3d0573452764d1dbbe9a717841ed257 Mon Sep 17 00:00:00 2001 From: "MANITOULIN\\amathiasen" Date: Fri, 26 May 2017 13:26:48 -0400 Subject: [PATCH 6/7] missed a spot, rebuilt --- build/loading-bar.js | 6 +++--- src/loading-bar.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/loading-bar.js b/build/loading-bar.js index 38d9c36..7b7c7e0 100644 --- a/build/loading-bar.js +++ b/build/loading-bar.js @@ -47,9 +47,9 @@ angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) // Choose the proper cache source. Borrowed from angular: $http service if ((config.cache || defaults.cache) && config.cache !== false && (config.method === 'GET' || config.method === 'JSONP')) { - cache = angular.isObject(config.cache) ? config.cache - : angular.isObject(defaults.cache) ? defaults.cache - : defaultCache; + cache = angular.isObject(config.cache) ? config.cache + : angular.isObject(defaults.cache) ? defaults.cache + : defaultCache; } var cached = cache !== undefined ? diff --git a/src/loading-bar.js b/src/loading-bar.js index 3ce1734..501a949 100644 --- a/src/loading-bar.js +++ b/src/loading-bar.js @@ -41,9 +41,9 @@ angular.module('cfp.loadingBarInterceptor', ['cfp.loadingBar']) // Choose the proper cache source. Borrowed from angular: $http service if ((config.cache || defaults.cache) && config.cache !== false && (config.method === 'GET' || config.method === 'JSONP')) { - cache = angular.isObject(config.cache) ? config.cache - : angular.isObject(defaults.cache) ? defaults.cache - : defaultCache; + cache = angular.isObject(config.cache) ? config.cache + : angular.isObject(defaults.cache) ? defaults.cache + : defaultCache; } var cached = cache !== undefined ? From beec7ae28c2e39bce15686006b3c672a25a6a8a5 Mon Sep 17 00:00:00 2001 From: "MANITOULIN\\amathiasen" Date: Fri, 26 May 2017 14:27:53 -0400 Subject: [PATCH 7/7] reworded the service api README change caught a typo in the configuration section change --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 3ef4355..3cde38c 100644 --- a/README.md +++ b/README.md @@ -153,7 +153,7 @@ $http.post('/save', data, { ``` #### Auto Increment -By default, the loading bar will increment by a random amount that get's smaller as the bar fills, you can disable this: +By default, the loading bar will increment by a random amount that gets smaller as the bar fills, you can disable this: ```js angular.module('myApp', ['angular-loading-bar']) @@ -199,16 +199,14 @@ cfpLoadingBar.status() // Returns the loading bar's progress. cfpLoadingBar.complete() // Set the loading bar's progress to 100%, and then remove it from the DOM. // -// Alternatively, you can us push() and pop() to control the loading bar -// It is suggested that you turn off autoIncrement if you plan on using this +// If your requests don't go through the $http service and can't be automatically detected, +// use the following cfpLoadingBar.push(x) -// starts the loading bar if it hasn't been already, and adds to number of 'requests' for this loading bar +// signals the start of a request // it will broadcast x on the 'cfpLoadingBar:loading' event when called cfpLoadingBar.pop(y) -// increments the number of requests that have been completed -// then, if the number of 'requests completed' is greater or equal to the number of 'requests' on this bar, it calls complete -// and broadcasts y on the 'cfpLoadingBar:loaded' event -// otherwise, it sets the bar's progress to the number of 'requests completed' divided by the number of 'requests' on this loading bar +// signals the completion of a request +// if it is the last request to complete, broadcasts y on the 'cfpLoadingBar:loaded' event ``` ## Events