diff --git a/src/.jshintrc b/src/.jshintrc index e5ce17e43234..470f763127df 100644 --- a/src/.jshintrc +++ b/src/.jshintrc @@ -81,6 +81,7 @@ "encodeUriSegment": false, "encodeUriQuery": false, "angularInit": false, + "info": false, "bootstrap": false, "getTestability": false, "snake_case": false, diff --git a/src/Angular.js b/src/Angular.js index fdd72ecf6883..00e672f54289 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -1504,6 +1504,25 @@ function angularInit(element, bootstrap) { } } + +/** + * @ngdoc function + * @name angular.info + * @module ng + * @returns { Object } + * An object containing the info about a module or an empty object if + * the module has not been defined. + * @description + * Get the info about a given module. + */ +function info(moduleName) { + try { + return angularModule(moduleName).info(); + } catch (e) { + return {}; + } +} + /** * @ngdoc function * @name angular.bootstrap diff --git a/src/AngularPublic.js b/src/AngularPublic.js index bf82b90c1a28..7307245f12ec 100644 --- a/src/AngularPublic.js +++ b/src/AngularPublic.js @@ -150,7 +150,8 @@ function publishExternalAPI(angular) { 'getTestability': getTestability, '$$minErr': minErr, '$$csp': csp, - 'reloadWithDebugInfo': reloadWithDebugInfo + 'reloadWithDebugInfo': reloadWithDebugInfo, + 'info': info }); angularModule = setupModuleLoader(window); diff --git a/src/loader.js b/src/loader.js index 93ce8e720a99..e0815276da3d 100644 --- a/src/loader.js +++ b/src/loader.js @@ -79,6 +79,9 @@ function setupModuleLoader(window) { * @returns {module} new module with the {@link angular.Module} api. */ return function module(name, requires, configFn) { + + var info = {}; + var assertNotHasOwnProperty = function(name, context) { if (name === 'hasOwnProperty') { throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context); @@ -114,6 +117,37 @@ function setupModuleLoader(window) { _configBlocks: configBlocks, _runBlocks: runBlocks, + /** + * @ngdoc method + * @name angular.Module#info + * @module ng + * + * @param {Object=} info Information about the module + * @returns {Object|Module} The current info object for this module if called as a getter, + * or `this` if called as a setter. + * + * @description + * Additional info about this module + * For example you could put the version of the module in here. + * + * ```js + * angular.module('myModule', []).info({ version: '1.0.0' }); + * ``` + * + * The global method `angular.info()` can be used to retrieve this info: + * + * ```js + * var version = angular.info('myModule').version; + * ``` + */ + info: function(value) { + if (isDefined(value)) { + info = value; + return this; + } + return info; + }, + /** * @ngdoc property * @name angular.Module#requires diff --git a/test/.jshintrc b/test/.jshintrc index 0d85795b3545..368b6b02e57c 100644 --- a/test/.jshintrc +++ b/test/.jshintrc @@ -75,6 +75,7 @@ "encodeUriSegment": false, "encodeUriQuery": false, "angularInit": false, + "info": false, "bootstrap": false, "snake_case": false, "bindJQuery": false, diff --git a/test/AngularSpec.js b/test/AngularSpec.js index 7a21a0feea39..cb94c07cef15 100644 --- a/test/AngularSpec.js +++ b/test/AngularSpec.js @@ -1614,6 +1614,21 @@ describe('angular', function() { }); }); + + describe('info', function() { + it('should return the additional info for the named module', function() { + angular.module('a', []).info({some: 'thing'}); + angular.module('b', ['dep'], function configFn() {}).info({other: 'thang'}); + + expect(info('a')).toEqual({some: 'thing'}); + expect(info('b')).toEqual({other: 'thang'}); + }); + + it('should return anh empty object if there is no such module', function() { + expect(info('no-such-module')).toEqual({}); + }); + }); + describe('bootstrap', function() { it('should bootstrap app', function() { var element = jqLite('