Skip to content

Update upstream #12

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Sep 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified docs/app/assets/img/AngularJS-small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/app/assets/img/bullet.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions docs/app/src/search.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ angular.module('search', [])
clearResults();
$scope.q = '';
};

$scope.handleResultClicked = function($event) {
if ($event.which === 1 && !$event.ctrlKey && !$event.metaKey) {
$scope.hideResults();
}
};
}])


Expand Down
11 changes: 6 additions & 5 deletions docs/config/services/deployments/production.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,23 @@ var angularCodeUrl = '//code.angularjs.org/';

var cdnUrl = googleCdnUrl + versionInfo.cdnVersion;

// The "examplesCdnUrl" here applies to the examples when they are opened in plnkr.co.
// The "examplesDependencyPath" here applies to the examples when they are opened in plnkr.co.
// The embedded examples instead always include the files from the *default* deployment,
// to ensure that the source files are always available.
// The plnkr examples must always use the code.angularjs.org source files.
// We cannot rely on the CDN files here, because they are not deployed by the time
// docs.angularjs.org and code.angularjs.org need them.
var examplesDependencyPath = versionInfo.currentVersion.isSnapshot ?
(angularCodeUrl + 'snapshot') :
(angularCodeUrl + (versionInfo.currentVersion.version || versionInfo.currentVersion.version));
var versionPath = versionInfo.currentVersion.isSnapshot ?
'snapshot' :
(versionInfo.currentVersion.version || versionInfo.currentVersion.version);
var examplesDependencyPath = angularCodeUrl + versionPath + '/';

module.exports = function productionDeployment(getVersion) {
return {
name: 'production',
examples: {
commonFiles: {
scripts: [examplesDependencyPath + '/angular.min.js']
scripts: [examplesDependencyPath + 'angular.min.js']
},
dependencyPath: examplesDependencyPath
},
Expand Down
2 changes: 1 addition & 1 deletion docs/config/templates/app/indexPage.template.html
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ <h1 class="brand"><a href="http://angularjs.org"><img width="117" height="30" sr
<div ng-repeat="(key, value) in results track by key" class="search-results-group" ng-class="colClassName + ' col-group-' + key" ng-show="value.length > 0">
<h4 class="search-results-group-heading">{{ key }}</h4>
<ul class="search-results">
<li ng-repeat="item in value" class="search-result"><a ng-click="hideResults()" ng-href="{{ item.path }}">{{ item.name }}</a></li>
<li ng-repeat="item in value" class="search-result"><a ng-click="handleResultClicked($event)" ng-href="{{ item.path }}">{{ item.name }}</a></li>
</ul>
</div>
</div>
Expand Down
Binary file modified docs/img/One_Way_Data_Binding.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/Two_Way_Data_Binding.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/angular_parts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/form_data_flow.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-databinding1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-databinding2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-directive.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-module-injector.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-runtime.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-scope-watch-strategies.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-startup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/concepts-view.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/crisis-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/crisis-list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/di_sequence_final.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/hashbang_vs_regular_url.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/hero-detail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/heroes-list.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/scenario_runner.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/guide/simple_scope_final.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/tutorial/catalog_screen.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/tutorial/tutorial_00.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/tutorial/tutorial_02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified docs/img/tutorial/tutorial_03.png
Binary file modified docs/img/tutorial/tutorial_05.png
Binary file modified docs/img/tutorial/tutorial_06.png
Binary file modified docs/img/tutorial/tutorial_09.png
Binary file modified docs/img/tutorial/tutorial_10.png
Binary file modified docs/img/tutorial/tutorial_12.png
Binary file modified images/docs/Diagrams.graffle/image1.png
Binary file modified images/docs/Diagrams.graffle/image2.png
Binary file modified images/docs/Diagrams.graffle/image4.png
Binary file modified images/docs/Diagrams.graffle/image9.png
Binary file modified images/docs/Diagrams.svg/image1.png
Binary file modified images/docs/Diagrams.svg/image2.png
Binary file modified images/docs/Diagrams.svg/image4.png
Binary file modified images/docs/Diagrams.svg/image9.png
Binary file modified images/docs/guide/concepts.graffle/image1.png
Binary file modified images/docs/guide/concepts.graffle/image4.png
Binary file modified images/docs/guide/concepts.graffle/image5.png
Binary file modified images/docs/guide/concepts.svg/image4.png
Binary file modified images/docs/guide/concepts.svg/image5.png
Binary file modified images/docs/guide/simple_scope.graffle/image7.png
Binary file modified images/docs/guide/simple_scope.svg/image7.png
Binary file modified images/docs/tutorial/simple_scope.graffle/image7.png
Binary file modified images/docs/tutorial/simple_scope.svg/image7.png
Binary file modified images/docs/tutorial/tutorial_02.graffle/image11.png
Binary file modified images/docs/tutorial/tutorial_02.svg/image11.png
Binary file modified images/docs/tutorial/tutorial_03.svg/image11.png
Binary file modified images/docs/tutorial/tutorial_05.graffle/image13.png
Binary file modified images/docs/tutorial/tutorial_05.svg/image13.png
Binary file modified images/docs/tutorial/tutorial_06.graffle/image15.png
Binary file modified images/docs/tutorial/tutorial_06.svg/image15.png
Binary file modified images/docs/tutorial/tutorial_09.graffle/image9.png
Binary file modified images/docs/tutorial/tutorial_09.svg/image9.png
Binary file modified images/docs/tutorial/tutorial_10.graffle/image10.png
Binary file modified images/docs/tutorial/tutorial_10.svg/image10.png
Binary file modified images/docs/tutorial/tutorial_12.graffle/image10.png
Binary file modified images/docs/tutorial/tutorial_12.svg/image10.png
Binary file modified images/docs/tutorial/tutorial_proto.graffle/image7.png
Binary file modified images/docs/tutorial/tutorial_proto.svg/image7.png
Binary file modified images/logo/AngularJS-Shield.exports/AngularJS-Shield-large.png
Binary file modified images/logo/AngularJS-Shield.exports/AngularJS-Shield-medium.png
Binary file modified images/logo/AngularJS-Shield.exports/AngularJS-Shield-small.png
Binary file modified images/logo/AngularJS.exports/AngularJS-huge.png
Binary file modified images/logo/AngularJS.exports/AngularJS-large.png
Binary file modified images/logo/AngularJS.exports/AngularJS-medium.png
Binary file modified images/logo/AngularJS.exports/AngularJS-small.png
Binary file modified images/logo/AngularJS.graffle/image1.png
Binary file modified images/logo/AngularJS.graffle/image2.png
46 changes: 45 additions & 1 deletion src/auto/injector.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,46 @@ function annotate(fn, strictDi, name) {
*
* @returns {Array.<string>} The names of the services which the function requires.
*/

/**
* @ngdoc method
* @name $injector#loadNewModules
*
* @description
*
* **This is a dangerous API, which you use at your own risk!**
*
* Add the specified modules to the current injector.
*
* This method will add each of the injectables to the injector and execute all of the config and run
* blocks for each module passed to the method.
*
* If a module has already been loaded into the injector then it will not be loaded again.
*
* * The application developer is responsible for loading the code containing the modules; and for
* ensuring that lazy scripts are not downloaded and executed more often that desired.
* * Previously compiled HTML will not be affected by newly loaded directives, filters and components.
* * Modules cannot be unloaded.
*
* You can use {@link $injector#modules `$injector.modules`} to check whether a module has been loaded
* into the injector, which may indicate whether the script has been executed already.
*
* ## Example
*
* Here is an example of loading a bundle of modules, with a utility method called `getScript`:
*
* ```javascript
* app.factory('loadModule', function($injector) {
* return function loadModule(moduleName, bundleUrl) {
* return getScript(bundleUrl).then(function() { $injector.loadNewModules([moduleName]); });
* };
* })
* ```
*
* @param {Array<String|Function|Array>=} mods an array of modules to load into the application.
* Each item in the array should be the name of a predefined module or a (DI annotated)
* function that will be invoked by the injector as a `config` block.
* See: {@link angular.module modules}
*/


/**
Expand Down Expand Up @@ -701,6 +740,11 @@ function createInjector(modulesToLoad, strictDi) {
instanceInjector.strictDi = strictDi;
forEach(runBlocks, function(fn) { if (fn) instanceInjector.invoke(fn); });

instanceInjector.loadNewModules = function(mods) {
forEach(loadModules(mods), function(fn) { if (fn) instanceInjector.invoke(fn); });
};


return instanceInjector;

////////////////////////////////////
Expand Down
160 changes: 159 additions & 1 deletion test/auto/injectorSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ describe('injector.modules', function() {
.info({ version: '1.2' })
.provider('test', ['$injector', function($injector) {
providerInjector = $injector;
return { $get: function() {} };
return {$get: function() {}};
}]);
module('test1');
// needed to ensure that the provider blocks are executed
Expand Down Expand Up @@ -152,6 +152,164 @@ describe('injector', function() {
expect($injector).not.toBe(providerInjector);
}));


describe('loadNewModules', function() {
it('should be defined on $injector', function() {
var injector = createInjector([]);
expect(injector.loadNewModules).toEqual(jasmine.any(Function));
});

it('should allow new modules to be added after injector creation', function() {
angular.module('initial', []);
var injector = createInjector(['initial']);
expect(injector.modules['initial']).toBeDefined();
expect(injector.modules['lazy']).toBeUndefined();
angular.module('lazy', []);
injector.loadNewModules(['lazy']);
expect(injector.modules['lazy']).toBeDefined();
});

it('should execute runBlocks of new modules', function() {
var log = [];
angular.module('initial', []).run(function() { log.push('initial'); });
var injector = createInjector(['initial']);
log.push('created');

angular.module('a', []).run(function() { log.push('a'); });
injector.loadNewModules(['a']);
expect(log).toEqual(['initial', 'created', 'a']);
});

it('should execute configBlocks of new modules', function() {
var log = [];
angular.module('initial', []).config(function() { log.push('initial'); });
var injector = createInjector(['initial']);
log.push('created');

angular.module('a', [], function() { log.push('config1'); }).config(function() { log.push('config2'); });
injector.loadNewModules(['a']);
expect(log).toEqual(['initial', 'created', 'config1', 'config2']);
});

it('should execute runBlocks and configBlocks in the correct order', function() {
var log = [];
angular.module('initial', [], function() { log.push(1); })
.config(function() { log.push(2); })
.run(function() { log.push(3); });
var injector = createInjector(['initial']);
log.push('created');

angular.module('a', [], function() { log.push(4); })
.config(function() { log.push(5); })
.run(function() { log.push(6); });
injector.loadNewModules(['a']);
expect(log).toEqual([1, 2, 3, 'created', 4, 5, 6]);
});

it('should load dependent modules', function() {
angular.module('initial', []);
var injector = createInjector(['initial']);
expect(injector.modules['initial']).toBeDefined();
expect(injector.modules['lazy1']).toBeUndefined();
expect(injector.modules['lazy2']).toBeUndefined();
angular.module('lazy1', ['lazy2']);
angular.module('lazy2', []);
injector.loadNewModules(['lazy1']);
expect(injector.modules['lazy1']).toBeDefined();
expect(injector.modules['lazy2']).toBeDefined();
});

it('should execute blocks of new modules in the correct order', function() {
var log = [];
angular.module('initial', []);
var injector = createInjector(['initial']);

angular.module('lazy1', ['lazy2'], function() { log.push('lazy1-1'); })
.config(function() { log.push('lazy1-2'); })
.run(function() { log.push('lazy1-3'); });
angular.module('lazy2', [], function() { log.push('lazy2-1'); })
.config(function() { log.push('lazy2-2'); })
.run(function() { log.push('lazy2-3'); });

injector.loadNewModules(['lazy1']);
expect(log).toEqual(['lazy2-1', 'lazy2-2', 'lazy1-1', 'lazy1-2', 'lazy2-3', 'lazy1-3']);
});

it('should not reload a module that is already loaded', function() {
var log = [];
angular.module('initial', []).run(function() { log.push('initial'); });
var injector = createInjector(['initial']);
expect(log).toEqual(['initial']);

injector.loadNewModules(['initial']);
expect(log).toEqual(['initial']);

angular.module('a', []).run(function() { log.push('a'); });
injector.loadNewModules(['a']);
expect(log).toEqual(['initial', 'a']);
injector.loadNewModules(['a']);
expect(log).toEqual(['initial', 'a']);

angular.module('b', ['a']).run(function() { log.push('b'); });
angular.module('c', []).run(function() { log.push('c'); });
angular.module('d', ['b', 'c']).run(function() { log.push('d'); });
injector.loadNewModules(['d']);
expect(log).toEqual(['initial', 'a', 'b', 'c', 'd']);
});

it('should be able to register a service from a new module', function() {
var injector = createInjector([]);
angular.module('a', []).factory('aService', function() {
return {sayHello: function() { return 'Hello'; }};
});
injector.loadNewModules(['a']);
injector.invoke(function(aService) {
expect(aService.sayHello()).toEqual('Hello');
});
});


it('should be able to register a controller from a new module', function() {
var injector = createInjector(['ng']);
angular.module('a', []).controller('aController', function($scope) {
$scope.test = 'b';
});
injector.loadNewModules(['a']);
injector.invoke(function($controller) {
var scope = {};
$controller('aController', {$scope: scope});
expect(scope.test).toEqual('b');
});
});


it('should be able to register a filter from a new module', function() {
var injector = createInjector(['ng']);
angular.module('a', []).filter('aFilter', function() {
return function(input) { return input + ' filtered'; };
});
injector.loadNewModules(['a']);
injector.invoke(function(aFilterFilter) {
expect(aFilterFilter('test')).toEqual('test filtered');
});
});


it('should be able to register a directive from a new module', function() {
var injector = createInjector(['ng']);
angular.module('a', []).directive('aDirective', function() {
return {template: 'test directive'};
});
injector.loadNewModules(['a']);
injector.invoke(function($compile, $rootScope) {
var elem = $compile('<div a-directive></div>')($rootScope); // compile and link
$rootScope.$digest();
expect(elem.text()).toEqual('test directive');
elem.remove();
});
});
});

it('should have a false strictDi property', inject(function($injector) {
expect($injector.strictDi).toBe(false);
}));
Expand Down