mirror of
https://github.com/gwenhael-le-moine/ledgerrb.git
synced 2025-01-26 07:58:10 +01:00
added angular-loading-bar
This commit is contained in:
parent
e4ebcf3ee8
commit
20d1b04755
12 changed files with 794 additions and 3 deletions
30
public/app/bower_components/angular-loading-bar/.bower.json
vendored
Normal file
30
public/app/bower_components/angular-loading-bar/.bower.json
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"name": "angular-loading-bar",
|
||||
"version": "0.5.0",
|
||||
"main": [
|
||||
"build/loading-bar.js",
|
||||
"build/loading-bar.css"
|
||||
],
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components",
|
||||
"test",
|
||||
"example"
|
||||
],
|
||||
"devDependencies": {
|
||||
"angular-mocks": "~1.2.9",
|
||||
"angular-animate": "~1.2.9"
|
||||
},
|
||||
"homepage": "https://github.com/chieffancypants/angular-loading-bar",
|
||||
"_release": "0.5.0",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "0.5.0",
|
||||
"commit": "4cc49a7df36e367457d0fdfbd44148848eeb8466"
|
||||
},
|
||||
"_source": "git://github.com/chieffancypants/angular-loading-bar.git",
|
||||
"_target": "~0.5.0",
|
||||
"_originalSource": "angular-loading-bar",
|
||||
"_direct": true
|
||||
}
|
36
public/app/bower_components/angular-loading-bar/CHANGELOG.md
vendored
Normal file
36
public/app/bower_components/angular-loading-bar/CHANGELOG.md
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
Changelog
|
||||
==========
|
||||
|
||||
## 0.5.0
|
||||
- Added spinner template configuration ([#82](https://github.com/chieffancypants/angular-loading-bar/pull/82))
|
||||
- $timeout was not canceled properly ([#79](https://github.com/chieffancypants/angular-loading-bar/pull/79))
|
||||
|
||||
## 0.4.3
|
||||
- update z-index to work with other css frameworks ([#69](https://github.com/chieffancypants/angular-loading-bar/pull/69))
|
||||
- ignoreLoadingBar not ignored when calculating percentage complete ([#70](https://github.com/chieffancypants/angular-loading-bar/pull/70))
|
||||
|
||||
## 0.4.2
|
||||
- Split loading bar into different modules so they can be included separately ([#46](https://github.com/chieffancypants/angular-loading-bar/issues/46))
|
||||
|
||||
## 0.4.1
|
||||
- Fix for route views defined on body where loading bar is also attached ([#56](https://github.com/chieffancypants/angular-loading-bar/issues/56))
|
||||
|
||||
## 0.4.0
|
||||
- Initial load percentage is now configurable ([#47](https://github.com/chieffancypants/angular-loading-bar/issues/47))
|
||||
- Peg graphic reworked so the loadingbar does not require CSS changes when not at the very top of the page ([#42](https://github.com/chieffancypants/angular-loading-bar/issues/42), [#45](https://github.com/chieffancypants/angular-loading-bar/issues/45), [#10](https://github.com/chieffancypants/angular-loading-bar/issues/10))
|
||||
- z-index of spinner increased to work with Bootstrap 3 z-indexes ([#53](https://github.com/chieffancypants/angular-loading-bar/issues/53))
|
||||
|
||||
## 0.3.0
|
||||
- Loading bar only appears on XHR requests with high latency ([#27](https://github.com/chieffancypants/angular-loading-bar/issues/27))
|
||||
|
||||
## 0.2.0
|
||||
- Progression bar not calculated correctly for consecutive calls within the 500ms delay ([#29](https://github.com/chieffancypants/angular-loading-bar/issues/29), [#32](https://github.com/chieffancypants/angular-loading-bar/issues/32))
|
||||
- Event broadcasts when loading (#31)
|
||||
|
||||
## 0.1.1
|
||||
- Alias chieffancypants.loadingbar to angular-loading-bar (#25, #19)
|
||||
|
||||
## 0.1.0
|
||||
- Fixed issues with Angular 1.2-rc3+
|
||||
- Ability to ignore particular XHR requests (#21)
|
||||
- Broadcasting of events (#18)
|
86
public/app/bower_components/angular-loading-bar/Gruntfile.js
vendored
Normal file
86
public/app/bower_components/angular-loading-bar/Gruntfile.js
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
/*global module:false*/
|
||||
module.exports = function(grunt) {
|
||||
|
||||
grunt.initConfig({
|
||||
|
||||
// Metadata.
|
||||
pkg: grunt.file.readJSON('package.json'),
|
||||
banner: '/*! \n * <%= pkg.title || pkg.name %> v<%= pkg.version %>\n' +
|
||||
' * <%= pkg.homepage %>\n' +
|
||||
' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>\n' +
|
||||
' * License: <%= pkg.license %>\n' +
|
||||
' */\n',
|
||||
|
||||
// Task configuration.
|
||||
uglify: {
|
||||
options: {
|
||||
banner: '<%= banner %>',
|
||||
report: 'gzip'
|
||||
},
|
||||
build: {
|
||||
src: 'src/loading-bar.js',
|
||||
dest: 'build/loading-bar.min.js'
|
||||
}
|
||||
},
|
||||
|
||||
cssmin: {
|
||||
options: {
|
||||
banner: '<%= banner %>',
|
||||
report: 'gzip'
|
||||
},
|
||||
minify: {
|
||||
src: 'src/loading-bar.css',
|
||||
dest: 'build/loading-bar.min.css'
|
||||
}
|
||||
},
|
||||
|
||||
karma: {
|
||||
unit: {
|
||||
configFile: 'test/karma.conf.js',
|
||||
singleRun: true,
|
||||
coverageReporter: {
|
||||
type: 'text',
|
||||
dir: 'coverage/'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
configFile: 'test/karma.conf.js',
|
||||
singleRun: false,
|
||||
reporters: ['progress'] // Don't display coverage
|
||||
}
|
||||
},
|
||||
|
||||
jshint: {
|
||||
jshintrc: '.jshintrc',
|
||||
gruntfile: {
|
||||
src: 'Gruntfile.js'
|
||||
},
|
||||
src: {
|
||||
src: ['src/*.js']
|
||||
}
|
||||
},
|
||||
|
||||
concat: {
|
||||
build: {
|
||||
options: {
|
||||
banner: '<%= banner %>'
|
||||
},
|
||||
files: {
|
||||
'build/loading-bar.css': 'src/loading-bar.css',
|
||||
'build/loading-bar.js': 'src/loading-bar.js',
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
grunt.loadNpmTasks('grunt-contrib-uglify');
|
||||
grunt.loadNpmTasks('grunt-contrib-jshint');
|
||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||
grunt.loadNpmTasks('grunt-contrib-concat');
|
||||
grunt.loadNpmTasks('grunt-karma');
|
||||
|
||||
grunt.registerTask('default', ['jshint', 'karma:unit', 'uglify', 'cssmin', 'concat:build']);
|
||||
grunt.registerTask('test', ['karma:watch']);
|
||||
grunt.registerTask('build', ['default']);
|
||||
|
||||
};
|
20
public/app/bower_components/angular-loading-bar/LICENSE
vendored
Normal file
20
public/app/bower_components/angular-loading-bar/LICENSE
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Wes Cruver
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in
|
||||
the Software without restriction, including without limitation the rights to
|
||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||
subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
152
public/app/bower_components/angular-loading-bar/README.md
vendored
Normal file
152
public/app/bower_components/angular-loading-bar/README.md
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
angular-loading-bar
|
||||
===================
|
||||
|
||||
The idea is simple: Add a loading bar / progress bar whenever an XHR request goes out in angular. Multiple requests within the same time period get bundled together such that each response increments the progress bar by the appropriate amount.
|
||||
|
||||
This is mostly cool because you simply include it in your app, and it works. There's no complicated setup, and no need to maintain the state of the loading bar; it's all handled automatically by the interceptor.
|
||||
|
||||
**Requirements:** AngularJS 1.2+
|
||||
|
||||
**File Size:** 2.4Kb minified, 0.5Kb gzipped
|
||||
|
||||
|
||||
## Usage:
|
||||
|
||||
1. include the loading bar as a dependency for your app. If you want animations, include `ngAnimate` as well. *note: ngAnimate is optional*
|
||||
|
||||
```js
|
||||
angular.module('myApp', ['angular-loading-bar', 'ngAnimate'])
|
||||
```
|
||||
|
||||
2. include the supplied CSS file (or create your own).
|
||||
3. That's it -- you're done!
|
||||
|
||||
#### via bower:
|
||||
```
|
||||
$ bower install angular-loading-bar
|
||||
```
|
||||
#### via npm:
|
||||
```
|
||||
$ npm install angular-loading-bar
|
||||
```
|
||||
|
||||
|
||||
## Why I created this
|
||||
There are a couple projects similar to this out there, but none were ideal for me. All implementations I've seen require that you maintain state on behalf of the loading bar. In other words, you're setting the value of the loading/progress bar manually from potentially many different locations. This becomes complicated when you have a very large application with several services all making independant XHR requests. It becomes even more complicated if you want these services to be loosly coupled.
|
||||
|
||||
Additionally, Angular was created as a highly testable framework, so it pains me to see Angular modules without tests. That is not the case here as this loading bar ships with 100% code coverage.
|
||||
|
||||
|
||||
**Goals for this project:**
|
||||
|
||||
1. Make it automatic
|
||||
2. Unit tests, 100% coverage
|
||||
3. Must work well with ngAnimate
|
||||
4. Must be styled via external CSS (not inline)
|
||||
5. No jQuery dependencies
|
||||
|
||||
|
||||
## Configuration
|
||||
|
||||
#### Turn the spinner on or off:
|
||||
The insertion of the spinner can be controlled through configuration. It's on by default, but if you'd like to turn it off, simply configure the service:
|
||||
|
||||
```js
|
||||
angular.module('myApp', ['angular-loading-bar'])
|
||||
.config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {
|
||||
cfpLoadingBarProvider.includeSpinner = false;
|
||||
}])
|
||||
```
|
||||
|
||||
#### Turn the loading bar on or off:
|
||||
Like the spinner configuration above, the loading bar can also be turned off for cases where you only want the spinner:
|
||||
|
||||
```js
|
||||
angular.module('myApp', ['angular-loading-bar'])
|
||||
.config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {
|
||||
cfpLoadingBarProvider.includeBar = false;
|
||||
}])
|
||||
```
|
||||
|
||||
#### Latency Threshold
|
||||
By default, the loading bar will only display after it has been waiting for a response for over 100ms. This helps keep things feeling snappy, and avoids the annoyingness of showing a loading bar every few seconds on really chatty applications. This threshold is totally configurable:
|
||||
|
||||
```js
|
||||
angular.module('myApp', ['angular-loading-bar'])
|
||||
.config(['cfpLoadingBarProvider', function(cfpLoadingBarProvider) {
|
||||
cfpLoadingBarProvider.latencyThreshold = 500;
|
||||
}])
|
||||
```
|
||||
|
||||
#### Ignoring particular XHR requests:
|
||||
The loading bar can also be forced to ignore certain requests, for example, when long-polling or periodically sending debugging information back to the server.
|
||||
|
||||
```js
|
||||
// ignore particular $http requests:
|
||||
$http.get('/status', {
|
||||
ignoreLoadingBar: true
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
// ignore particular $resource requests:
|
||||
.factory('Restaurant', function($resource) {
|
||||
return $resource('/api/restaurant/:id', {id: '@id'}, {
|
||||
query: {
|
||||
method: 'GET',
|
||||
isArray: true,
|
||||
ignoreLoadingBar: true
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
```
|
||||
|
||||
|
||||
|
||||
|
||||
## How it works:
|
||||
This library is split into two modules, an $http `interceptor`, and a `service`:
|
||||
|
||||
**Interceptor**
|
||||
The interceptor simply listens for all outgoing XHR requests, and then instructs the loadingBar service to start, stop, and increment accordingly. There is no public API for the interceptor. It can be used stand-alone by including `cfp.loadingBarInterceptor` as a dependency for your module.
|
||||
|
||||
**Service**
|
||||
The service is responsible for the presentation of the loading bar. It injects the loading bar into the DOM, adjusts the width whenever `set()` is called, and `complete()`s the whole show by removing the loading bar from the DOM.
|
||||
|
||||
## Service API (advanced usage)
|
||||
Under normal circumstances you won't need to use this. However, if you wish to use the loading bar without the interceptor, you can do that as well. Simply include the loading bar service as a dependency instead of the main `angular-loading-bar` module:
|
||||
|
||||
```js
|
||||
angular.module('myApp', ['cfp.loadingBar'])
|
||||
```
|
||||
|
||||
|
||||
```js
|
||||
|
||||
cfpLoadingBar.start();
|
||||
// will insert the loading bar into the DOM, and display its progress at 1%.
|
||||
// It will automatically call `inc()` repeatedly to give the illusion that the page load is progressing.
|
||||
|
||||
cfpLoadingBar.inc();
|
||||
// increments the loading bar by a random amount.
|
||||
// It is important to note that the auto incrementing will begin to slow down as
|
||||
// the progress increases. This is to prevent the loading bar from appearing
|
||||
// completed (or almost complete) before the XHR request has responded.
|
||||
|
||||
cfpLoadingBar.set(0.3) // Set the loading bar to 30%
|
||||
cfpLoadingBar.status() // Returns the loading bar's progress.
|
||||
// -> 0.3
|
||||
|
||||
cfpLoadingBar.complete()
|
||||
// Set the loading bar's progress to 100%, and then remove it from the DOM.
|
||||
|
||||
```
|
||||
|
||||
## Credits:
|
||||
Credit goes to [rstacruz](https://github.com/rstacruz) for his excellent [nProgress](https://github.com/rstacruz/nprogress).
|
||||
|
||||
## License:
|
||||
Licensed under the MIT license
|
16
public/app/bower_components/angular-loading-bar/bower.json
vendored
Normal file
16
public/app/bower_components/angular-loading-bar/bower.json
vendored
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"name": "angular-loading-bar",
|
||||
"version": "0.5.0",
|
||||
"main": ["build/loading-bar.js", "build/loading-bar.css"],
|
||||
"ignore": [
|
||||
"**/.*",
|
||||
"node_modules",
|
||||
"components",
|
||||
"test",
|
||||
"example"
|
||||
],
|
||||
"devDependencies": {
|
||||
"angular-mocks": "~1.2.9",
|
||||
"angular-animate": "~1.2.9"
|
||||
}
|
||||
}
|
45
public/app/bower_components/angular-loading-bar/package.json
vendored
Normal file
45
public/app/bower_components/angular-loading-bar/package.json
vendored
Normal file
|
@ -0,0 +1,45 @@
|
|||
{
|
||||
"name": "angular-loading-bar",
|
||||
"version": "0.5.0",
|
||||
"description": "An automatic loading bar for AngularJS",
|
||||
"main": "src/loading-bar.js",
|
||||
"directories": {
|
||||
"example": "example",
|
||||
"test": "test"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/chieffancypants/angular-loading-bar.git"
|
||||
},
|
||||
"keywords": [
|
||||
"angular",
|
||||
"angularjs",
|
||||
"loading",
|
||||
"loadingbar",
|
||||
"progress",
|
||||
"progressbar"
|
||||
],
|
||||
"author": "Wes Cruver",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/chieffancypants/angular-loading-bar/issues"
|
||||
},
|
||||
"homepage": "https://chieffancypants.github.io/angular-loading-bar",
|
||||
"devDependencies": {
|
||||
"karma-script-launcher": "~0.1.0",
|
||||
"karma-chrome-launcher": "~0.1.0",
|
||||
"karma-firefox-launcher": "~0.1.0",
|
||||
"karma-html2js-preprocessor": "~0.1.0",
|
||||
"karma-jasmine": "~0.1.3",
|
||||
"karma-coffee-preprocessor": "~0.1.0",
|
||||
"karma-phantomjs-launcher": "~0.1.0",
|
||||
"karma": "~0.10.2",
|
||||
"karma-coverage": "~0.1.0",
|
||||
"grunt": "~0.4.1",
|
||||
"grunt-contrib-jshint": "~0.6.4",
|
||||
"grunt-contrib-uglify": "~0.2.4",
|
||||
"grunt-contrib-cssmin": "~0.6.1",
|
||||
"grunt-karma": "~0.6.2",
|
||||
"grunt-contrib-concat": "~0.3.0"
|
||||
}
|
||||
}
|
104
public/app/bower_components/angular-loading-bar/src/loading-bar.css
vendored
Normal file
104
public/app/bower_components/angular-loading-bar/src/loading-bar.css
vendored
Normal file
|
@ -0,0 +1,104 @@
|
|||
|
||||
/* Make clicks pass-through */
|
||||
#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.ng-enter,
|
||||
#loading-bar.ng-leave.ng-leave-active,
|
||||
#loading-bar-spinner.ng-enter,
|
||||
#loading-bar-spinner.ng-leave.ng-leave-active {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
#loading-bar.ng-enter.ng-enter-active,
|
||||
#loading-bar.ng-leave,
|
||||
#loading-bar-spinner.ng-enter.ng-enter-active,
|
||||
#loading-bar-spinner.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;
|
||||
}
|
||||
|
||||
/* Fancy blur effect */
|
||||
#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: 10px;
|
||||
|
||||
-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(0deg); transform: rotate(0deg); }
|
||||
100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@-moz-keyframes loading-bar-spinner {
|
||||
0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@-o-keyframes loading-bar-spinner {
|
||||
0% { -o-transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { -o-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@-ms-keyframes loading-bar-spinner {
|
||||
0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
||||
@keyframes loading-bar-spinner {
|
||||
0% { transform: rotate(0deg); transform: rotate(0deg); }
|
||||
100% { transform: rotate(360deg); transform: rotate(360deg); }
|
||||
}
|
298
public/app/bower_components/angular-loading-bar/src/loading-bar.js
vendored
Normal file
298
public/app/bower_components/angular-loading-bar/src/loading-bar.js
vendored
Normal file
|
@ -0,0 +1,298 @@
|
|||
/*
|
||||
* angular-loading-bar
|
||||
*
|
||||
* intercepts XHR requests and creates a loading bar.
|
||||
* Based on the excellent nprogress work by rstacruz (more info in readme)
|
||||
*
|
||||
* (c) 2013 Wes Cruver
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
// Alias the loading bar for various backwards compatibilities since the project has matured:
|
||||
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', 'cfpLoadingBar', function ($q, $cacheFactory, $timeout, $rootScope, 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 defaults = $httpProvider.defaults;
|
||||
|
||||
if (config.method !== 'GET' || config.cache === false) {
|
||||
config.cached = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (config.cache === true && defaults.cache === undefined) {
|
||||
cache = $cacheFactory.get('$http');
|
||||
} else if (defaults.cache !== undefined) {
|
||||
cache = defaults.cache;
|
||||
} else {
|
||||
cache = config.cache;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
reqsTotal++;
|
||||
cfpLoadingBar.set(reqsCompleted / reqsTotal);
|
||||
}
|
||||
return config;
|
||||
},
|
||||
|
||||
'response': function(response) {
|
||||
if (!response.config.ignoreLoadingBar && !isCached(response.config)) {
|
||||
reqsCompleted++;
|
||||
$rootScope.$broadcast('cfpLoadingBar:loaded', {url: response.config.url});
|
||||
if (reqsCompleted >= reqsTotal) {
|
||||
setComplete();
|
||||
} else {
|
||||
cfpLoadingBar.set(reqsCompleted / reqsTotal);
|
||||
}
|
||||
}
|
||||
return response;
|
||||
},
|
||||
|
||||
'responseError': function(rejection) {
|
||||
if (!rejection.config.ignoreLoadingBar && !isCached(rejection.config)) {
|
||||
reqsCompleted++;
|
||||
$rootScope.$broadcast('cfpLoadingBar:loaded', {url: rejection.config.url});
|
||||
if (reqsCompleted >= reqsTotal) {
|
||||
setComplete();
|
||||
} else {
|
||||
cfpLoadingBar.set(reqsCompleted / reqsTotal);
|
||||
}
|
||||
}
|
||||
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.includeSpinner = true;
|
||||
this.includeBar = true;
|
||||
this.latencyThreshold = 100;
|
||||
this.startSize = 0.02;
|
||||
this.parentSelector = 'body';
|
||||
this.spinnerTemplate = '<div id="loading-bar-spinner"><div class="spinner-icon"></div></div>';
|
||||
|
||||
this.$get = ['$document', '$timeout', '$animate', '$rootScope', function ($document, $timeout, $animate, $rootScope) {
|
||||
|
||||
var $parentSelector = this.parentSelector,
|
||||
loadingBarContainer = angular.element('<div id="loading-bar"><div class="bar"><div class="peg"></div></div></div>'),
|
||||
loadingBar = loadingBarContainer.find('div').eq(0),
|
||||
spinner = angular.element(this.spinnerTemplate);
|
||||
|
||||
var incTimeout,
|
||||
completeTimeout,
|
||||
started = false,
|
||||
status = 0;
|
||||
|
||||
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() {
|
||||
var $parent = $document.find($parentSelector);
|
||||
$timeout.cancel(completeTimeout);
|
||||
|
||||
// do not continually broadcast the started event:
|
||||
if (started) {
|
||||
return;
|
||||
}
|
||||
|
||||
$rootScope.$broadcast('cfpLoadingBar:started');
|
||||
started = true;
|
||||
|
||||
if (includeBar) {
|
||||
$animate.enter(loadingBarContainer, $parent);
|
||||
}
|
||||
|
||||
if (includeSpinner) {
|
||||
$animate.enter(spinner, $parent);
|
||||
}
|
||||
|
||||
_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.
|
||||
$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;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
function _status() {
|
||||
return status;
|
||||
}
|
||||
|
||||
function _complete() {
|
||||
$rootScope.$broadcast('cfpLoadingBar:completed');
|
||||
_set(1);
|
||||
|
||||
$timeout.cancel(completeTimeout);
|
||||
|
||||
// Attempt to aggregate any start/complete calls within 500ms:
|
||||
completeTimeout = $timeout(function() {
|
||||
$animate.leave(loadingBarContainer, function() {
|
||||
status = 0;
|
||||
started = false;
|
||||
});
|
||||
$animate.leave(spinner);
|
||||
}, 500);
|
||||
}
|
||||
|
||||
return {
|
||||
start : _start,
|
||||
set : _set,
|
||||
status : _status,
|
||||
inc : _inc,
|
||||
complete : _complete,
|
||||
includeSpinner : this.includeSpinner,
|
||||
latencyThreshold : this.latencyThreshold,
|
||||
parentSelector : this.parentSelector,
|
||||
startSize : this.startSize
|
||||
};
|
||||
|
||||
|
||||
}]; //
|
||||
}); // wtf javascript. srsly
|
||||
})(); //
|
|
@ -16,6 +16,7 @@
|
|||
<link type="text/css" rel="stylesheet" href="/bower_components/nvd3/nv.d3.min.css">
|
||||
<link type="text/css" rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
|
||||
<link type="text/css" rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap-theme.min.css">
|
||||
<link type="text/css" rel="stylesheet" href="/bower_components/angular-loading-bar/build/loading-bar.min.css">
|
||||
|
||||
<link type="text/css" rel="stylesheet" href="/css/app.css"/>
|
||||
<script src="/bower_components/html5-boilerplate/js/vendor/modernizr-2.6.2.min.js"></script>
|
||||
|
@ -44,6 +45,7 @@
|
|||
<script src="/bower_components/angular-bootstrap/ui-bootstrap.min.js"></script>
|
||||
<script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
|
||||
<script src="/bower_components/angularjs-nvd3-directives/dist/angularjs-nvd3-directives.min.js"></script>
|
||||
<script src="/bower_components/angular-loading-bar/build/loading-bar.min.js"></script>
|
||||
|
||||
<!-- APP -->
|
||||
<script src="/js/app.js"></script>
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
var app = angular.module( 'app', [ 'ui.router',
|
||||
'nvd3ChartDirectives',
|
||||
'angularMoment' ] );
|
||||
'angularMoment',
|
||||
'chieffancypants.loadingBar' ] );
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
"html5-boilerplate": "latest",
|
||||
"angularjs-nvd3-directives": "latest",
|
||||
"angular-bootstrap": "latest",
|
||||
"bootstrap": "~3.2.0",
|
||||
"angular-moment": "~0.8.0"
|
||||
"bootstrap": "latest",
|
||||
"angular-moment": "latest",
|
||||
"angular-loading-bar": "latest"
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue