Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit afc48a6

Browse files
feat(angular.info): optionally store and access additional info on modules
This feature allows the developer to store additional meta data about a module when it is defined by adding an additional parameter containing an object to the `angular.module(moduleName, deps, info, configFn)` call. Developers can then access this information by calling `angular.info(moduleName)` See this angular/material#3842 for more background.
1 parent 533d9b7 commit afc48a6

File tree

7 files changed

+88
-8
lines changed

7 files changed

+88
-8
lines changed

src/.jshintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@
8181
"encodeUriSegment": false,
8282
"encodeUriQuery": false,
8383
"angularInit": false,
84+
"info": false,
8485
"bootstrap": false,
8586
"getTestability": false,
8687
"snake_case": false,

src/Angular.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1502,6 +1502,18 @@ function angularInit(element, bootstrap) {
15021502
}
15031503
}
15041504

1505+
1506+
/**
1507+
* @ngdoc function
1508+
* @name angular.info
1509+
* @module ng
1510+
* @description
1511+
* Get the info about a given module
1512+
*/
1513+
function info(moduleName) {
1514+
return angularModule(moduleName).info;
1515+
}
1516+
15051517
/**
15061518
* @ngdoc function
15071519
* @name angular.bootstrap

src/AngularPublic.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,8 @@ function publishExternalAPI(angular) {
147147
'getTestability': getTestability,
148148
'$$minErr': minErr,
149149
'$$csp': csp,
150-
'reloadWithDebugInfo': reloadWithDebugInfo
150+
'reloadWithDebugInfo': reloadWithDebugInfo,
151+
'info': info
151152
});
152153

153154
angularModule = setupModuleLoader(window);

src/loader.js

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ function setupModuleLoader(window) {
4949
*
5050
* ```js
5151
* // Create a new module
52-
* var myModule = angular.module('myModule', []);
52+
* var myModule = angular.module('myModule', [], { version: '1.0.2' });
5353
*
5454
* // register a new service
5555
* myModule.value('appName', 'MyCoolApp');
@@ -71,14 +71,34 @@ function setupModuleLoader(window) {
7171
* {@link ng.directive:ngApp ngApp} or
7272
* {@link angular.bootstrap} to simplify this process for you.
7373
*
74+
* You can access the extra module information that you provided when defining
75+
* the module by calling {@link module.info }:
76+
*
77+
* ```js
78+
* var version = angular.info('myModule').version;
79+
* ```
80+
*
7481
* @param {!string} name The name of the module to create or retrieve.
7582
* @param {!Array.<string>=} requires If specified then new module is being created. If
7683
* unspecified then the module is being retrieved for further configuration.
84+
* @param {Object=} info Optional information about the module.
85+
* For example you could put the version of the module in here.
7786
* @param {Function=} configFn Optional configuration function for the module. Same as
7887
* {@link angular.Module#config Module#config()}.
7988
* @returns {module} new module with the {@link angular.Module} api.
8089
*/
81-
return function module(name, requires, configFn) {
90+
return function module(name, requires, configFnOrInfo, configFn) {
91+
92+
var info = {};
93+
94+
if (!isArray(configFnOrInfo) && isObject(configFnOrInfo)) {
95+
info = configFnOrInfo;
96+
}
97+
98+
if (isUndefined(configFn) && (isArray(configFnOrInfo) || isFunction(configFnOrInfo))) {
99+
configFn = configFnOrInfo;
100+
}
101+
82102
var assertNotHasOwnProperty = function(name, context) {
83103
if (name === 'hasOwnProperty') {
84104
throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
@@ -114,6 +134,17 @@ function setupModuleLoader(window) {
114134
_configBlocks: configBlocks,
115135
_runBlocks: runBlocks,
116136

137+
/**
138+
* @ngdoc property
139+
* @name angular.Module#info
140+
* @module ng
141+
*
142+
* @description
143+
* Additional info about this module, optionally provided when the module was defined.
144+
* For example you could put the version of the module in here.
145+
*/
146+
info: info,
147+
117148
/**
118149
* @ngdoc property
119150
* @name angular.Module#requires

test/.jshintrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
"encodeUriSegment": false,
7676
"encodeUriQuery": false,
7777
"angularInit": false,
78+
"info": false,
7879
"bootstrap": false,
7980
"snake_case": false,
8081
"bindJQuery": false,

test/AngularSpec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1602,6 +1602,23 @@ describe('angular', function() {
16021602
});
16031603
});
16041604

1605+
1606+
describe('info', function() {
1607+
it('should return the additional info for the named module', function() {
1608+
angular.module('a', [], {some: 'thing'});
1609+
angular.module('b', ['dep'], {other: 'thang'}, function configFn() {});
1610+
1611+
expect(info('a')).toEqual({some: 'thing'});
1612+
expect(info('b')).toEqual({other: 'thang'});
1613+
});
1614+
1615+
it('should complain if there is no such module', function() {
1616+
expect(function() {
1617+
info('no-such-module');
1618+
}).toThrowMinErr('$injector', 'nomod');
1619+
});
1620+
});
1621+
16051622
describe('bootstrap', function() {
16061623
it('should bootstrap app', function() {
16071624
var element = jqLite('<div>{{1+2}}</div>');

test/loaderSpec.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,14 @@ describe('module loader', function() {
2626

2727

2828
it('should record calls', function() {
29+
function config() {}
30+
function init() {}
31+
function init2() {}
32+
2933
var otherModule = window.angular.module('other', []);
30-
otherModule.config('otherInit');
34+
otherModule.config(init);
3135

32-
var myModule = window.angular.module('my', ['other'], 'config');
36+
var myModule = window.angular.module('my', ['other'], config);
3337

3438
expect(myModule.
3539
decorator('dk', 'dv').
@@ -40,7 +44,7 @@ describe('module loader', function() {
4044
filter('f', 'ff').
4145
directive('d', 'dd').
4246
controller('ctrl', 'ccc').
43-
config('init2').
47+
config(init2).
4448
constant('abc', 123).
4549
run('runBlock')).toBe(myModule);
4650

@@ -57,13 +61,26 @@ describe('module loader', function() {
5761
['$controllerProvider', 'register', ['ctrl', 'ccc']]
5862
]);
5963
expect(myModule._configBlocks).toEqual([
60-
['$injector', 'invoke', ['config']],
61-
['$injector', 'invoke', ['init2']]
64+
['$injector', 'invoke', [config]],
65+
['$injector', 'invoke', [init2]]
6266
]);
6367
expect(myModule._runBlocks).toEqual(['runBlock']);
6468
});
6569

6670

71+
it('should store additional module info', function() {
72+
var myModule = angular.module('myModule', ['dep1'], {version: '1.0'});
73+
var otherModule = angular.module('otherModule', ['dep2'], {version: '2.0'}, function someConfig() {});
74+
var thirdModule = angular.module('thirdModule', ['dep2', 'dep3'], {version: '3.0'}, [function someConfig() {}]);
75+
var fourthModule = angular.module('fourthModule', [], [function someConfig() {}]);
76+
77+
expect(myModule.info).toEqual({version: '1.0'});
78+
expect(otherModule.info).toEqual({version: '2.0'});
79+
expect(thirdModule.info).toEqual({version: '3.0'});
80+
expect(fourthModule.info).toEqual({});
81+
});
82+
83+
6784
it('should allow module redefinition', function() {
6885
expect(window.angular.module('a', [])).not.toBe(window.angular.module('a', []));
6986
});

0 commit comments

Comments
 (0)