diff --git a/config/ngModuleData.js b/config/ngModuleData.js index cc376e030f3..f0c0d0e93bb 100644 --- a/config/ngModuleData.js +++ b/config/ngModuleData.js @@ -1,21 +1,48 @@ -// Regex adapted from https://github.com/ceymard/gulp-ngcompile - -module.exports = function processContent(fileContent, materialOnly) { - var NG_MODULE_REGEX = materialOnly ? /\.module\(('material\.[^']*'|"material\.[^"]*")\s*,(?:\s*\[([^\]]+)\])?/g : /\.module\(('[^']*'|"[^"]*")\s*,(?:\s*\[([^\]]+)\])?/g; - var match = NG_MODULE_REGEX.exec(fileContent || ''); - var module = match && match[1] && match[1].slice(1, -1); //remove quotes - var depsMatch = match && match[2] && match[2].trim(); - - var dependencies = []; - if (depsMatch) { - dependencies = depsMatch.split(/\s*,\s*/).map(function(dep) { - dep = dep.slice(1, -1); //remove quotes - return dep; - }); +/** + * The Angular Material module `ngMaterial` is generated by scanning all Material components + * for valid module definitions. @see gulp-utils.js ::buildNgMaterialDefinition() + * + * angular.module('ngMaterial', [ + * "ng","ngAnimate","ngAria", + * "material.core","material.core.gestures","material.layout","material.core.theming.palette", + * ... + * ]); + * + */ + +// Define patterns for AngularJS Module definitions + +var MATERIAL_ONLY = /\.module\(['|"](material\.[a-zA-Z\-\.]*)['|"]\s*,(\s*\[([^\]]*)\])/; +var ANY = /\.module\(('[^']*'|"[^"]*")\s*,(?:\s*\[([^\]]+)\])?/; + +/** + * Find module definition s that match the module definition pattern + */ +function buildScanner(pattern) { + + return function findPatternIn(content) { + var dependencies; + var match = pattern.exec(content || ''); + var moduleName = match ? match[1].replace(/\'/gi,'') : null; + var depsMatch = match && match[2] && match[2].trim(); + + if (depsMatch) { + dependencies = depsMatch.split(/\s*,\s*/).map(function(dep) { + dep = dep.trim().slice(1, -1); //remove quotes + return dep; + }); + } + + return match ? { + name : moduleName || '', + module : moduleName || '', + dependencies : dependencies || [ ] + } : null; } +} - return { - module: module || '', - dependencies: dependencies - }; +module.exports = { + material : buildScanner( MATERIAL_ONLY ), + any : buildScanner( ANY ) }; + diff --git a/docs/app/js/app.js b/docs/app/js/app.js index 827c47440b6..6badf164f5e 100644 --- a/docs/app/js/app.js +++ b/docs/app/js/app.js @@ -1,4 +1,4 @@ -var DocsApp = angular.module('docsApp', ['ngMaterial', 'ngRoute', 'angularytics', 'ngMessages']) +var DocsApp = angular.module('docsApp', [ 'angularytics', 'ngRoute', 'ngMessages', 'ngMaterial' ]) .config([ 'SERVICES', @@ -716,5 +716,4 @@ function($rootScope, $scope, component, demos, $http, $templateCache, $q) { } return str; }; -}) -; +}); diff --git a/scripts/gulp-utils.js b/scripts/gulp-utils.js index 72afbe0d59e..1657de09854 100644 --- a/scripts/gulp-utils.js +++ b/scripts/gulp-utils.js @@ -7,8 +7,7 @@ var Buffer = require('buffer').Buffer; var fs = require('fs'); var path = require('path'); - -var getModuleInfo = require('../config/ngModuleData.js'); +var findModule = require('../config/ngModuleData.js'); exports.humanizeCamelCase = function(str) { switch (str) { @@ -77,7 +76,7 @@ exports.readModuleDemos = function(moduleName, fileTasks) { } else { var fileType = path.extname(file.path).substring(1); if (fileType == 'js') { - demo.ngModule = demo.ngModule || getModuleInfo(file.contents.toString()); + demo.ngModule = demo.ngModule || findModule.any(file.contents.toString()); } demo[fileType] && demo[fileType].push(toDemoObject(file)); } @@ -106,8 +105,8 @@ exports.pathsForModule = function(name) { function lookupPath() { gulp.src('src/{services,components,core}/**/*') .pipe(through2.obj(function(file, enc, next) { - var modName = getModuleInfo(file.contents).module; - if (modName == name) { + var module = findModule.any(file.contents); + if (module && module.name == name) { var modulePath = file.path.split(path.sep).slice(0, -1).join(path.sep); pathsForModules[name] = modulePath + '/**'; } @@ -123,8 +122,8 @@ exports.filesForModule = function(name) { } else { return gulp.src('src/{services,components,core}/**/*') .pipe(through2.obj(function(file, enc, next) { - var modName = getModuleInfo(file.contents).module; - if (modName == name) { + var module = findModule.any(file.contents); + if (module && (module.name == name)) { var modulePath = file.path.split(path.sep).slice(0, -1).join(path.sep); pathsForModules[name] = modulePath + '/**'; var self = this; @@ -165,29 +164,33 @@ exports.appendToFile = function(filePath) { }; exports.buildNgMaterialDefinition = function() { - var buffer = []; + var srcBuffer = []; var modulesSeen = []; + var count = 0; return through2.obj(function(file, enc, next) { - var moduleName; - if (moduleName = getModuleInfo(file.contents, true).module) { - modulesSeen.push(moduleName); - } - buffer.push(file); + var module = findModule.material(file.contents); + if (module) modulesSeen.push(module.name); + srcBuffer.push(file); next(); }, function(done) { - var EXPLICIT_DEPS = ['ng', 'ngAnimate', 'ngAria']; - var angularFileContents = "angular.module('ngMaterial', " + JSON.stringify(EXPLICIT_DEPS.concat(modulesSeen)) + ');'; + var self = this; + var requiredLibs = ['ng', 'ngAnimate', 'ngAria']; + var dependencies = JSON.stringify(requiredLibs.concat(modulesSeen)); + var ngMaterialModule = "angular.module('ngMaterial', " + dependencies + ');'; var angularFile = new gutil.File({ base: process.cwd(), path: process.cwd() + '/ngMaterial.js', - contents: new Buffer(angularFileContents) + contents: new Buffer(ngMaterialModule) }); - this.push(angularFile); - var self = this; - buffer.forEach(function(file) { + + // Elevate ngMaterial module registration to first in queue + self.push(angularFile); + + srcBuffer.forEach(function(file) { self.push(file); }); - buffer = []; + + srcBuffer = []; done(); }); }; @@ -197,8 +200,8 @@ function moduleNameToClosureName(name) { } exports.addJsWrapper = function(enforce) { return through2.obj(function(file, enc, next) { - var moduleInfo = getModuleInfo(file.contents); - if (!!enforce || moduleInfo.module) { + var module = findModule.any(file.contents); + if (!!enforce || module) { file.contents = new Buffer([ !!enforce ? '(function(){' : '(function( window, angular, undefined ){', '"use strict";\n', @@ -212,18 +215,18 @@ exports.addJsWrapper = function(enforce) { }; exports.addClosurePrefixes = function() { return through2.obj(function(file, enc, next) { - var moduleInfo = getModuleInfo(file.contents); - if (moduleInfo.module) { - var closureModuleName = moduleNameToClosureName(moduleInfo.module); - var requires = (moduleInfo.dependencies || []).sort().map(function(dep) { - return dep.indexOf(moduleInfo.module) === 0 ? '' : 'goog.require(\'' + moduleNameToClosureName(dep) + '\');'; + var module = findModule.any(file.contents); + if (module) { + var closureModuleName = moduleNameToClosureName(module.name); + var requires = (module.dependencies || []).sort().map(function(dep) { + return dep.indexOf(module.name) === 0 ? '' : 'goog.require(\'' + moduleNameToClosureName(dep) + '\');'; }).join('\n'); file.contents = new Buffer([ 'goog.provide(\'' + closureModuleName + '\');', requires, file.contents.toString(), - closureModuleName + ' = angular.module("' + moduleInfo.module + '");' + closureModuleName + ' = angular.module("' + module.name + '");' ].join('\n')); } this.push(file); @@ -234,10 +237,10 @@ exports.addClosurePrefixes = function() { exports.buildModuleBower = function(name, version) { return through2.obj(function(file, enc, next) { this.push(file); - var moduleInfo = getModuleInfo(file.contents); - if (moduleInfo.module) { + var module = findModule.any(file.contents); + if (module) { var bowerDeps = {}; - (moduleInfo.dependencies || []).forEach(function(dep) { + (module.dependencies || []).forEach(function(dep) { var convertedName = 'angular-material-' + dep.split('.').pop(); bowerDeps[convertedName] = version; }); diff --git a/src/components/bottomSheet/bottom-sheet.js b/src/components/bottomSheet/bottom-sheet.js index 78cbc76a917..d8db2a55c3b 100644 --- a/src/components/bottomSheet/bottom-sheet.js +++ b/src/components/bottomSheet/bottom-sheet.js @@ -4,10 +4,11 @@ * @description * BottomSheet */ -angular.module('material.components.bottomSheet', [ - 'material.core', - 'material.components.backdrop' -]) +angular + .module('material.components.bottomSheet', [ + 'material.core', + 'material.components.backdrop' + ]) .directive('mdBottomSheet', MdBottomSheetDirective) .provider('$mdBottomSheet', MdBottomSheetProvider); diff --git a/src/components/select/select.js b/src/components/select/select.js index a4053ba5800..52f9f247e4f 100755 --- a/src/components/select/select.js +++ b/src/components/select/select.js @@ -22,9 +22,9 @@ var SELECT_EDGE_MARGIN = 8; var selectNextId = 0; angular.module('material.components.select', [ - 'material.core', - 'material.components.backdrop' -]) + 'material.core', + 'material.components.backdrop' + ]) .directive('mdSelect', SelectDirective) .directive('mdSelectMenu', SelectMenuDirective) .directive('mdOption', OptionDirective) diff --git a/src/components/sidenav/sidenav.js b/src/components/sidenav/sidenav.js index 02f3a5cff07..f99358be9cb 100644 --- a/src/components/sidenav/sidenav.js +++ b/src/components/sidenav/sidenav.js @@ -5,7 +5,8 @@ * @description * A Sidenav QP component. */ -angular.module('material.components.sidenav', [ +angular + .module('material.components.sidenav', [ 'material.core', 'material.components.backdrop' ]) @@ -16,7 +17,6 @@ angular.module('material.components.sidenav', [ /** - * @private * @ngdoc service * @name $mdSidenav * @module material.components.sidenav diff --git a/src/components/sticky/sticky.js b/src/components/sticky/sticky.js index ad5e64f3cb5..0aea4290763 100644 --- a/src/components/sticky/sticky.js +++ b/src/components/sticky/sticky.js @@ -1,18 +1,18 @@ -/* +/** * @ngdoc module * @name material.components.sticky * @description - * * Sticky effects for md + * */ - -angular.module('material.components.sticky', [ - 'material.core', - 'material.components.content' -]) +angular + .module('material.components.sticky', [ + 'material.core', + 'material.components.content' + ]) .factory('$mdSticky', MdSticky); -/* +/** * @ngdoc service * @name $mdSticky * @module material.components.sticky @@ -27,7 +27,6 @@ angular.module('material.components.sticky', [ * when the user starts scrolling past the original element. * If not provided, it will use the result of `element.clone()`. */ - function MdSticky($document, $mdConstant, $$rAF, $mdUtil) { var browserStickySupport = checkStickySupport(); @@ -134,7 +133,6 @@ function MdSticky($document, $mdConstant, $$rAF, $mdUtil) { setCurrentItem(item); } - /*************** * Private ***************/ @@ -159,7 +157,6 @@ function MdSticky($document, $mdConstant, $$rAF, $mdUtil) { } } - // As we scroll, push in and select the correct sticky element. function onScroll() { var scrollTop = contentEl.prop('scrollTop'); @@ -220,55 +217,55 @@ function MdSticky($document, $mdConstant, $$rAF, $mdUtil) { translate(self.current, scrollTop); } } - - function setCurrentItem(item) { - if (self.current === item) return; - // Deactivate currently active item - if (self.current) { - translate(self.current, null); - setStickyState(self.current, null); - } - - // Activate new item if given - if (item) { - setStickyState(item, 'active'); - } - - self.current = item; - var index = self.items.indexOf(item); - // If index === -1, index + 1 = 0. It works out. - self.next = self.items[index + 1]; - self.prev = self.items[index - 1]; - setStickyState(self.next, 'next'); - setStickyState(self.prev, 'prev'); - } - - function setStickyState(item, state) { - if (!item || item.state === state) return; - if (item.state) { - item.clone.attr('sticky-prev-state', item.state); - item.element.attr('sticky-prev-state', item.state); - } - item.clone.attr('sticky-state', state); - item.element.attr('sticky-state', state); - item.state = state; - } - - function translate(item, amount) { - if (!item) return; - if (amount === null || amount === undefined) { - if (item.translateY) { - item.translateY = null; - item.clone.css($mdConstant.CSS.TRANSFORM, ''); - } - } else { - item.translateY = amount; - item.clone.css( - $mdConstant.CSS.TRANSFORM, - 'translate3d(' + item.left + 'px,' + amount + 'px,0)' - ); - } - } + + function setCurrentItem(item) { + if (self.current === item) return; + // Deactivate currently active item + if (self.current) { + translate(self.current, null); + setStickyState(self.current, null); + } + + // Activate new item if given + if (item) { + setStickyState(item, 'active'); + } + + self.current = item; + var index = self.items.indexOf(item); + // If index === -1, index + 1 = 0. It works out. + self.next = self.items[index + 1]; + self.prev = self.items[index - 1]; + setStickyState(self.next, 'next'); + setStickyState(self.prev, 'prev'); + } + + function setStickyState(item, state) { + if (!item || item.state === state) return; + if (item.state) { + item.clone.attr('sticky-prev-state', item.state); + item.element.attr('sticky-prev-state', item.state); + } + item.clone.attr('sticky-state', state); + item.element.attr('sticky-state', state); + item.state = state; + } + + function translate(item, amount) { + if (!item) return; + if (amount === null || amount === undefined) { + if (item.translateY) { + item.translateY = null; + item.clone.css($mdConstant.CSS.TRANSFORM, ''); + } + } else { + item.translateY = amount; + item.clone.css( + $mdConstant.CSS.TRANSFORM, + 'translate3d(' + item.left + 'px,' + amount + 'px,0)' + ); + } + } } // Function to check for browser sticky support diff --git a/src/components/subheader/subheader.js b/src/components/subheader/subheader.js index 8db1b49c2b8..c3f7d4de39c 100644 --- a/src/components/subheader/subheader.js +++ b/src/components/subheader/subheader.js @@ -16,10 +16,11 @@ * > To improve the visual grouping of content, use the system color for your subheaders. * */ -angular.module('material.components.subheader', [ - 'material.core', - 'material.components.sticky' -]) +angular + .module('material.components.subheader', [ + 'material.core', + 'material.components.sticky' + ]) .directive('mdSubheader', MdSubheaderDirective); /** diff --git a/src/core/services/theming/theming.js b/src/core/services/theming/theming.js index 199c65368db..67bc9c5be0a 100644 --- a/src/core/services/theming/theming.js +++ b/src/core/services/theming/theming.js @@ -5,9 +5,9 @@ angular.module('material.core.theming', ['material.core.theming.palette']) .run(generateThemes); /** - * @ngdoc provider + * @ngdoc service * @name $mdThemingProvider - * @module material.core + * @module material.core.theming * * @description Provider to configure the `$mdTheming` service. */