From 8cb37040d0cc29e42070553c6909609cd4a1d01e Mon Sep 17 00:00:00 2001 From: Guoqiang Chen Date: Tue, 6 Oct 2015 08:42:52 +0000 Subject: [PATCH] 1.0.0 released --- .gitignore | 13 ++ .npmignore | 6 + LICENSE | 201 +++++++++++++++++++++++++ README.md | 153 +++++++++++++++++++ angular-async-loader.js | 153 +++++++++++++++++++ package.json | 28 ++++ sample/README.md | 14 ++ sample/package.json | 14 ++ sample/server.js | 9 ++ sample/webapp/app-routes.js | 30 ++++ sample/webapp/app.js | 12 ++ sample/webapp/bootstrap.js | 19 +++ sample/webapp/home/home.html | 6 + sample/webapp/home/homeCtrl.js | 7 + sample/webapp/index.html | 21 +++ sample/webapp/services/usersService.js | 19 +++ sample/webapp/users/users.html | 9 ++ sample/webapp/users/usersCtrl.js | 10 ++ 18 files changed, 724 insertions(+) create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 angular-async-loader.js create mode 100644 package.json create mode 100644 sample/README.md create mode 100644 sample/package.json create mode 100644 sample/server.js create mode 100644 sample/webapp/app-routes.js create mode 100644 sample/webapp/app.js create mode 100644 sample/webapp/bootstrap.js create mode 100644 sample/webapp/home/home.html create mode 100644 sample/webapp/home/homeCtrl.js create mode 100644 sample/webapp/index.html create mode 100644 sample/webapp/services/usersService.js create mode 100644 sample/webapp/users/users.html create mode 100644 sample/webapp/users/usersCtrl.js diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..509d138 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +node_modules/ +coverage/ +*.log + +.idea/ +*.iml +*.iws + +.settings/ +.project +.classpath + +.DS_Store diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..3796797 --- /dev/null +++ b/.npmignore @@ -0,0 +1,6 @@ +.idea/ +node_modules/ +sample/ + +.DS_Store +.gitignore diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8dada3e --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright {yyyy} {name of copyright owner} + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..2f6d2c9 --- /dev/null +++ b/README.md @@ -0,0 +1,153 @@ +[![NPM Repo](https://img.shields.io/npm/v/angular-async-loader.svg)](https://www.npmjs.com/package/angular-async-loader) +[![License](http://img.shields.io/badge/License-Apache_2-red.svg?style=flat)](http://www.apache.org/licenses/LICENSE-2.0) + +# angular-async-loader + +async loader for angular 1.x. + +Support following components to dynamic register: + +* controller +* services +* filter +* directive +* value +* constant +* provider +* decorator + +And we can use following loader: + +* Require.js +* Sea.js +* System.js + + +# Installation + +```shell +npm install angular-async-loader +``` + +# Usage + +See Sample: https://github.com/subchen/angular-async-loader/blob/master/sample/ + +**index.html** + +``` + + +``` + +**bootstrap.js** + +```js +require.config({ + baseUrl: '/', + paths: { + 'angular': 'assets/angular/angular.min', + 'angular-ui-router': 'assets/angular-ui-router/release/angular-ui-router.min', + 'angular-async-loader': 'assets/angular-async-loader/angular-async-loader' + }, + shim: { + 'angular': {exports: 'angular'}, + 'angular-ui-router': {deps: ['angular']} + } +}); + +require(['angular', './app-routes'], function (angular) { + angular.element(document).ready(function () { + angular.bootstrap(document, ['app']); + angular.element(document).find('html').addClass('ng-app'); + }); +}); +``` + +**app.js** + +```js +define(function (require, exports, module) { + var angular = require('angular'); + var asyncLoader = require('angular-async-loader'); + + require('angular-ui-router'); + + var app = angular.module('app', ['ui.router']); + + // initialze app module for async loader + asyncLoader.configure(app); + + module.exports = app; +}); +``` + +**app-routes.js** + +```js +define(function (require) { + var app = require('./app'); + + app.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) { + $urlRouterProvider.otherwise('/home'); + + $stateProvider + .state('home', { + url: '/home', + templateUrl: 'home/home.html', + controller: 'homeCtrl', + resolve: { + // async load controller + dummy: app.load('./home/homeCtrl') + } + }) + .state('users', { + url: '/users', + templateUrl: 'users/users.html', + controller: 'usersCtrl', + resolve: { + // async load controller, services, ... + dummy: app.load(['./users/usersCtrl', './services/usersService']) + } + }); + }]); +}); +``` + +**users/usersCtrl.js** + +```js +define(function (require) { + var app = require('../app'); + + require('../services/usersService'); + + app.controller('usersCtrl', ['$scope', function ($scope) { + // shortcut to get angular injected service. + var userServices = app.get('usersService'); + + $scope.userList = usersService.list(); + }]); + +}); +``` + +# License + +Released under the [Apache 2 License](http://www.apache.org/licenses/LICENSE-2.0). + +``` +Copyright 2015 Guoqiang Chen + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +``` diff --git a/angular-async-loader.js b/angular-async-loader.js new file mode 100644 index 0000000..b85ad8c --- /dev/null +++ b/angular-async-loader.js @@ -0,0 +1,153 @@ +/** + * async loader for angular 1.x. + * + * https://github.com/subchen/angular-async-loader + * subchen@gmail.com + */ +(function () { + + function factory(angular, undefined) { + + return { + VERSION: '1.0.0', + + configure: function (app) { + + // Support require.js, sea.js, system.js + if (app.require === undefined) { + if (typeof(require) === 'function') { + if (typeof(require.async) === 'function') { + app.require = require.async; + } else { + app.require = require; + } + } else if (typeof(seajs) === 'object' && typeof (seajs.use) === 'function') { + app.require = seajs.use; + } else if (typeof(System) === 'object' && typeof (System.import) === 'function') { + app.require = System.import; + } + } + + app.provider('$asyncLoader', [ + '$controllerProvider', + '$compileProvider', + '$provide', + '$filterProvider', + function ($controllerProvider, + $compileProvider, + $provide, + $filterProvider) { + this.$get = function () { + return { + $controllerProvider: $controllerProvider, + $compileProvider: $compileProvider, + $provide: $provide, + $filterProvider: $filterProvider + }; + }; + }]); + + app.run(['$asyncLoader', function ($asyncLoader) { + var $controllerProvider = $asyncLoader.$controllerProvider; + var $compileProvider = $asyncLoader.$compileProvider; + var $provide = $asyncLoader.$provide; + var $filterProvider = $asyncLoader.$filterProvider; + + app.value = function (name, value) { + $provide.value.apply(null, [name, value]); + }; + + app.constant = function (name, value) { + $provide.value.apply(null, [name, value]); + }; + + app.factory = function (name, factory) { + $provide.factory.apply(null, [name, factory]); + }; + + app.service = function (name, service) { + $provide.service.apply(null, [name, service]); + }; + + app.filter = function (name, filter) { + $filterProvider.register.apply(null, [name, filter]); + }; + + app.directive = function (name, directive) { + $compileProvider.directive.apply(null, [name, directive]); + }; + + app.controller = function (name, controller) { + $controllerProvider.register.apply(null, [name, controller]); + }; + + app.decorator = function (name, decorator) { + $provide.decorator.apply(null, [name, decorator]); + }; + + app.provider = function (name, service) { + $provide.provider.apply(null, [name, service]); + }; + }]); + + + /** + * Load external resources, such as Controller, Service, etc. + * + * @param {String|Array} dependencies + * @returns {*} + */ + app.load = function (dependencies) { + if (!angular.isArray(dependencies)) { + dependencies = [dependencies]; + } + + return ['$q', '$rootScope', function ($q, $rootScope) { + var defer = $q.defer(); + app.require(dependencies, function () { + var out = arguments[arguments.length - 1]; + defer.resolve(out); + $rootScope.$apply(); + }); + return defer.promise; + }]; + }; + + + var injector; + + /** + * Get angular injector object by name. + * + * @param {String} name + * @returns {*} + */ + app.get = function (name) { + if (injector === undefined) { + var elements = [app.element, document, 'html', 'body']; + for (var i = 0; i < elements.length; i++) { + injector = angular.element(elements[i]).injector(); + if (injector !== undefined) { + break; + } + } + } + return injector.get(name); + }; + + } + }; + } + + /** + * @exports + */ + if (typeof(define) === 'function' && define.amd) { + define(['angular'], function (angular) { + return factory(angular); + }); + } else { + window.asyncLoader = factory(window.angular); + } + +}()); diff --git a/package.json b/package.json new file mode 100644 index 0000000..3cb466d --- /dev/null +++ b/package.json @@ -0,0 +1,28 @@ +{ + "name": "angular-async-loader", + "version": "1.0.0", + "description": "async loader for angular 1.x", + "author": { + "name": "Guoqiang Chen", + "email": "subchen@gmail.com", + "url": "https://github.com/subchen" + }, + "contributors": [], + "license": "Apache-2.0", + "repository": { + "type": "git", + "url": "https://github.com/subchen/angular-async-loader.git" + }, + "bugs": { + "url": "https://github.com/subchen/angular-async-loader/issues" + }, + "keywords": [ + "angular", + "requirejs", + "systemjs", + "seajs", + "async" + ], + "dependencies": { + } +} diff --git a/sample/README.md b/sample/README.md new file mode 100644 index 0000000..8658462 --- /dev/null +++ b/sample/README.md @@ -0,0 +1,14 @@ +To run sample +============== + +```bash + +git clone https://github.com/subchen/angular-async-loader + +cd angular-async-loader/sample + +npm install +npm start + +open browser: http://127.0.0.1:8080/ +``` diff --git a/sample/package.json b/sample/package.json new file mode 100644 index 0000000..cc68488 --- /dev/null +++ b/sample/package.json @@ -0,0 +1,14 @@ +{ + "name": "angular-async-loader-sample", + "version": "1.0.0", + "dependencies": { + "angular": "^1.4.7", + "angular-async-loader": "file:..", + "angular-ui-router": "^0.2.15", + "express": "^4.13.3", + "requirejs": "^2.1.20" + }, + "scripts": { + "start": "node server.js" + } +} diff --git a/sample/server.js b/sample/server.js new file mode 100644 index 0000000..4670893 --- /dev/null +++ b/sample/server.js @@ -0,0 +1,9 @@ +var express = require('express'); +var app = express(); + +app.use('/', express.static(__dirname + '/webapp')); +app.use('/assets', express.static(__dirname + '/node_modules')); + +app.listen(8080, function() { + console.log('listening on http://localhost:8080/'); +}); diff --git a/sample/webapp/app-routes.js b/sample/webapp/app-routes.js new file mode 100644 index 0000000..47228cb --- /dev/null +++ b/sample/webapp/app-routes.js @@ -0,0 +1,30 @@ +define(function (require) { + var app = require('./app'); + + app.run(['$state', '$stateParams', '$rootScope', function ($state, $stateParams, $rootScope) { + $rootScope.$state = $state; + $rootScope.$stateParams = $stateParams; + }]); + + app.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) { + $urlRouterProvider.otherwise('/home'); + + $stateProvider + .state('home', { + url: '/home', + templateUrl: 'home/home.html', + controller: 'homeCtrl', + resolve: { + deps: app.load('./home/homeCtrl') + } + }) + .state('users', { + url: '/users', + templateUrl: 'users/users.html', + controller: 'usersCtrl', + resolve: { + deps: app.load('./users/usersCtrl') + } + }); + }]); +}); diff --git a/sample/webapp/app.js b/sample/webapp/app.js new file mode 100644 index 0000000..482f725 --- /dev/null +++ b/sample/webapp/app.js @@ -0,0 +1,12 @@ +define(function (require, exports, module) { + var angular = require('angular'); + var asyncLoader = require('angular-async-loader'); + + require('angular-ui-router'); + + var app = angular.module('app', ['ui.router']); + + asyncLoader.configure(app); + + module.exports = app; +}); diff --git a/sample/webapp/bootstrap.js b/sample/webapp/bootstrap.js new file mode 100644 index 0000000..a499916 --- /dev/null +++ b/sample/webapp/bootstrap.js @@ -0,0 +1,19 @@ +require.config({ + baseUrl: '/', + paths: { + 'angular': 'assets/angular/angular.min', + 'angular-ui-router': 'assets/angular-ui-router/release/angular-ui-router.min', + 'angular-async-loader': 'assets/angular-async-loader/angular-async-loader' + }, + shim: { + 'angular': {exports: 'angular'}, + 'angular-ui-router': {deps: ['angular']} + } +}); + +require(['angular', './app-routes'], function (angular) { + angular.element(document).ready(function () { + angular.bootstrap(document, ['app']); + angular.element(document).find('html').addClass('ng-app'); + }); +}); diff --git a/sample/webapp/home/home.html b/sample/webapp/home/home.html new file mode 100644 index 0000000..c033045 --- /dev/null +++ b/sample/webapp/home/home.html @@ -0,0 +1,6 @@ +
+ This is a home page - {{name}}. +
+
+ goto users +
diff --git a/sample/webapp/home/homeCtrl.js b/sample/webapp/home/homeCtrl.js new file mode 100644 index 0000000..fa3d1b6 --- /dev/null +++ b/sample/webapp/home/homeCtrl.js @@ -0,0 +1,7 @@ +define(function (require) { + var app = require('../app'); + + app.controller('homeCtrl', ['$scope', function($scope) { + $scope.name = 'Home'; + }]); +}); diff --git a/sample/webapp/index.html b/sample/webapp/index.html new file mode 100644 index 0000000..5f5bf7d --- /dev/null +++ b/sample/webapp/index.html @@ -0,0 +1,21 @@ + + + + + Sample for angular-async-loader + + + +
+ +
+ +
+ $state = {{$state.current.name}} +
+ + + + + + diff --git a/sample/webapp/services/usersService.js b/sample/webapp/services/usersService.js new file mode 100644 index 0000000..bfd96fc --- /dev/null +++ b/sample/webapp/services/usersService.js @@ -0,0 +1,19 @@ +define(function (require) { + var app = require('../app'); + + app.service('usersService', function () { + return { + list: function () { + return [ + { + name: 'user-1', + mail: 'user-1@email.com' + }, { + name: 'user-2', + mail: 'user-2@email.com' + } + ]; + } + }; + }); +}); diff --git a/sample/webapp/users/users.html b/sample/webapp/users/users.html new file mode 100644 index 0000000..b789f2d --- /dev/null +++ b/sample/webapp/users/users.html @@ -0,0 +1,9 @@ +
+
name = {{user.name}}
+
mail = {{user.mail}}
+
+
+ +
+ goto home +
diff --git a/sample/webapp/users/usersCtrl.js b/sample/webapp/users/usersCtrl.js new file mode 100644 index 0000000..a1a7ce0 --- /dev/null +++ b/sample/webapp/users/usersCtrl.js @@ -0,0 +1,10 @@ +define(function (require) { + var app = require('../app'); + + require('../services/usersService'); + + app.controller('usersCtrl', ['$scope', function ($scope) { + $scope.userList = app.get('usersService').list(); + }]); + +});