Skip to content

Commit 8b8ef6a

Browse files
committed
Better documentation, more comments.
1 parent 8f0d108 commit 8b8ef6a

File tree

2 files changed

+101
-35
lines changed

2 files changed

+101
-35
lines changed

README.md

+82-24
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,22 @@
44

55
A script loader for AngularJS that perform AMD-like script injection without the need for special syntax.
66

7+
8+
9+
10+
11+
712
# Rationale
813

914
Say you are like me and love having a Javascript file for every module. And you have a lot of scripts with specific tasks; directives, factories, utility functions. You name it.
1015

1116
One solution that we used here at Coders at Work was RequireJS, but I grew tired of it; it is becoming too heavy and doesn't integrate that well with AngularJS.
1217

18+
19+
20+
21+
22+
1323
# Example
1424

1525
So I decided to go ahead and build this little script. Here's how it works:
@@ -25,7 +35,7 @@ So I decided to go ahead and build this little script. Here's how it works:
2535
>
2636
> <body>
2737
> <div ng-controller="TestCtrl as test">
28-
> {{test.value}}<br/>
38+
> {{test.value}}
2939
> </div>
3040
> </body>
3141
> </html>
@@ -47,9 +57,14 @@ So I decided to go ahead and build this little script. Here's how it works:
4757
> });
4858
> ```
4959
50-
Angularjs-loader automatically sees that angular.module() has a dependency to 'test_ctrl', and as such loads the script automatically when it's ready. When all `angular.module()` calls are done, it automatically bootstrap angular.
60+
Angularjs-loader automatically sees that angular.module() has a dependency to 'test_ctrl', and loads the script automatically when it's ready. When all `angular.module()` calls are done, it automatically bootstrap angular.
61+
62+
As long as you stick to AngularJS, there's no need for shims, paths or configurations. A blocking module makes it simple to include other libraries as well.
63+
64+
65+
66+
5167
52-
As long as you stick to AngularJS, there's no need for shims, paths or configurations.
5368
5469
# API
5570
@@ -65,6 +80,8 @@ It takes 3 arguments:
6580
* `onbootstrap`. Code to evaluate when the Angular is finished loading.
6681
* `noinit`. Any non-empty string to prevent the AngularJS-Loader from automatically starting the initialization process. See [Tests](#Tests).
6782
83+
84+
6885
## Angular Modules
6986
7087
The loader overrides `angular.module()` and does two things:
@@ -75,11 +92,13 @@ The loader overrides `angular.module()` and does two things:
7592
7693
As you use `angular.module()` to create a module, it will load its dependencies recursively. Using `angular.module()` to only access the module itself is okay and has no side effect.
7794
95+
96+
7897
## Custom Scripts
7998
8099
When you need to load custom scripts you should use the new function `angular.loader()`. It takes 2 arguments and returns a simplified promise object.
81100
82-
The first argument is either a filename or an array of filename to load. Remember that these will be transformed using [path transform](#Configuration).
101+
The first argument is either a filename or an array of filename to load. Remember that these will be transformed using the [path transform](#Configuration).
83102
84103
The second argument is an object of named options:
85104
@@ -93,12 +112,16 @@ Omitting this option performs no checks at all and unlock the bootstrap when the
93112
94113
The object returned can be used as a simpler Angular deferred promise object, but there's no `finally` method on it, only `catch` and `then`. The promise will be fulfilled after the checker has returned `true` for all the scripts.
95114
115+
116+
96117
## Locking the Bootstrap
97118
98119
You can lock bootstrapping of AngularJS with `angular.loader.lock()` (and unlock it with `angular.loader.unlock()`). The functions take a name as parameter. Locking the same name twice, unlocking an unlocked or unknown name are all errors. The only limit on locks are that you cannot lock/unlock once the bootstrap happened. Anything after bootstrapping angular is considered an error.
99120
100121
Locking and unlocking before the end of loading all the modules and their dependencies will simply result in waiting for the dependencies to finish loading.
101122
123+
124+
102125
## <a name="Configuration"></a> Configuration
103126
104127
Configuration is set by calling `angular.loader.config()`. The function takes an object as argument and update the internal configuration.
@@ -108,48 +131,83 @@ The list of configuration options is as follow:
108131
* `path`. A map of name to full path (or `null`). If a module name is present in this map, the loader will use this path instead of the name to load. If the full path in the map is `null`, the script will return
109132
* `pathTransform`. A list of functions that take a path and return a path or `null`. This is to allow transforming a module or script name to its file path. The transform chain will not be executed if the path is part of the `path` option above or is a full URI.
110133
* `checker`. A checker map for modules. See loading custom scripts above. This is to simplify the calls to `angular.loader()`.
134+
* `error`. An error handler. If specified, NO error will be thrown or outputted, they will all be passed to the handler.
111135
112136
The process of getting a script path from a module name is as follow:
113137
114138
```javascript
115-
var name; // Original name for the module.
116-
var path = name in config.path ? config.path[name] : name; // Path to load.
117-
if (path === null) return;
118-
if (isUri(path)) return path;
119-
120-
for (var i = 0; i < config.transformPath.length; i++) {
121-
old_path = path;
122-
path = config.transformPath[i](path, name);
123-
if (path === null) {
124-
path = old_path;
125-
break;
126-
}
127-
}
128-
129-
if (isUri(path)) return path;
130-
if (path[0] != '/') path = '/' + path;
131-
if (!/\.js$/.test(path)) path += '.js';
132-
return path;
139+
var name; // Original name for the module.
140+
var path = name in config.path ? config.path[name] : name; // Path to load.
141+
if (path === null) return;
142+
if (isUri(path)) return path;
143+
144+
for (var i = 0; i < config.transformPath.length; i++) {
145+
old_path = path;
146+
path = config.transformPath[i](path, name);
147+
if (path === null) {
148+
path = old_path;
149+
break;
150+
}
151+
}
152+
153+
if (isUri(path)) return path;
154+
if (path[0] != '/') path = '/' + path;
155+
if (!/\.js$/.test(path)) path += '.js';
156+
return path;
133157
```
134158
159+
160+
135161
## <a name="Tests"></a> Tests (Karma and Jasmine)
136162

137-
*__To Be Done!__*
163+
Some Karma tests are included to cover the most basis cases. Tests are added regularly for better coverage.
164+
165+
To run the tests, simply run `karma run` in the angularjs-loader folder.
166+
138167

139-
-----
140168

141169
# ToDo
142170

171+
For version 1.0:
172+
143173
1. Minification pre-step. Having a script that takes all `angular.module()` calls and merge the scripts into a single file (or multiple).
144174

175+
Future:
176+
177+
1. Nothing really.
178+
179+
180+
181+
182+
183+
145184
# Suggestions / Questions / Praises
146185

147186
If you think of something, create an issue!
148187

188+
189+
190+
191+
192+
149193
# FAQ
150194

151195

152196

197+
198+
### Are there any complex examples out there?
199+
200+
None for now. I want to add some cookbook for this as it can be quite powerful but hard to grasp. I figure that for now the simple case will be enough for most uses.
201+
202+
### Requirejs does X. Why don't you do it?
203+
204+
A mixture of reasons, really. RequireJS has a couple of devs behind it and more bandwidth. Also, I wanted to keep the size really low (AJS-Loader is currently under 3650 bytes minified and uncompressed, while RequireJS sits at 15kb) and performance really high (benchmarks coming later).
205+
206+
Some stuff had to be sacrificed. Mainly, there's no plugin for AJS-Loader, you can't load things that are not scripts (but can load stuff outside of AngularJS modules, of course), it is mainly meant as a developer only script (meaning that production code should use the `concat` script I'm working on), and while path transforms and checkers can be quite powerful, they're also more complex than other solutions.
207+
208+
209+
210+
153211
# Special Thanks
154212

155213
None for now.

angularjs-loader.js

+19-11
Original file line numberDiff line numberDiff line change
@@ -26,20 +26,20 @@ var ANGULARJS_LOADER_DEBUG = true;
2626
*******************************************************************************
2727
* Documentation: see http://github.com/hansl/angularjs-loader
2828
*/
29-
(function(window) {
29+
(function(window, UNDEFINED) {
3030

3131
/**
3232
* These constants are just easier to shorten and reuse when using a
3333
* minificator.
3434
*/
35-
var UNDEFINED = void 0;
3635
var NULL = null;
3736

3837
/**
3938
* Config parameters passed in angular.loader.config().
4039
* @type Config
4140
*/
4241
var config = {
42+
error: NULL,
4343
path: {},
4444
checker: {},
4545
pathTransform: []
@@ -58,16 +58,16 @@ var angularModuleOriginalFn = window.angular && window.angular.module;
5858
* Some polyfills.
5959
*/
6060
// Returns true if the value is of type type.
61-
function is(value, type) {
61+
function isOfType(value, type) {
6262
return typeof value == type;
6363
}
6464
// Returns true if the value is a string.
6565
function isString(value) {
66-
return is(value, 'string');
66+
return isOfType(value, 'string');
6767
}
6868
// Returns true if the value is an object.
6969
function isObject(value) {
70-
return is(value, 'object');
70+
return isOfType(value, 'object');
7171
}
7272
// Extend an object. See jQuery.extend() for "some" documentation.
7373
function extend(orig, extension, override) {
@@ -89,8 +89,16 @@ function bind(fn, o, args) {
8989
}
9090

9191

92+
/*******************************************************************************
93+
* Error function. If a handler is specified it will be called with the ID and
94+
* params. Otherwise this will either throw or log an error on the console.
95+
* Optimized, the message will disappear.
96+
*/
9297
function error(id, params, msg) {
93-
if (ANGULARJS_LOADER_DEBUG) {
98+
if (config.error) {
99+
config.error(id, params);
100+
}
101+
else if (ANGULARJS_LOADER_DEBUG) {
94102
message = msg.replace(/\{\d+\}/g, function(_, i) {
95103
return params[i];
96104
});
@@ -569,11 +577,11 @@ if (ANGULARJS_LOADER_TESTING) {
569577
lockCount = 0;
570578
isBootstrapped = false;
571579
locks = {};
572-
mainModulePathArg = null;
573-
rootPathArg = null;
574-
timeoutArg = null;
575-
bootstrapFnArg = null;
576-
angularModuleOriginalFn = null;
580+
mainModulePathArg = NULL;
581+
rootPathArg = NULL;
582+
timeoutArg = NULL;
583+
bootstrapFnArg = NULL;
584+
angularModuleOriginalFn = NULL;
577585

578586
maybeSwapAngularModuleFn();
579587
}

0 commit comments

Comments
 (0)