aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/Angular.js48
-rw-r--r--test/AngularSpec.js74
2 files changed, 105 insertions, 17 deletions
diff --git a/src/Angular.js b/src/Angular.js
index 93e4f6af..20c032c1 100644
--- a/src/Angular.js
+++ b/src/Angular.js
@@ -944,22 +944,38 @@ function angularInit(element, bootstrap) {
* @returns {AUTO.$injector} Returns the newly created injector for this app.
*/
function bootstrap(element, modules) {
- element = jqLite(element);
- modules = modules || [];
- modules.unshift(['$provide', function($provide) {
- $provide.value('$rootElement', element);
- }]);
- modules.unshift('ng');
- var injector = createInjector(modules);
- injector.invoke(
- ['$rootScope', '$rootElement', '$compile', '$injector', function(scope, element, compile, injector){
- scope.$apply(function() {
- element.data('$injector', injector);
- compile(element)(scope);
- });
- }]
- );
- return injector;
+ var resumeBootstrapInternal = function() {
+ element = jqLite(element);
+ modules = modules || [];
+ modules.unshift(['$provide', function($provide) {
+ $provide.value('$rootElement', element);
+ }]);
+ modules.unshift('ng');
+ var injector = createInjector(modules);
+ injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
+ function(scope, element, compile, injector) {
+ scope.$apply(function() {
+ element.data('$injector', injector);
+ compile(element)(scope);
+ });
+ }]
+ );
+ return injector;
+ };
+
+ var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
+
+ if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
+ return resumeBootstrapInternal();
+ }
+
+ window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
+ angular.resumeBootstrap = function(extraModules) {
+ forEach(extraModules, function(module) {
+ modules.push(module);
+ });
+ resumeBootstrapInternal();
+ };
}
var SNAKE_CASE_REGEXP = /[A-Z]/g;
diff --git a/test/AngularSpec.js b/test/AngularSpec.js
index c535bf12..28b2205f 100644
--- a/test/AngularSpec.js
+++ b/test/AngularSpec.js
@@ -658,7 +658,7 @@ describe('angular', function() {
var element = jqLite('<div>{{1+2}}</div>');
var injector = angular.bootstrap(element);
expect(injector).toBeDefined();
- expect(element.data('$injector')).toBe(injector);
+ expect(element.injector()).toBe(injector);
dealoc(element);
});
@@ -672,6 +672,78 @@ describe('angular', function() {
expect(element.html()).toBe('{{1+2}}');
dealoc(element);
});
+
+
+ describe('deferred bootstrap', function() {
+ var originalName = window.name,
+ element;
+
+ beforeEach(function() {
+ window.name = '';
+ element = jqLite('<div>{{1+2}}</div>');
+ });
+
+ afterEach(function() {
+ dealoc(element);
+ window.name = originalName;
+ });
+
+
+ it('should wait for extra modules', function() {
+ window.name = 'NG_DEFER_BOOTSTRAP!';
+ angular.bootstrap(element);
+
+ expect(element.html()).toBe('{{1+2}}');
+
+ angular.resumeBootstrap();
+
+ expect(element.html()).toBe('3');
+ expect(window.name).toEqual('');
+ });
+
+
+ it('should load extra modules', function() {
+ element = jqLite('<div>{{1+2}}</div>');
+ window.name = 'NG_DEFER_BOOTSTRAP!';
+
+ var bootstrapping = jasmine.createSpy('bootstrapping');
+ angular.bootstrap(element, [bootstrapping]);
+
+ expect(bootstrapping).not.toHaveBeenCalled();
+ expect(element.injector()).toBeUndefined();
+
+ angular.module('addedModule', []).value('foo', 'bar');
+ angular.resumeBootstrap(['addedModule']);
+
+ expect(bootstrapping).toHaveBeenCalledOnce();
+ expect(element.injector().get('foo')).toEqual('bar');
+ });
+
+
+ it('should not defer bootstrap without window.name cue', function() {
+ angular.bootstrap(element, []);
+ angular.module('addedModule', []).value('foo', 'bar');
+
+ expect(function() {
+ element.injector().get('foo');
+ }).toThrow('Unknown provider: fooProvider <- foo');
+
+ expect(element.injector().get('$http')).toBeDefined();
+ });
+
+
+ it('should restore the original window.name after bootstrap', function() {
+ window.name = 'NG_DEFER_BOOTSTRAP!my custom name';
+ angular.bootstrap(element);
+
+ expect(element.html()).toBe('{{1+2}}');
+
+ angular.resumeBootstrap();
+
+ expect(element.html()).toBe('3');
+ expect(window.name).toEqual('my custom name');
+ });
+ });
});