├── .editorconfig
├── .gitignore
├── .travis.yml
├── CHANGELOG.md
├── Examples
├── advancedUsage.html
└── basicUsage.html
├── LICENSE
├── README.md
├── karma.conf.js
├── package.json
├── src
├── Config
│ └── UsSpinnerConfig.ts
├── Constants
│ └── SpinJSSpinner.ts
├── Directives
│ └── AngularSpinner.ts
├── Interfaces
│ ├── IUsSpinnerAttributes.d.ts
│ ├── IUsSpinnerConfig.d.ts
│ ├── IUsSpinnerScope.d.ts
│ └── IUsSpinnerService.d.ts
├── Services
│ └── UsSpinnerService.ts
└── angular-spinner.ts
├── test
├── Config
│ └── UsSpinnerConfig.test.ts
├── Directives
│ └── AngularSpinner.test.ts
└── index.ts
├── tsconfig.json
├── webpack.config.js
└── webpack.production.config.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig helps developers define and maintain consistent
2 | # coding styles between different editors and IDEs
3 | # editorconfig.org
4 |
5 | root = true
6 |
7 | [*]
8 |
9 | # Change these settings to your own preference
10 | indent_style = tab
11 | indent_size = 4
12 |
13 | # We recommend you to keep these unchanged
14 | end_of_line = lf
15 | charset = utf-8
16 | trim_trailing_whitespace = true
17 | insert_final_newline = true
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | node_modules
3 | coverage
4 | .history
5 | .vscode
6 | dist
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | sudo: false
3 | node_js:
4 | - 6.9.1
5 | install:
6 | - npm install
7 | script:
8 | - npm test
9 | after_success:
10 | - cat ./coverage/*/lcov.info | ./node_modules/coveralls/bin/coveralls.js
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.0.0 - 2017-01-23
4 | - Breaking changes: Refactored the project to be written with TypeScript, contributed by [Attrash-Islam](https://github.com/Attrash-Islam)
5 |
6 | ## 0.8.1 - 2016-02-16
7 | - Bugfix: Default options overwriting ([#81](https://github.com/urish/angular-spinner/pull/81), contributed by [dmytroyarmak](https://github.com/dmytroyarmak))
8 |
9 | ## 0.8.0 - 2015-10-29
10 | - Improve UMD (Universal Module Definition) code, fixes ([#61](https://github.com/urish/angular-spinner/issues/61))
11 | - Theme support ([#66](https://github.com/urish/angular-spinner/pull/66), contributed by [marknadig](https://github.com/marknadig))
12 | - Add `spinner-on` attribute ([#71](https://github.com/urish/angular-spinner/pull/71), contributed by [marknadig](https://github.com/marknadig))
13 |
14 | ## 0.7.0 - 2015-09-09
15 | - Add CommonJS support, improve AMD support (for use with browserify, webpack, SystemJS, etc.)
16 |
17 | ## 0.6.2 - 2015-07-02
18 | - Relax Angular's dependency version lock ([#52](https://github.com/urish/angular-spinner/pull/52), contributed by [gottfrois](https://github.com/gottfrois))
19 |
20 | ## 0.6.1 - 2015-01-06
21 | - Removed NBSP characters from source code ([#40](https://github.com/urish/angular-spinner/pull/40), contributed by [amolghotankar](https://github.com/amolghotankar))
22 | - Return the created AngularJS module ([#37](https://github.com/urish/angular-spinner/pull/37), contributed by [k7sleeper](https://github.com/k7sleeper))
23 |
24 | ## 0.6.0 - 2014-12-12
25 | - Added configurable default options ([#31](https://github.com/urish/angular-spinner/pull/31), contributed by [aleksih](https://github.com/aleksih))
26 | - Added scope eval to allow for data binding support ([#21](https://github.com/urish/angular-spinner/pull/21), contributed by [jdamick](https://github.com/jdamick))
27 |
28 | ## 0.5.1 - 2014-08-09
29 | - AMD / Require.js compatibility ([#11](https://github.com/urish/angular-spinner/pull/11), contributed by [floribon](https://github.com/floribon))
30 | - Bugfix: Stop events are ignored if sent before the directive is fully initialized and `startActive` is true ([#22](https://github.com/urish/angular-spinner/pull/22), contributed by [vleborgne](https://github.com/vleborgne))
31 |
32 | ## 0.5.0 - 2014-06-03
33 |
34 | - Add support for expressions in attributes ([#12](https://github.com/urish/angular-spinner/pull/12), contributed by [aaronroberson](https://github.com/aaronroberson))
35 | - Generate source map for the minified version ([#14](https://github.com/urish/angular-spinner/issues/14))
36 | - Add a `main` field to package.json ([#15](https://github.com/urish/angular-spinner/pull/15), contributed by [elfreyshira](https://github.com/elfreyshira))
37 | - Enable support for AngularJS 1.3.x in bower.json
38 |
39 | ## 0.4.0 - 2014-03-15
40 |
41 | - Upgrade spin.js to 2.0.0. See breaking changes [here](http://fgnass.github.io/spin.js/#v2.0.0).
42 |
43 | ## 0.3.1 - 2014-01-31
44 |
45 | - Fixed an issue that caused the minified code to fail.
46 |
47 | ## 0.3.0 - 2014-01-26
48 |
49 | - Add ability to control spinner state with bundled service (([#6](https://github.com/urish/angular-spinner/pull/6), contributed by [lossendae](https://github.com/lossendae))
50 |
51 | ## 0.2.1 - 2013-08-28
52 |
53 | - Add test coverage reporting
54 | - Stop the spinner on scope destroy
55 | - Support for AngularJS 1.2
56 |
--------------------------------------------------------------------------------
/Examples/advancedUsage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Hello Spinner!
7 |
8 |
9 |
Spinner active: {{spinneractive}}
Started: {{startcounter}} times
10 |
11 |
12 |
13 |
14 |
15 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/Examples/basicUsage.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013-2017 Uri Shaked and contributors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-spinner
2 |
3 | Angular directive to show an animated spinner (using [spin.js](http://fgnass.github.io/spin.js/))
4 |
5 | Copyright (C) 2013, 2014, 2015, 2016, 2017 Uri Shaked, Islam Attrash and contributors
6 |
7 | [](https://travis-ci.org/urish/angular-spinner)
8 | [](https://coveralls.io/r/urish/angular-spinner)
9 |
10 |
11 | ## Usage
12 |
13 | Get angular-spinner
14 |
15 | - via npm: by running ``` $ npm install angular-spinner ``` from your console
16 | - via bower: by running ``` $ bower install angular-spinner ``` from your console
17 |
18 | Include angular-spinner.js in your application.
19 |
20 | ```js
21 | import 'angular-spinner';
22 |
23 | OR:
24 |
25 | require('angular-spinner');
26 | ```
27 |
28 | OR by picking one of the following file (depends on the package manager):
29 |
30 | ```html
31 |
32 |
33 | ```
34 |
35 | Add the module `angularSpinner` as a dependency to your app module:
36 |
37 | ```js
38 | var myapp = angular.module('myapp', ['angularSpinner']);
39 | ```
40 |
41 | You can now start using the us-spinner directive to display an animated
42 | spinner. For example :
43 |
44 | ```html
45 |
46 | ```
47 |
48 | You can also pass spinner options, for example:
49 |
50 | ```html
51 |
52 | ```
53 |
54 | Possible configuration options are described in the [spin.js homepage](http://fgnass.github.io/spin.js/).
55 |
56 | You can direct the spinner to start and stop based on a scope expression, for example:
57 |
58 | ```html
59 |
60 | ```
61 |
62 |
63 | ### Configuring default spinner options
64 |
65 | You can use `usSpinnerConfigProvider` to configure default options for all spinners globally. Any options passed from a directive still override these.
66 |
67 | ```js
68 | myapp.config(['usSpinnerConfigProvider', function (usSpinnerConfigProvider) {
69 | usSpinnerConfigProvider.setDefaults({color: 'blue'});
70 | }]);
71 | ```
72 |
73 | ## Themes
74 |
75 | Themes provide named default options for spinners. Any options passed from a directive still override these.
76 |
77 | ```js
78 | myapp.config(['usSpinnerConfigProvider', function (usSpinnerConfigProvider) {
79 | usSpinnerConfigProvider.setTheme('bigBlue', {color: 'blue', radius: 20});
80 | usSpinnerConfigProvider.setTheme('smallRed', {color: 'red', radius: 6});
81 | }]);
82 | ```
83 |
84 | ```html
85 |
86 | ```
87 |
88 | ### Using the usSpinnerService to control spinners
89 |
90 | ```html
91 |
92 |
93 |
94 |
95 | ```
96 |
97 | The `usSpinnerService` service let you control spin start and stop by key.
98 | Whenever the key is not specified all the spinner will be affected (Start/Stop all spinners):
99 |
100 | ```js
101 | app.controller('MyController', ['$scope', 'usSpinnerService', function($scope, usSpinnerService){
102 | $scope.startSpin = function(){
103 | usSpinnerService.spin('spinner-1');
104 | }
105 | $scope.stopSpin = function(){
106 | usSpinnerService.stop('spinner-1');
107 | }
108 | }]);
109 | ```
110 |
111 | Note that when you specify a key, the spinner is rendered inactive.
112 | You can still render the spinner as active with the spinner-start-active parameter :
113 | ```html
114 |
115 | ```
116 |
117 | spinner-start-active is ignored if spinner-on is specified.
118 |
119 | The spinner-key will be used as an identifier (not unique) allowing you to have several spinners controlled by the same key :
120 |
121 | ```html
122 |
123 |
124 |
125 | ... random html code ...
126 |
127 |
128 |
129 | ```
130 |
131 | ### Example
132 |
133 | See [online example on Plunker](http://plnkr.co/edit/OUJTJbtG2F0VUvnIk1dv?p=preview).
134 |
135 | ## License
136 |
137 | Released under the terms of MIT License.
138 |
139 | ## Contributing
140 |
141 | 1. Fork repo.
142 | 2. `npm i`
143 | 3. Make your changes, add your tests.
144 | 4. `npm run test`
145 | 5. `npm run build` once all tests are passing. Commit, push, PR.
146 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | /* License: MIT.
2 | * Copyright (C) 2013, 2014, Uri Shaked and contributors.
3 | */
4 |
5 | 'use strict';
6 |
7 | var webpackConf = require('./webpack.config.js');
8 |
9 | webpackConf.entry = {};
10 | webpackConf.module.postLoaders = [
11 | {
12 | test: /\.ts$/,
13 | loader: 'istanbul-instrumenter-loader',
14 | exclude: [
15 | 'node_modules',
16 | /test/
17 | ]
18 | }
19 | ];
20 |
21 | module.exports = function (config) {
22 | config.set({
23 | basePath: '',
24 | frameworks: ['jasmine', 'source-map-support'],
25 | logLevel: config.LOG_INFO,
26 | browsers: ['PhantomJS'],
27 | singleRun: true,
28 | reporters: ['dots', 'coverage'],
29 | files: [
30 | 'node_modules/angular/angular.js',
31 | 'node_modules/angular-mocks/angular-mocks.js',
32 | 'src/angular-spinner.ts',
33 | 'test/index.ts'
34 | ],
35 | webpack: webpackConf,
36 | preprocessors: {
37 | 'src/angular-spinner.ts': ['webpack'],
38 | 'test/index.ts': ['webpack']
39 | },
40 | coverageReporter: {
41 | type: 'lcov',
42 | dir: 'coverage/'
43 | },
44 | mime: {
45 | 'text/x-typescript': ['ts']
46 | }
47 | });
48 | };
49 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-spinner",
3 | "version": "1.0.1",
4 | "repository": {
5 | "type": "git",
6 | "url": "http://github.com/urish/angular-spinner.git"
7 | },
8 | "main": "./dist/angular-spinner.js",
9 | "dependencies": {
10 | "spin.js": "2.3.2"
11 | },
12 | "scripts": {
13 | "clean": "rimraf ./dist",
14 | "build": "npm run clean && npm run build:browser && npm run build:browser:debug",
15 | "build:browser": "webpack ./src/angular-spinner.ts ./dist/angular-spinner.min.js --output-library-target=\"umd\" -p --config webpack.production.config.js",
16 | "build:browser:debug": "webpack ./src/angular-spinner.ts ./dist/angular-spinner.js --output-library-target=\"umd\" -d",
17 | "prepublish": "npm run build",
18 | "test": "karma start karma.conf.js"
19 | },
20 | "license": "MIT",
21 | "devDependencies": {
22 | "@types/angular": "1.6.1",
23 | "@types/angular-mocks": "1.5.8",
24 | "@types/jasmine": "2.5.40",
25 | "@types/jquery": "2.0.39",
26 | "@types/spin.js": "2.3.0",
27 | "angular": "1.6.1",
28 | "angular-mocks": "1.6.1",
29 | "coveralls": "2.11.15",
30 | "istanbul-instrumenter-loader": "1.0.0",
31 | "jasmine": "2.5.3",
32 | "karma": "1.3.0",
33 | "karma-coverage": "1.1.1",
34 | "karma-jasmine": "1.1.0",
35 | "karma-phantomjs-launcher": "1.0.2",
36 | "karma-source-map-support": "1.2.0",
37 | "karma-sourcemap-loader": "0.3.7",
38 | "karma-webpack": "2.0.1",
39 | "rimraf": "2.5.4",
40 | "ts-loader": "1.3.3",
41 | "typescript": "2.1.5",
42 | "webpack": "1.14.0"
43 | },
44 | "engines": {
45 | "node": ">=0.10.0"
46 | },
47 | "files": [
48 | "dist/"
49 | ]
50 | }
51 |
--------------------------------------------------------------------------------
/src/Config/UsSpinnerConfig.ts:
--------------------------------------------------------------------------------
1 | import { IUsSpinnerConfig } from '../Interfaces/IUsSpinnerConfig';
2 |
3 | /**
4 | * UsSpinnerConfig
5 | */
6 | export class UsSpinnerConfig implements ng.IServiceProvider, IUsSpinnerConfig {
7 |
8 | config:SpinnerOptions;
9 | themes: {
10 | [name: string]: SpinnerOptions;
11 | }
12 |
13 | constructor() {
14 | this.config = {};
15 | this.themes = {};
16 | }
17 |
18 | setDefaults(config:SpinnerOptions) {
19 | this.config = config || this.config;
20 | }
21 |
22 | setTheme(name:string, config:SpinnerOptions) {
23 | this.themes[name] = config;
24 | }
25 |
26 | $get () {
27 | let { config, themes } = this;
28 |
29 | return {
30 | config,
31 | themes
32 | };
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/src/Constants/SpinJSSpinner.ts:
--------------------------------------------------------------------------------
1 | import Spinner = require('spin.js');
2 |
3 | /**
4 | * Exporting the Spinner prototype from spin.js library
5 | */
6 | export const SpinJSSpinner = Spinner;
7 |
--------------------------------------------------------------------------------
/src/Directives/AngularSpinner.ts:
--------------------------------------------------------------------------------
1 | import { IUsSpinnerConfig } from '../Interfaces/IUsSpinnerConfig';
2 | import { IUsSpinnerAttributes } from '../Interfaces/IUsSpinnerAttributes';
3 | import { IUsSpinnerScope } from '../Interfaces/IUsSpinnerScope';
4 | import * as angular from 'angular';
5 |
6 | export const usSpinner = (SpinJSSpinner:typeof Spinner, usSpinnerConfig:IUsSpinnerConfig) => {
7 |
8 | return {
9 | scope: true,
10 | link: (scope:IUsSpinnerScope, element:ng.IAugmentedJQuery, attr:IUsSpinnerAttributes) => {
11 | scope.spinner = null;
12 |
13 | scope.key = angular.isDefined(attr.spinnerKey) ? attr.spinnerKey : false;
14 |
15 | scope.startActive = (attr.spinnerStartActive) ?
16 | scope.$eval(attr.spinnerStartActive) : scope.key ?
17 | false : true;
18 |
19 | function stopSpinner() {
20 | if (scope.spinner) {
21 | scope.spinner.stop();
22 | }
23 | }
24 |
25 | scope.spin = () => {
26 | if (scope.spinner) {
27 | scope.spinner.spin(element[0]);
28 | }
29 | };
30 |
31 | scope.stop = () => {
32 | scope.startActive = false;
33 | stopSpinner();
34 | };
35 |
36 | scope.$watch(attr.usSpinner, (options:SpinnerOptions) => {
37 | stopSpinner();
38 |
39 | // order of precedence: element options, theme, defaults.
40 | options = angular.extend(
41 | {},
42 | usSpinnerConfig.config,
43 | attr.spinnerTheme ? usSpinnerConfig.themes[attr.spinnerTheme] : undefined,
44 | options);
45 |
46 | scope.spinner = new SpinJSSpinner(options);
47 | if ((!scope.key || scope.startActive) && !attr.spinnerOn) {
48 | scope.spinner.spin(element[0]);
49 | }
50 | }, true);
51 |
52 | if (attr.spinnerOn) {
53 | scope.$watch(attr.spinnerOn, (spin) => {
54 | if (spin) {
55 | scope.spin();
56 | } else {
57 | scope.stop();
58 | }
59 | });
60 | }
61 |
62 | scope.$on('us-spinner:spin', (event, key) => {
63 | if (!key || key === scope.key) {
64 | scope.spin();
65 | }
66 | });
67 |
68 | scope.$on('us-spinner:stop', (event, key) => {
69 | if (!key || key === scope.key) {
70 | scope.stop();
71 | }
72 | });
73 |
74 | scope.$on('$destroy', () => {
75 | scope.stop();
76 | scope.spinner = null;
77 | });
78 | }
79 | };
80 | }
81 |
82 | usSpinner.$inject = ['SpinJSSpinner', 'usSpinnerConfig'];
83 |
--------------------------------------------------------------------------------
/src/Interfaces/IUsSpinnerAttributes.d.ts:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * UsSpinner directive attributes interface
4 | * @extends ng.IAttributes
5 | */
6 | export interface IUsSpinnerAttributes extends ng.IAttributes {
7 | /**
8 | * The spinner-key will be used as an identifier (not unique) allowing you to have several spinners controlled by the same key
9 | */
10 | spinnerKey?:string,
11 | /**
12 | * Render the spinner as active if true
13 | * spinner-start-active is ignored if spinner-on is specified
14 | */
15 | spinnerStartActive?:string,
16 | /**
17 | * Specifies the spinner theme name to use in this usSpinner directive instance
18 | */
19 | spinnerTheme?:string,
20 | /**
21 | * usSpinner directive (can also include Spinner options)
22 | */
23 | usSpinner:string,
24 | /**
25 | * Spinner-on expression to evaluate and when gets true the spinner been activated
26 | */
27 | spinnerOn:string
28 | }
29 |
--------------------------------------------------------------------------------
/src/Interfaces/IUsSpinnerConfig.d.ts:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * UsSpinnerConfig interface
4 | */
5 | export interface IUsSpinnerConfig {
6 | /**
7 | * Configure default options for all spinners globally
8 | * Any options passed from a directive still override these
9 | * @param config - Spinner options configuration
10 | */
11 | setDefaults(config:SpinnerOptions);
12 | /**
13 | * Themes provide method named default options for spinners.
14 | * Any options passed from a directive still override these
15 | * @param name - Theme name
16 | * @param config - Spinner options configuration
17 | */
18 | setTheme(name:string, config:SpinnerOptions);
19 | /**
20 | * Spinner default options
21 | */
22 | config:SpinnerOptions;
23 | /**
24 | * Spinner options for spinners
25 | */
26 | themes: {
27 | [name: string]: SpinnerOptions;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/Interfaces/IUsSpinnerScope.d.ts:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * UsSpinner directive scope interface
4 | * @extends ng.IScope
5 | */
6 | export interface IUsSpinnerScope extends ng.IScope {
7 | startActive:boolean,
8 | spin(),
9 | stop(),
10 | spinner:Spinner | null,
11 | key:string | false | undefined
12 | }
13 |
--------------------------------------------------------------------------------
/src/Interfaces/IUsSpinnerService.d.ts:
--------------------------------------------------------------------------------
1 |
2 | /**
3 | * UsSpinnerService interface
4 | * This service will allow you to control spinner element(s) by appended keys
5 | * You can append multiple key with two spinners and they will be triggered together
6 | */
7 | export interface IUsSpinnerService {
8 | /**
9 | * Spins spinner element(s) which is linked with the passed @key
10 | * If @key is not supplied all us-spinner directive will be triggered to spin
11 | * @param key - A key which is linked with spinner items to controll them
12 | */
13 | spin(key?:string);
14 | /**
15 | * Stops the spinner element(s) which is linked with the passed @key
16 | * If @key is not supplied all us-spinner directive will be triggered to stop
17 | * @param key - A key which is linked with spinner items to controll them
18 | */
19 | stop(key?:string);
20 | }
21 |
--------------------------------------------------------------------------------
/src/Services/UsSpinnerService.ts:
--------------------------------------------------------------------------------
1 | import { IUsSpinnerService } from '../Interfaces/IUsSpinnerService';
2 |
3 | /**
4 | * UsSpinnerService
5 | * This service let you control spin, start and stop
6 | */
7 | export class UsSpinnerService implements IUsSpinnerService {
8 |
9 | constructor(private $rootScope:ng.IRootScopeService) {}
10 | static $inject = ['$rootScope'];
11 |
12 | spin(key?:string) {
13 | this.$rootScope.$broadcast('us-spinner:spin', key);
14 | }
15 |
16 | stop(key?:string) {
17 | this.$rootScope.$broadcast('us-spinner:stop', key);
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/src/angular-spinner.ts:
--------------------------------------------------------------------------------
1 | import { SpinJSSpinner } from './Constants/SpinJSSpinner';
2 | import { UsSpinnerService } from './Services/UsSpinnerService';
3 | import { usSpinner } from './Directives/AngularSpinner';
4 | import { UsSpinnerConfig } from './Config/UsSpinnerConfig';
5 | import * as angular from 'angular';
6 |
7 | export const angularSpinner = angular
8 | .module('angularSpinner', [])
9 | .provider('usSpinnerConfig', UsSpinnerConfig)
10 | .constant('SpinJSSpinner', SpinJSSpinner)
11 | .service('usSpinnerService', UsSpinnerService)
12 | .directive('usSpinner', usSpinner);
13 |
--------------------------------------------------------------------------------
/test/Config/UsSpinnerConfig.test.ts:
--------------------------------------------------------------------------------
1 | import * as angular from 'angular';
2 | import { IUsSpinnerConfig } from '../../src/Interfaces/IUsSpinnerConfig';
3 |
4 | beforeEach(angular.mock.module('angularSpinner'));
5 |
6 | describe('Provider: usSpinnerConfigProvider', function () {
7 | it('should have configurable options', function () {
8 | angular.mock.module(function (usSpinnerConfigProvider:IUsSpinnerConfig) {
9 | usSpinnerConfigProvider.setDefaults({color: 'black'});
10 | });
11 |
12 | inject(function (usSpinnerConfig:IUsSpinnerConfig) {
13 | expect(usSpinnerConfig.config.color).toBe('black');
14 | });
15 | });
16 | it('should support themes', function () {
17 | angular.mock.module(function (usSpinnerConfigProvider:IUsSpinnerConfig) {
18 | usSpinnerConfigProvider.setTheme('bigRed', {color: 'red', speed: 2});
19 | });
20 |
21 | inject(function (usSpinnerConfig:IUsSpinnerConfig) {
22 | expect(usSpinnerConfig.themes['bigRed'].color).toBe('red');
23 | });
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/test/Directives/AngularSpinner.test.ts:
--------------------------------------------------------------------------------
1 | import * as angular from 'angular';
2 | import { IUsSpinnerConfig } from '../../src/Interfaces/IUsSpinnerConfig';
3 | import { IUsSpinnerService } from '../../src/Interfaces/IUsSpinnerService';
4 |
5 | beforeEach(angular.mock.module('angularSpinner'));
6 |
7 | describe('Directive: us-spinner', function () {
8 | var Spinner;
9 |
10 | beforeEach(angular.mock.module(function ($provide:ng.auto.IProvideService) {
11 | Spinner = jasmine.createSpy('Spinner');
12 | Spinner.prototype.spin = jasmine.createSpy('Spinner.spin');
13 | Spinner.prototype.stop = jasmine.createSpy('Spinner.stop');
14 |
15 | $provide.constant('SpinJSSpinner', Spinner);
16 | }));
17 |
18 | it('should create a spinner object',
19 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
20 | var element = angular.element('');
21 | element = $compile(element)($rootScope);
22 | $rootScope.$digest();
23 | expect(Spinner).toHaveBeenCalled();
24 | }));
25 |
26 | it('should start spinning the spinner automatically',
27 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
28 | var element = angular.element('');
29 | element = $compile(element)($rootScope);
30 | $rootScope.$digest();
31 | expect(Spinner.prototype.spin).toHaveBeenCalled();
32 | expect(Spinner.prototype.stop).not.toHaveBeenCalled();
33 | }));
34 |
35 | it('should start spinning the second spinner without stopping the first one',
36 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
37 | var element = angular.element('');
38 | element = $compile(element)($rootScope);
39 | var secondElement = angular.element('');
40 | secondElement = $compile(secondElement)($rootScope);
41 | $rootScope.$digest();
42 | expect(Spinner.prototype.spin.calls.count()).toBe(2);
43 | expect(Spinner.prototype.stop).not.toHaveBeenCalled();
44 | }));
45 |
46 | it('should set spinner options as given in attribute',
47 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
48 | var element = angular.element('');
49 | element = $compile(element)($rootScope);
50 | $rootScope.$digest();
51 | expect(Spinner).toHaveBeenCalledWith({width: 15});
52 | }));
53 |
54 | describe('with default options', function() {
55 | beforeEach(angular.mock.module(function(usSpinnerConfigProvider:IUsSpinnerConfig) {
56 | usSpinnerConfigProvider.setDefaults({width: 10, color: 'black'});
57 | }));
58 |
59 | it('should add spinner default options to options',
60 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
61 | var element = angular.element('');
62 | element = $compile(element)($rootScope);
63 | $rootScope.$digest();
64 | expect(Spinner).toHaveBeenCalledWith({width: 15, color: 'black'});
65 | }));
66 |
67 | describe('and with theme options', function() {
68 | beforeEach(angular.mock.module(function(usSpinnerConfigProvider:IUsSpinnerConfig) {
69 | usSpinnerConfigProvider.setTheme('bigRed', {speed: 20, color: 'red'});
70 | }));
71 |
72 | it('should add theme options to options',
73 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
74 | var element = angular.element('');
75 | element = $compile(element)($rootScope);
76 | $rootScope.$digest();
77 | expect(Spinner).toHaveBeenCalledWith({width: 15, color: 'red', speed: 20});
78 | }));
79 |
80 | it('should not change default options by spinner options or theme options',
81 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService, usSpinnerConfig:IUsSpinnerConfig) {
82 | var element = angular.element('');
83 | element = $compile(element)($rootScope);
84 | $rootScope.$digest();
85 | expect(usSpinnerConfig.config).toEqual({width: 10, color: 'black'});
86 | }));
87 | });
88 | });
89 |
90 | it('should update spinner options in response to scope updates',
91 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
92 | $rootScope['actualWidth'] = 25;
93 | var element = angular.element('');
94 | element = $compile(element)($rootScope);
95 | $rootScope.$digest();
96 | expect(Spinner).toHaveBeenCalledWith({width: 25});
97 | expect(Spinner.prototype.stop).not.toHaveBeenCalled();
98 |
99 | $rootScope['actualWidth'] = 72;
100 | $rootScope.$digest();
101 | expect(Spinner).toHaveBeenCalledWith({width: 72});
102 | expect(Spinner.prototype.stop).toHaveBeenCalled();
103 | expect(Spinner.prototype.spin.calls.count()).toBe(2);
104 | }));
105 |
106 | it('should spin in response to scope updates',
107 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
108 | $rootScope['shouldSpin'] = false;
109 | var element = angular.element('');
110 | element = $compile(element)($rootScope);
111 | $rootScope.$digest();
112 | expect(Spinner).toHaveBeenCalled();
113 | expect(Spinner.prototype.spin).not.toHaveBeenCalled();
114 |
115 | $rootScope['shouldSpin'] = true;
116 | $rootScope.$digest();
117 | expect(Spinner.prototype.spin).toHaveBeenCalled();
118 | }));
119 |
120 | it('should stop the spinner when the scope is destroyed',
121 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
122 | var scope = $rootScope.$new();
123 | var element = angular.element('');
124 | element = $compile(element)(scope);
125 | $rootScope.$digest();
126 | expect(Spinner.prototype.stop).not.toHaveBeenCalled();
127 | scope.$destroy();
128 | expect(Spinner.prototype.stop).toHaveBeenCalled();
129 | }));
130 |
131 | it('should not start spinning automatically',
132 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
133 | var element = angular.element('');
134 | element = $compile(element)($rootScope);
135 | $rootScope.$digest();
136 | expect(Spinner.prototype.spin).not.toHaveBeenCalled();
137 | }));
138 |
139 | it('should start spinning when service trigger the spin event',
140 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService, usSpinnerService:IUsSpinnerService) {
141 | var element = angular.element('');
142 | element = $compile(element)($rootScope);
143 | $rootScope.$digest();
144 | expect(Spinner.prototype.spin).not.toHaveBeenCalled();
145 | usSpinnerService.spin('spinner');
146 | expect(Spinner.prototype.spin).toHaveBeenCalled();
147 | }));
148 |
149 | it('should start spinning the spinner automatically and stop when service trigger the stop event',
150 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService, usSpinnerService:IUsSpinnerService) {
151 | var element = angular.element('');
152 | element = $compile(element)($rootScope);
153 | $rootScope.$digest();
154 | expect(Spinner.prototype.spin).toHaveBeenCalled();
155 | usSpinnerService.stop('spinner');
156 | expect(Spinner.prototype.stop).toHaveBeenCalled();
157 | }));
158 |
159 | it('should not start spinning the spinner automatically from binding',
160 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
161 | $rootScope['spinnerActive'] = false;
162 | var element = angular.element('');
163 | element = $compile(element)($rootScope);
164 | $rootScope.$digest();
165 | expect(Spinner.prototype.spin).not.toHaveBeenCalled();
166 | }));
167 |
168 | it('should start spinning the spinner automatically from binding',
169 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService) {
170 | $rootScope['spinnerActive'] = true;
171 | var element = angular.element('');
172 | element = $compile(element)($rootScope);
173 | $rootScope.$digest();
174 | expect(Spinner.prototype.spin).toHaveBeenCalled();
175 | }));
176 |
177 | it('should start spinning the second spinner without starting the first one',
178 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService, usSpinnerService:IUsSpinnerService) {
179 | var element = angular.element('');
180 | element = $compile(element)($rootScope);
181 | var secondElement = angular.element('');
182 | secondElement = $compile(secondElement)($rootScope);
183 | $rootScope.$digest();
184 | usSpinnerService.spin('spinner2');
185 | expect(Spinner.prototype.spin.calls.count()).toBe(1);
186 | expect(Spinner.prototype.stop).not.toHaveBeenCalled();
187 | }));
188 |
189 | it('should start spinning the spinners with the same key',
190 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService, usSpinnerService:IUsSpinnerService) {
191 | $compile('')($rootScope);
192 | $compile('')($rootScope);
193 | $compile('')($rootScope);
194 | $compile('')($rootScope);
195 | $compile('')($rootScope);
196 | $rootScope.$digest();
197 | usSpinnerService.spin('spinner');
198 | expect(Spinner.prototype.spin.calls.count()).toBe(3);
199 | expect(Spinner.prototype.stop).not.toHaveBeenCalled();
200 | usSpinnerService.stop('spinner');
201 | expect(Spinner.prototype.stop.calls.count()).toBe(3);
202 | usSpinnerService.spin('spinner2');
203 | expect(Spinner.prototype.spin.calls.count()).toBe(5);
204 | usSpinnerService.stop('spinner2');
205 | expect(Spinner.prototype.stop.calls.count()).toBe(5);
206 | }));
207 |
208 | //Feature: Stop all/Start all spinners - Issue #28
209 | it('should start spinning all the spinners when usSpinnerService.spin() is called without specific key',
210 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService, usSpinnerService:IUsSpinnerService) {
211 | $compile('')($rootScope);
212 | $compile('')($rootScope);
213 | $compile('')($rootScope);
214 | $compile('')($rootScope);
215 | $compile('')($rootScope);
216 | $rootScope.$digest();
217 | usSpinnerService.spin();
218 | expect(Spinner.prototype.spin.calls.count()).toBe(5);
219 | expect(Spinner.prototype.stop).not.toHaveBeenCalled();
220 | }));
221 |
222 | //Feature: Stop all/Start all spinners - Issue #28
223 | it('should stop spinning all the spinners when usSpinnerService.stop() is called without specific key',
224 | inject(function ($rootScope:ng.IRootScopeService, $compile:ng.ICompileService, usSpinnerService:IUsSpinnerService) {
225 | $compile('')($rootScope);
226 | $compile('')($rootScope);
227 | $compile('')($rootScope);
228 | $compile('')($rootScope);
229 | $compile('')($rootScope);
230 | $rootScope.$digest();
231 | usSpinnerService.stop();
232 | expect(Spinner.prototype.stop.calls.count()).toBe(5);
233 | expect(Spinner.prototype.spin).not.toHaveBeenCalled();
234 | }));
235 |
236 | });
237 |
--------------------------------------------------------------------------------
/test/index.ts:
--------------------------------------------------------------------------------
1 | import './Config/UsSpinnerConfig.test';
2 | import './Directives/AngularSpinner.test';
3 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es5",
5 | "strictNullChecks": true,
6 | "sourceMap": true
7 | },
8 | "include": [
9 | "src",
10 | "test"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 |
2 | var webpack = require('webpack');
3 |
4 | module.exports = {
5 | devtool: 'inline-source-map',
6 | resolve: {
7 | // Add `.ts` as a resolvable extension.
8 | extensions: ['', '.webpack.js', '.web.js', '.ts', '.js']
9 | },
10 | externals: {
11 | // require("angular") is external and available
12 | // on the global var angular
13 | "angular": "angular"
14 | },
15 | module: {
16 | loaders: [
17 | // all files with a `.ts` extension will be handled by `ts-loader`
18 | { test: /\.ts$/, loader: 'ts-loader' }
19 | ]
20 | },
21 | plugins: [
22 | // existing plugins go here
23 | new webpack.SourceMapDevToolPlugin({
24 | filename: null, // if no value is provided the sourcemap is inlined
25 | test: /\.(ts)($|\?)/i // process .ts files only
26 | })
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/webpack.production.config.js:
--------------------------------------------------------------------------------
1 |
2 | var webpack = require('webpack');
3 | var webpackConfig = require('./webpack.config.js');
4 |
5 | //Remove sourcemaps from production version
6 | webpackConfig.devtool = undefined;
7 | webpackConfig.plugins = undefined;
8 | webpackConfig.ts = {
9 | compilerOptions: {
10 | "sourceMap": false
11 | }
12 | };
13 |
14 | module.exports = webpackConfig;
15 |
--------------------------------------------------------------------------------