diff --git a/gulpfile.js b/gulpfile.js index 6506f80496b..fd3dc2e8d04 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -84,12 +84,12 @@ var buildModes = { useBower: false }, 'demos': { - transform: gutil.noop, + transform: utils.addJsWrapper, outputDir: path.join(config.outputDir, 'demos') + path.sep, useBower: false }, 'default': { - transform: gutil.noop, + transform: utils.addJsWrapper, outputDir: path.join(config.outputDir, 'modules/js') + path.sep, useBower: true } diff --git a/scripts/gulp-utils.js b/scripts/gulp-utils.js index 7fd3320185e..0250102bdbb 100644 --- a/scripts/gulp-utils.js +++ b/scripts/gulp-utils.js @@ -172,21 +172,17 @@ exports.addClosurePrefixes = function() { return through2.obj(function(file, enc, next) { var moduleInfo = getModuleInfo(file.contents); if (moduleInfo.module) { - var closureModuleName = moduleNameToClosureName(moduleInfo.module); - var provide = 'goog.provide(\'' + closureModuleName + '\');'; var requires = (moduleInfo.dependencies || []).sort().map(function(dep) { return dep.indexOf(moduleInfo.module) === 0 ? '' : 'goog.require(\'' + moduleNameToClosureName(dep) + '\');'; }).join('\n'); - - var contents = file.contents.toString(); - - // Assign the module to the provided Closure namespace: - contents = contents.replace('angular.module', closureModuleName + ' = angular.module'); - file.contents = new Buffer( - provide + '\n' + requires + '\n' + contents - ); + file.contents = new Buffer([ + 'goog.provide(\'' + closureModuleName + '\');', + requires, + file.contents.toString(), + closureModuleName + '= angular.module(' + moduleInfo.module + ');' + ].join('\n')); } this.push(file); next(); @@ -196,17 +192,13 @@ 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 bowerDeps = {}; - (moduleInfo.dependencies || []).forEach(function(dep) { var convertedName = 'angular-material-' + dep.split('.').pop(); bowerDeps[convertedName] = version; }); - var bowerContents = JSON.stringify({ name: 'angular-material-' + name, version: version, diff --git a/src/components/autocomplete/autocomplete.js b/src/components/autocomplete/autocomplete.js index 197d9b5453a..0b086d308e6 100644 --- a/src/components/autocomplete/autocomplete.js +++ b/src/components/autocomplete/autocomplete.js @@ -1,14 +1,11 @@ -(function () { - 'use strict'; - /** - * @ngdoc module - * @name material.components.autocomplete - */ - /* - * @see js folder for autocomplete implementation - */ - angular.module('material.components.autocomplete', [ - 'material.core', - 'material.components.icon' - ]); -})(); +/** + * @ngdoc module + * @name material.components.autocomplete + */ +/* + * @see js folder for autocomplete implementation + */ +angular.module('material.components.autocomplete', [ + 'material.core', + 'material.components.icon' +]); diff --git a/src/components/autocomplete/js/autocompleteController.js b/src/components/autocomplete/js/autocompleteController.js index 95187dea332..49ca3c1c851 100644 --- a/src/components/autocomplete/js/autocompleteController.js +++ b/src/components/autocomplete/js/autocompleteController.js @@ -1,376 +1,373 @@ -(function () { - 'use strict'; - angular - .module('material.components.autocomplete') - .controller('MdAutocompleteCtrl', MdAutocompleteCtrl); - - var ITEM_HEIGHT = 41, - MAX_HEIGHT = 5.5 * ITEM_HEIGHT, - MENU_PADDING = 8; - - function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $mdTheming, $window, $rootElement) { - - //-- private variables - - var self = this, - itemParts = $scope.itemsExpr.split(/ in /i), - itemExpr = itemParts[1], - elements = null, - promise = null, - cache = {}, - noBlur = false, - selectedItemWatchers = [], - hasFocus = false; - - //-- public variables - - self.scope = $scope; - self.parent = $scope.$parent; - self.itemName = itemParts[0]; - self.matches = []; - self.loading = false; - self.hidden = true; - self.index = null; - self.messages = []; - self.id = $mdUtil.nextUid(); - - //-- public methods - - self.keydown = keydown; - self.blur = blur; - self.focus = focus; - self.clear = clearValue; - self.select = select; - self.getCurrentDisplayValue = getCurrentDisplayValue; - self.registerSelectedItemWatcher = registerSelectedItemWatcher; - self.unregisterSelectedItemWatcher = unregisterSelectedItemWatcher; - - self.listEnter = function () { noBlur = true; }; - self.listLeave = function () { - noBlur = false; - if (!hasFocus) self.hidden = true; - }; - self.mouseUp = function () { elements.input.focus(); }; - - return init(); - - //-- initialization methods +angular + .module('material.components.autocomplete') + .controller('MdAutocompleteCtrl', MdAutocompleteCtrl); + +var ITEM_HEIGHT = 41, + MAX_HEIGHT = 5.5 * ITEM_HEIGHT, + MENU_PADDING = 8; + +function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $timeout, $mdTheming, $window, $rootElement) { + + //-- private variables + + var self = this, + itemParts = $scope.itemsExpr.split(/ in /i), + itemExpr = itemParts[1], + elements = null, + promise = null, + cache = {}, + noBlur = false, + selectedItemWatchers = [], + hasFocus = false; + + //-- public variables + + self.scope = $scope; + self.parent = $scope.$parent; + self.itemName = itemParts[0]; + self.matches = []; + self.loading = false; + self.hidden = true; + self.index = null; + self.messages = []; + self.id = $mdUtil.nextUid(); + + //-- public methods + + self.keydown = keydown; + self.blur = blur; + self.focus = focus; + self.clear = clearValue; + self.select = select; + self.getCurrentDisplayValue = getCurrentDisplayValue; + self.registerSelectedItemWatcher = registerSelectedItemWatcher; + self.unregisterSelectedItemWatcher = unregisterSelectedItemWatcher; + + self.listEnter = function () { noBlur = true; }; + self.listLeave = function () { + noBlur = false; + if (!hasFocus) self.hidden = true; + }; + self.mouseUp = function () { elements.input.focus(); }; + + return init(); + + //-- initialization methods + + function init () { + configureWatchers(); + $timeout(function () { + gatherElements(); + focusElement(); + moveDropdown(); + }); + } - function init () { - configureWatchers(); - $timeout(function () { - gatherElements(); - focusElement(); - moveDropdown(); - }); + function positionDropdown () { + if (!elements) return $timeout(positionDropdown, 0, false); + var hrect = elements.wrap.getBoundingClientRect(), + vrect = elements.snap.getBoundingClientRect(), + root = elements.root.getBoundingClientRect(), + top = vrect.bottom - root.top, + bot = root.bottom - vrect.top, + left = hrect.left - root.left, + width = hrect.width, + styles = { + left: left + 'px', + minWidth: width + 'px', + maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px' + }; + if (top > bot && root.height - hrect.bottom - MENU_PADDING < MAX_HEIGHT) { + styles.top = 'auto'; + styles.bottom = bot + 'px'; + styles.maxHeight = Math.min(MAX_HEIGHT, hrect.top - root.top - MENU_PADDING) + 'px'; + } else { + styles.top = top + 'px'; + styles.bottom = 'auto'; + styles.maxHeight = Math.min(MAX_HEIGHT, root.bottom - hrect.bottom - MENU_PADDING) + 'px'; } - - function positionDropdown () { - if (!elements) return $timeout(positionDropdown, 0, false); - var hrect = elements.wrap.getBoundingClientRect(), - vrect = elements.snap.getBoundingClientRect(), - root = elements.root.getBoundingClientRect(), - top = vrect.bottom - root.top, - bot = root.bottom - vrect.top, - left = hrect.left - root.left, - width = hrect.width, - styles = { - left: left + 'px', - minWidth: width + 'px', - maxWidth: Math.max(hrect.right - root.left, root.right - hrect.left) - MENU_PADDING + 'px' - }; - if (top > bot && root.height - hrect.bottom - MENU_PADDING < MAX_HEIGHT) { - styles.top = 'auto'; - styles.bottom = bot + 'px'; - styles.maxHeight = Math.min(MAX_HEIGHT, hrect.top - root.top - MENU_PADDING) + 'px'; - } else { - styles.top = top + 'px'; - styles.bottom = 'auto'; - styles.maxHeight = Math.min(MAX_HEIGHT, root.bottom - hrect.bottom - MENU_PADDING) + 'px'; + elements.$.ul.css(styles); + $timeout(correctHorizontalAlignment, 0, false); + + function correctHorizontalAlignment () { + var dropdown = elements.ul.getBoundingClientRect(), + styles = {}; + if (dropdown.right > root.right - MENU_PADDING) { + styles.left = (hrect.right - dropdown.width) + 'px'; } elements.$.ul.css(styles); - $timeout(correctHorizontalAlignment, 0, false); - - function correctHorizontalAlignment () { - var dropdown = elements.ul.getBoundingClientRect(), - styles = {}; - if (dropdown.right > root.right - MENU_PADDING) { - styles.left = (hrect.right - dropdown.width) + 'px'; - } - elements.$.ul.css(styles); - } } + } - function moveDropdown () { - if (!elements.$.root.length) return; - $mdTheming(elements.$.ul); - elements.$.ul.detach(); - elements.$.root.append(elements.$.ul); - } + function moveDropdown () { + if (!elements.$.root.length) return; + $mdTheming(elements.$.ul); + elements.$.ul.detach(); + elements.$.root.append(elements.$.ul); + } - function focusElement () { - if ($scope.autofocus) elements.input.focus(); - } + function focusElement () { + if ($scope.autofocus) elements.input.focus(); + } - function configureWatchers () { - var wait = parseInt($scope.delay, 10) || 0; - $scope.$watch('searchText', wait - ? $mdUtil.debounce(handleSearchText, wait) - : handleSearchText); - registerSelectedItemWatcher(selectedItemChange); - $scope.$watch('selectedItem', handleSelectedItemChange); - $scope.$watch('$mdAutocompleteCtrl.hidden', function (hidden, oldHidden) { - if (!hidden && oldHidden) positionDropdown(); - }); - angular.element($window).on('resize', positionDropdown); - } + function configureWatchers () { + var wait = parseInt($scope.delay, 10) || 0; + $scope.$watch('searchText', wait + ? $mdUtil.debounce(handleSearchText, wait) + : handleSearchText); + registerSelectedItemWatcher(selectedItemChange); + $scope.$watch('selectedItem', handleSelectedItemChange); + $scope.$watch('$mdAutocompleteCtrl.hidden', function (hidden, oldHidden) { + if (!hidden && oldHidden) positionDropdown(); + }); + angular.element($window).on('resize', positionDropdown); + } - function gatherElements () { - elements = { - main: $element[0], - ul: $element.find('ul')[0], - input: $element.find('input')[0], - wrap: $element.find('md-autocomplete-wrap')[0], - root: document.body - }; - elements.snap = getSnapTarget(); - elements.$ = getAngularElements(elements); - } + function gatherElements () { + elements = { + main: $element[0], + ul: $element.find('ul')[0], + input: $element.find('input')[0], + wrap: $element.find('md-autocomplete-wrap')[0], + root: document.body + }; + elements.snap = getSnapTarget(); + elements.$ = getAngularElements(elements); + } - function getSnapTarget () { - for (var element = $element; element.length; element = element.parent()) { - if (angular.isDefined(element.attr('md-autocomplete-snap'))) return element[0]; - } - return elements.wrap; + function getSnapTarget () { + for (var element = $element; element.length; element = element.parent()) { + if (angular.isDefined(element.attr('md-autocomplete-snap'))) return element[0]; } + return elements.wrap; + } - function getAngularElements (elements) { - var obj = {}; - for (var key in elements) { - obj[key] = angular.element(elements[key]); - } - return obj; + function getAngularElements (elements) { + var obj = {}; + for (var key in elements) { + obj[key] = angular.element(elements[key]); } + return obj; + } - //-- event/change handlers + //-- event/change handlers - function selectedItemChange (selectedItem, previousSelectedItem) { - if (selectedItem) { - $scope.searchText = getDisplayValue(selectedItem); - } - if ($scope.itemChange && selectedItem !== previousSelectedItem) - $scope.itemChange(getItemScope(selectedItem)); + function selectedItemChange (selectedItem, previousSelectedItem) { + if (selectedItem) { + $scope.searchText = getDisplayValue(selectedItem); } + if ($scope.itemChange && selectedItem !== previousSelectedItem) + $scope.itemChange(getItemScope(selectedItem)); + } - function handleSelectedItemChange(selectedItem, previousSelectedItem) { - for (var i = 0; i < selectedItemWatchers.length; ++i) { - selectedItemWatchers[i](selectedItem, previousSelectedItem); - } + function handleSelectedItemChange(selectedItem, previousSelectedItem) { + for (var i = 0; i < selectedItemWatchers.length; ++i) { + selectedItemWatchers[i](selectedItem, previousSelectedItem); } + } - /** - * Register a function to be called when the selected item changes. - * @param cb - */ - function registerSelectedItemWatcher(cb) { - if (selectedItemWatchers.indexOf(cb) == -1) { - selectedItemWatchers.push(cb); - } + /** + * Register a function to be called when the selected item changes. + * @param cb + */ + function registerSelectedItemWatcher(cb) { + if (selectedItemWatchers.indexOf(cb) == -1) { + selectedItemWatchers.push(cb); } + } - /** - * Unregister a function previously registered for selected item changes. - * @param cb - */ - function unregisterSelectedItemWatcher(cb) { - var i = selectedItemWatchers.indexOf(cb); - if (i != -1) { - selectedItemWatchers.splice(i, 1); - } + /** + * Unregister a function previously registered for selected item changes. + * @param cb + */ + function unregisterSelectedItemWatcher(cb) { + var i = selectedItemWatchers.indexOf(cb); + if (i != -1) { + selectedItemWatchers.splice(i, 1); } + } - function handleSearchText (searchText, previousSearchText) { - self.index = getDefaultIndex(); - //-- do nothing on init if there is no initial value - if (!searchText && searchText === previousSearchText) return; - //-- clear selected item if search text no longer matches it - if (searchText !== getDisplayValue($scope.selectedItem)) $scope.selectedItem = null; - else return; - //-- trigger change event if available - if ($scope.textChange && searchText !== previousSearchText) - $scope.textChange(getItemScope($scope.selectedItem)); - //-- cancel results if search text is not long enough - if (!isMinLengthMet()) { - self.loading = false; - self.matches = []; - self.hidden = shouldHide(); - updateMessages(); - } else { - handleQuery(); - } + function handleSearchText (searchText, previousSearchText) { + self.index = getDefaultIndex(); + //-- do nothing on init if there is no initial value + if (!searchText && searchText === previousSearchText) return; + //-- clear selected item if search text no longer matches it + if (searchText !== getDisplayValue($scope.selectedItem)) $scope.selectedItem = null; + else return; + //-- trigger change event if available + if ($scope.textChange && searchText !== previousSearchText) + $scope.textChange(getItemScope($scope.selectedItem)); + //-- cancel results if search text is not long enough + if (!isMinLengthMet()) { + self.loading = false; + self.matches = []; + self.hidden = shouldHide(); + updateMessages(); + } else { + handleQuery(); } + } - function blur () { - hasFocus = false; - if (!noBlur) self.hidden = true; - } + function blur () { + hasFocus = false; + if (!noBlur) self.hidden = true; + } - function focus () { - hasFocus = true; - //-- if searchText is null, let's force it to be a string - if (!angular.isString($scope.searchText)) $scope.searchText = ''; - if ($scope.minLength > 0) return; - self.hidden = shouldHide(); - if (!self.hidden) handleQuery(); - } + function focus () { + hasFocus = true; + //-- if searchText is null, let's force it to be a string + if (!angular.isString($scope.searchText)) $scope.searchText = ''; + if ($scope.minLength > 0) return; + self.hidden = shouldHide(); + if (!self.hidden) handleQuery(); + } - function keydown (event) { - switch (event.keyCode) { - case $mdConstant.KEY_CODE.DOWN_ARROW: - if (self.loading) return; - event.preventDefault(); - self.index = Math.min(self.index + 1, self.matches.length - 1); - updateScroll(); - updateSelectionMessage(); - break; - case $mdConstant.KEY_CODE.UP_ARROW: - if (self.loading) return; - event.preventDefault(); - self.index = self.index < 0 ? self.matches.length - 1 : Math.max(0, self.index - 1); - updateScroll(); - updateSelectionMessage(); - break; - case $mdConstant.KEY_CODE.ENTER: - if (self.hidden || self.loading || self.index < 0) return; - event.preventDefault(); - select(self.index); - break; - case $mdConstant.KEY_CODE.ESCAPE: - self.matches = []; - self.hidden = true; - self.index = getDefaultIndex(); - break; - case $mdConstant.KEY_CODE.TAB: - break; - default: - } + function keydown (event) { + switch (event.keyCode) { + case $mdConstant.KEY_CODE.DOWN_ARROW: + if (self.loading) return; + event.preventDefault(); + self.index = Math.min(self.index + 1, self.matches.length - 1); + updateScroll(); + updateSelectionMessage(); + break; + case $mdConstant.KEY_CODE.UP_ARROW: + if (self.loading) return; + event.preventDefault(); + self.index = self.index < 0 ? self.matches.length - 1 : Math.max(0, self.index - 1); + updateScroll(); + updateSelectionMessage(); + break; + case $mdConstant.KEY_CODE.ENTER: + if (self.hidden || self.loading || self.index < 0) return; + event.preventDefault(); + select(self.index); + break; + case $mdConstant.KEY_CODE.ESCAPE: + self.matches = []; + self.hidden = true; + self.index = getDefaultIndex(); + break; + case $mdConstant.KEY_CODE.TAB: + break; + default: } + } - //-- getters + //-- getters - function getMinLength () { - return angular.isNumber($scope.minLength) ? $scope.minLength : 1; - } + function getMinLength () { + return angular.isNumber($scope.minLength) ? $scope.minLength : 1; + } - function getDisplayValue (item) { - return (item && $scope.itemText) ? $scope.itemText(getItemScope(item)) : item; - } + function getDisplayValue (item) { + return (item && $scope.itemText) ? $scope.itemText(getItemScope(item)) : item; + } - function getItemScope (item) { - if (!item) return; - var locals = {}; - if (self.itemName) locals[self.itemName] = item; - return locals; - } + function getItemScope (item) { + if (!item) return; + var locals = {}; + if (self.itemName) locals[self.itemName] = item; + return locals; + } - function getDefaultIndex () { - return $scope.autoselect ? 0 : -1; - } + function getDefaultIndex () { + return $scope.autoselect ? 0 : -1; + } - function shouldHide () { - if (!isMinLengthMet()) return true; - } + function shouldHide () { + if (!isMinLengthMet()) return true; + } - function getCurrentDisplayValue () { - return getDisplayValue(self.matches[self.index]); - } + function getCurrentDisplayValue () { + return getDisplayValue(self.matches[self.index]); + } - function isMinLengthMet () { - return $scope.searchText.length >= getMinLength(); - } + function isMinLengthMet () { + return $scope.searchText.length >= getMinLength(); + } - //-- actions + //-- actions - function select (index) { - $scope.selectedItem = self.matches[index]; - $scope.searchText = getDisplayValue($scope.selectedItem) || $scope.searchText; - self.hidden = true; - self.index = 0; - self.matches = []; - } + function select (index) { + $scope.selectedItem = self.matches[index]; + $scope.searchText = getDisplayValue($scope.selectedItem) || $scope.searchText; + self.hidden = true; + self.index = 0; + self.matches = []; + } - function clearValue () { - $scope.searchText = ''; - select(-1); - elements.input.focus(); - } + function clearValue () { + $scope.searchText = ''; + select(-1); + elements.input.focus(); + } - function fetchResults (searchText) { - var items = $scope.$parent.$eval(itemExpr), - term = searchText.toLowerCase(); - if (angular.isArray(items)) { - handleResults(items); - } else { - self.loading = true; - if (items.success) items.success(handleResults); - if (items.then) items.then(handleResults); - if (items.error) items.error(function () { self.loading = false; }); - } - function handleResults (matches) { - cache[term] = matches; - if (searchText !== $scope.searchText) return; //-- just cache the results if old request - promise = null; - self.loading = false; - self.matches = matches; - self.hidden = shouldHide(); - updateMessages(); - positionDropdown(); - } + function fetchResults (searchText) { + var items = $scope.$parent.$eval(itemExpr), + term = searchText.toLowerCase(); + if (angular.isArray(items)) { + handleResults(items); + } else { + self.loading = true; + if (items.success) items.success(handleResults); + if (items.then) items.then(handleResults); + if (items.error) items.error(function () { self.loading = false; }); } - - function updateMessages () { - if (self.hidden) return; - switch (self.matches.length) { - case 0: return self.messages.splice(0); - case 1: return self.messages.push({ display: 'There is 1 match available.' }); - default: return self.messages.push({ display: 'There are ' - + self.matches.length - + ' matches available.' }); - } + function handleResults (matches) { + cache[term] = matches; + if (searchText !== $scope.searchText) return; //-- just cache the results if old request + promise = null; + self.loading = false; + self.matches = matches; + self.hidden = shouldHide(); + updateMessages(); + positionDropdown(); } + } - function updateSelectionMessage () { - self.messages.push({ display: getCurrentDisplayValue() }); + function updateMessages () { + if (self.hidden) return; + switch (self.matches.length) { + case 0: return self.messages.splice(0); + case 1: return self.messages.push({ display: 'There is 1 match available.' }); + default: return self.messages.push({ display: 'There are ' + + self.matches.length + + ' matches available.' }); } + } - function updateScroll () { - var top = ITEM_HEIGHT * self.index, - bot = top + ITEM_HEIGHT, - hgt = elements.ul.clientHeight; - if (top < elements.ul.scrollTop) { - elements.ul.scrollTop = top; - } else if (bot > elements.ul.scrollTop + hgt) { - elements.ul.scrollTop = bot - hgt; - } - } + function updateSelectionMessage () { + self.messages.push({ display: getCurrentDisplayValue() }); + } - function handleQuery () { - var searchText = $scope.searchText, - term = searchText.toLowerCase(); - //-- cancel promise if a promise is in progress - if (promise && promise.cancel) { - promise.cancel(); - promise = null; - } - //-- if results are cached, pull in cached results - if (!$scope.noCache && cache[term]) { - self.matches = cache[term]; - updateMessages(); - } else { - fetchResults(searchText); - } - self.hidden = shouldHide(); + function updateScroll () { + var top = ITEM_HEIGHT * self.index, + bot = top + ITEM_HEIGHT, + hgt = elements.ul.clientHeight; + if (top < elements.ul.scrollTop) { + elements.ul.scrollTop = top; + } else if (bot > elements.ul.scrollTop + hgt) { + elements.ul.scrollTop = bot - hgt; } + } + function handleQuery () { + var searchText = $scope.searchText, + term = searchText.toLowerCase(); + //-- cancel promise if a promise is in progress + if (promise && promise.cancel) { + promise.cancel(); + promise = null; + } + //-- if results are cached, pull in cached results + if (!$scope.noCache && cache[term]) { + self.matches = cache[term]; + updateMessages(); + } else { + fetchResults(searchText); + } + self.hidden = shouldHide(); } -})(); + +} diff --git a/src/components/autocomplete/js/autocompleteDirective.js b/src/components/autocomplete/js/autocompleteDirective.js index 7ee25683446..b48c0d4080f 100644 --- a/src/components/autocomplete/js/autocompleteDirective.js +++ b/src/components/autocomplete/js/autocompleteDirective.js @@ -1,155 +1,152 @@ -(function () { - 'use strict'; - angular - .module('material.components.autocomplete') - .directive('mdAutocomplete', MdAutocomplete); +angular + .module('material.components.autocomplete') + .directive('mdAutocomplete', MdAutocomplete); - /** - * @ngdoc directive - * @name mdAutocomplete - * @module material.components.autocomplete - * - * @description - * `` is a special input component with a drop-down of all possible matches to a custom query. - * This component allows you to provide real-time suggestions as the user types in the input area. - * - * @param {expression} md-items An expression in the format of `item in items` to iterate over matches for your search. - * @param {expression} md-selected-item-change An expression to be run each time a new item is selected - * @param {expression} md-search-text-change An expression to be run each time the search text updates - * @param {string=} md-search-text A model to bind the search query text to - * @param {object=} md-selected-item A model to bind the selected item to - * @param {string=} md-item-text An expression that will convert your object to a single string. - * @param {string=} placeholder Placeholder text that will be forwarded to the input. - * @param {boolean=} md-no-cache Disables the internal caching that happens in autocomplete - * @param {boolean=} ng-disabled Determines whether or not to disable the input field - * @param {number=} md-min-length Specifies the minimum length of text before autocomplete will make suggestions - * @param {number=} md-delay Specifies the amount of time (in milliseconds) to wait before looking for results - * @param {boolean=} md-autofocus If true, will immediately focus the input element - * @param {boolean=} md-autoselect If true, the first item will be selected by default - * @param {string=} md-menu-class This will be applied to the dropdown menu for styling - * - * @usage - * - * - * {{item.display}} - * - * - */ +/** + * @ngdoc directive + * @name mdAutocomplete + * @module material.components.autocomplete + * + * @description + * `` is a special input component with a drop-down of all possible matches to a custom query. + * This component allows you to provide real-time suggestions as the user types in the input area. + * + * @param {expression} md-items An expression in the format of `item in items` to iterate over matches for your search. + * @param {expression} md-selected-item-change An expression to be run each time a new item is selected + * @param {expression} md-search-text-change An expression to be run each time the search text updates + * @param {string=} md-search-text A model to bind the search query text to + * @param {object=} md-selected-item A model to bind the selected item to + * @param {string=} md-item-text An expression that will convert your object to a single string. + * @param {string=} placeholder Placeholder text that will be forwarded to the input. + * @param {boolean=} md-no-cache Disables the internal caching that happens in autocomplete + * @param {boolean=} ng-disabled Determines whether or not to disable the input field + * @param {number=} md-min-length Specifies the minimum length of text before autocomplete will make suggestions + * @param {number=} md-delay Specifies the amount of time (in milliseconds) to wait before looking for results + * @param {boolean=} md-autofocus If true, will immediately focus the input element + * @param {boolean=} md-autoselect If true, the first item will be selected by default + * @param {string=} md-menu-class This will be applied to the dropdown menu for styling + * + * @usage + * + * + * {{item.display}} + * + * + */ - function MdAutocomplete ($mdTheming) { - return { - controller: 'MdAutocompleteCtrl', - controllerAs: '$mdAutocompleteCtrl', - link: link, - scope: { - name: '@', - searchText: '=?mdSearchText', - selectedItem: '=?mdSelectedItem', - itemsExpr: '@mdItems', - itemText: '&mdItemText', - placeholder: '@placeholder', - noCache: '=?mdNoCache', - itemChange: '&?mdSelectedItemChange', - textChange: '&?mdSearchTextChange', - isDisabled: '=?ngDisabled', - minLength: '=?mdMinLength', - delay: '=?mdDelay', - autofocus: '=?mdAutofocus', - floatingLabel: '@?mdFloatingLabel', - autoselect: '=?mdAutoselect', - menuClass: '@?mdMenuClass' - }, - template: function (element, attr) { - //-- grab the original HTML for custom transclusion before Angular attempts to parse it - //-- the HTML is being stored on the attr object so that it is available to postLink - attr.$mdAutocompleteTemplate = element.html(); - //-- return the replacement template, which will wipe out the original HTML - return '\ - \ - \ - \ - \ - \ - \ +function MdAutocomplete ($mdTheming) { + return { + controller: 'MdAutocompleteCtrl', + controllerAs: '$mdAutocompleteCtrl', + link: link, + scope: { + name: '@', + searchText: '=?mdSearchText', + selectedItem: '=?mdSelectedItem', + itemsExpr: '@mdItems', + itemText: '&mdItemText', + placeholder: '@placeholder', + noCache: '=?mdNoCache', + itemChange: '&?mdSelectedItemChange', + textChange: '&?mdSearchTextChange', + isDisabled: '=?ngDisabled', + minLength: '=?mdMinLength', + delay: '=?mdDelay', + autofocus: '=?mdAutofocus', + floatingLabel: '@?mdFloatingLabel', + autoselect: '=?mdAutoselect', + menuClass: '@?mdMenuClass' + }, + template: function (element, attr) { + //-- grab the original HTML for custom transclusion before Angular attempts to parse it + //-- the HTML is being stored on the attr object so that it is available to postLink + attr.$mdAutocompleteTemplate = element.html(); + //-- return the replacement template, which will wipe out the original HTML + return '\ + \ + \ + \ \ - \ - \ - Clear\ - \ - \ - \ - \ - \ -

{{message.display}}

\ - '; - } - }; - - function link (scope, element, attr) { - scope.contents = attr.$mdAutocompleteTemplate; - delete attr.$mdAutocompleteTemplate; - angular.forEach(scope.$$isolateBindings, function (binding, key) { - if (binding.optional && angular.isUndefined(scope[key])) { - scope[key] = attr.hasOwnProperty(attr.$normalize(binding.attrName)); - } - }); - $mdTheming(element); + \ + \ + \ + \ + \ + Clear\ + \ + \ + \ +
\ + \ +

{{message.display}}

\ + '; } + }; + + function link (scope, element, attr) { + scope.contents = attr.$mdAutocompleteTemplate; + delete attr.$mdAutocompleteTemplate; + angular.forEach(scope.$$isolateBindings, function (binding, key) { + if (binding.optional && angular.isUndefined(scope[key])) { + scope[key] = attr.hasOwnProperty(attr.$normalize(binding.attrName)); + } + }); + $mdTheming(element); } -})(); +} diff --git a/src/components/autocomplete/js/highlightController.js b/src/components/autocomplete/js/highlightController.js index 99f41406d14..78cf7f4ddcb 100644 --- a/src/components/autocomplete/js/highlightController.js +++ b/src/components/autocomplete/js/highlightController.js @@ -1,32 +1,28 @@ -(function () { - 'use strict'; - angular - .module('material.components.autocomplete') - .controller('MdHighlightCtrl', MdHighlightCtrl); +angular + .module('material.components.autocomplete') + .controller('MdHighlightCtrl', MdHighlightCtrl); - function MdHighlightCtrl ($scope, $element, $interpolate) { - var term = $element.attr('md-highlight-text'), - text = $interpolate($element.text())($scope), - flags = $element.attr('md-highlight-flags') || '', - watcher = $scope.$watch(term, function (term) { - var regex = getRegExp(term, flags), - html = text.replace(regex, '$&'); - $element.html(html); - }); - $element.on('$destroy', function () { watcher(); }); +function MdHighlightCtrl ($scope, $element, $interpolate) { + var term = $element.attr('md-highlight-text'), + text = $interpolate($element.text())($scope), + flags = $element.attr('md-highlight-flags') || '', + watcher = $scope.$watch(term, function (term) { + var regex = getRegExp(term, flags), + html = text.replace(regex, '$&'); + $element.html(html); + }); + $element.on('$destroy', function () { watcher(); }); - function sanitize (term) { - if (!term) return term; - return term.replace(/[\*\[\]\(\)\{\}\\\^\$]/g, '\\$&'); - } - - function getRegExp (text, flags) { - var str = ''; - if (flags.indexOf('^') >= 1) str += '^'; - str += text; - if (flags.indexOf('$') >= 1) str += '$'; - return new RegExp(sanitize(str), flags.replace(/[\$\^]/g, '')); - } + function sanitize (term) { + if (!term) return term; + return term.replace(/[\*\[\]\(\)\{\}\\\^\$]/g, '\\$&'); } -})(); + function getRegExp (text, flags) { + var str = ''; + if (flags.indexOf('^') >= 1) str += '^'; + str += text; + if (flags.indexOf('$') >= 1) str += '$'; + return new RegExp(sanitize(str), flags.replace(/[\$\^]/g, '')); + } +} diff --git a/src/components/autocomplete/js/highlightDirective.js b/src/components/autocomplete/js/highlightDirective.js index f864df3eb11..d0ec39dc471 100644 --- a/src/components/autocomplete/js/highlightDirective.js +++ b/src/components/autocomplete/js/highlightDirective.js @@ -1,43 +1,40 @@ -(function () { - 'use strict'; - angular - .module('material.components.autocomplete') - .directive('mdHighlightText', MdHighlight); +angular + .module('material.components.autocomplete') + .directive('mdHighlightText', MdHighlight); - /** - * @ngdoc directive - * @name mdHighlightText - * @module material.components.autocomplete - * - * @description - * The `md-highlight-text` directive allows you to specify text that should be highlighted within - * an element. Highlighted text will be wrapped in `` which can - * be styled through CSS. Please note that child elements may not be used with this directive. - * - * @param {string} md-highlight-text A model to be searched for - * @param {string=} md-highlight-flags A list of flags (loosely based on JavaScript RexExp flags). - * #### **Supported flags**: - * - `g`: Find all matches within the provided text - * - `i`: Ignore case when searching for matches - * - `$`: Only match if the text ends with the search term - * - `^`: Only match if the text begins with the search term - * - * @usage - * - * - *
    - *
  • - * {{result.text}} - *
  • - *
- *
- */ +/** + * @ngdoc directive + * @name mdHighlightText + * @module material.components.autocomplete + * + * @description + * The `md-highlight-text` directive allows you to specify text that should be highlighted within + * an element. Highlighted text will be wrapped in `` which can + * be styled through CSS. Please note that child elements may not be used with this directive. + * + * @param {string} md-highlight-text A model to be searched for + * @param {string=} md-highlight-flags A list of flags (loosely based on JavaScript RexExp flags). + * #### **Supported flags**: + * - `g`: Find all matches within the provided text + * - `i`: Ignore case when searching for matches + * - `$`: Only match if the text ends with the search term + * - `^`: Only match if the text begins with the search term + * + * @usage + * + * + *
    + *
  • + * {{result.text}} + *
  • + *
+ *
+ */ - function MdHighlight () { - return { - terminal: true, - scope: false, - controller: 'MdHighlightCtrl' - }; - } -})(); +function MdHighlight () { + return { + terminal: true, + scope: false, + controller: 'MdHighlightCtrl' + }; +} diff --git a/src/components/autocomplete/js/listItemDirective.js b/src/components/autocomplete/js/listItemDirective.js index 72470895267..2ea5c4aae3a 100644 --- a/src/components/autocomplete/js/listItemDirective.js +++ b/src/components/autocomplete/js/listItemDirective.js @@ -1,26 +1,23 @@ -(function () { - 'use strict'; - angular - .module('material.components.autocomplete') - .directive('mdAutocompleteListItem', MdAutocompleteListItem); +angular + .module('material.components.autocomplete') + .directive('mdAutocompleteListItem', MdAutocompleteListItem); - function MdAutocompleteListItem ($compile, $mdUtil) { - return { - terminal: true, - link: postLink, - scope: false - }; - function postLink (scope, element, attr) { - var ctrl = scope.$parent.$mdAutocompleteCtrl, - newScope = ctrl.parent.$new(false, ctrl.parent), - itemName = ctrl.scope.$eval(attr.mdAutocompleteListItem); - newScope[itemName] = scope.item; - element.html(ctrl.scope.$eval(attr.mdAutocompleteListItemTemplate)); - $compile(element.contents())(newScope); - element.attr({ - role: 'option', - id: 'item_' + $mdUtil.nextUid() - }); - } +function MdAutocompleteListItem ($compile, $mdUtil) { + return { + terminal: true, + link: postLink, + scope: false + }; + function postLink (scope, element, attr) { + var ctrl = scope.$parent.$mdAutocompleteCtrl, + newScope = ctrl.parent.$new(false, ctrl.parent), + itemName = ctrl.scope.$eval(attr.mdAutocompleteListItem); + newScope[itemName] = scope.item; + element.html(ctrl.scope.$eval(attr.mdAutocompleteListItemTemplate)); + $compile(element.contents())(newScope); + element.attr({ + role: 'option', + id: 'item_' + $mdUtil.nextUid() + }); } -})(); +} diff --git a/src/components/backdrop/backdrop.js b/src/components/backdrop/backdrop.js index 5dc25423301..88ad2b28f3b 100644 --- a/src/components/backdrop/backdrop.js +++ b/src/components/backdrop/backdrop.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /* * @ngdoc module * @name material.components.backdrop @@ -28,4 +25,3 @@ angular.module('material.components.backdrop', [ function BackdropDirective($mdTheming) { return $mdTheming; } -})(); diff --git a/src/components/bottomSheet/bottomSheet.js b/src/components/bottomSheet/bottomSheet.js index c90ab66948e..e0cfe0adc8c 100644 --- a/src/components/bottomSheet/bottomSheet.js +++ b/src/components/bottomSheet/bottomSheet.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.bottomSheet @@ -255,5 +252,3 @@ function MdBottomSheetProvider($$interimElementProvider) { } } - -})(); diff --git a/src/components/button/button.js b/src/components/button/button.js index a20d5bc7833..d9eb98663ef 100644 --- a/src/components/button/button.js +++ b/src/components/button/button.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.button @@ -8,10 +5,9 @@ * * Button */ -angular.module('material.components.button', [ - 'material.core' -]) - .directive('mdButton', MdButtonDirective); +angular + .module('material.components.button', [ 'material.core' ]) + .directive('mdButton', MdButtonDirective); /** * @ngdoc directive @@ -114,4 +110,3 @@ function MdButtonDirective($mdInkRipple, $mdTheming, $mdAria, $timeout) { } } -})(); diff --git a/src/components/card/card.js b/src/components/card/card.js index e44f0689223..097c6b60711 100644 --- a/src/components/card/card.js +++ b/src/components/card/card.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.card @@ -55,4 +52,3 @@ function mdCardDirective($mdTheming) { } }; } -})(); diff --git a/src/components/checkbox/checkbox.js b/src/components/checkbox/checkbox.js index 04f30432a63..06488d43087 100644 --- a/src/components/checkbox/checkbox.js +++ b/src/components/checkbox/checkbox.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.checkbox @@ -155,5 +152,3 @@ function MdCheckboxDirective(inputDirective, $mdInkRipple, $mdAria, $mdConstant, }; } } - -})(); diff --git a/src/components/chips/chips.js b/src/components/chips/chips.js index 8f971f4e58c..af8f362cc7f 100644 --- a/src/components/chips/chips.js +++ b/src/components/chips/chips.js @@ -1,14 +1,11 @@ -(function () { - 'use strict'; - /** - * @ngdoc module - * @name material.components.chips - */ - /* - * @see js folder for chips implementation - */ - angular.module('material.components.chips', [ - 'material.core', - 'material.components.autocomplete' - ]); -})(); +/** + * @ngdoc module + * @name material.components.chips + */ +/* + * @see js folder for chips implementation + */ +angular.module('material.components.chips', [ + 'material.core', + 'material.components.autocomplete' +]); diff --git a/src/components/chips/js/chipDirective.js b/src/components/chips/js/chipDirective.js index 91573326c99..40a69fd80c5 100644 --- a/src/components/chips/js/chipDirective.js +++ b/src/components/chips/js/chipDirective.js @@ -1,58 +1,54 @@ -(function () { - 'use strict'; - angular - .module('material.components.chips') - .directive('mdChip', MdChip); +angular + .module('material.components.chips') + .directive('mdChip', MdChip); - /** - * @ngdoc directive - * @name mdChip - * @module material.components.chips - * - * @description - * `` is a component used within `` and is responsible for rendering individual - * chips. - * - * - * @usage - * - * {{$chip}} - * - * - */ +/** + * @ngdoc directive + * @name mdChip + * @module material.components.chips + * + * @description + * `` is a component used within `` and is responsible for rendering individual + * chips. + * + * + * @usage + * + * {{$chip}} + * + * + */ - // This hint text is hidden within a chip but used by screen readers to - // inform the user how they can interact with a chip. - var DELETE_HINT_TEMPLATE = '\ - \ - {{$mdChipsCtrl.deleteHint}}\ - '; +// This hint text is hidden within a chip but used by screen readers to +// inform the user how they can interact with a chip. +var DELETE_HINT_TEMPLATE = '\ + \ + {{$mdChipsCtrl.deleteHint}}\ + '; - /** - * MDChip Directive Definition - * - * @param $mdTheming - * @param $mdInkRipple - * @ngInject - */ - function MdChip($mdTheming) { - return { - restrict: 'E', - require: '^?mdChips', - compile: compile - }; +/** + * MDChip Directive Definition + * + * @param $mdTheming + * @param $mdInkRipple + * @ngInject + */ +function MdChip($mdTheming) { + return { + restrict: 'E', + require: '^?mdChips', + compile: compile + }; - function compile(element, attr) { - element.append(DELETE_HINT_TEMPLATE); - return function postLink(scope, element, attr, ctrl) { - if (ctrl) angular.element(element[0].querySelector('.md-chip-content')) - .on('blur', function () { - ctrl.$scope.$apply(function () { ctrl.selectedChip = -1; }); - }); - element.addClass('md-chip'); - $mdTheming(element); - }; - } + function compile(element, attr) { + element.append(DELETE_HINT_TEMPLATE); + return function postLink(scope, element, attr, ctrl) { + if (ctrl) angular.element(element[0].querySelector('.md-chip-content')) + .on('blur', function () { + ctrl.$scope.$apply(function () { ctrl.selectedChip = -1; }); + }); + element.addClass('md-chip'); + $mdTheming(element); + }; } - -})(); +} diff --git a/src/components/chips/js/chipRemoveDirective.js b/src/components/chips/js/chipRemoveDirective.js index 62e0167c83f..f5dcb2199c9 100644 --- a/src/components/chips/js/chipRemoveDirective.js +++ b/src/components/chips/js/chipRemoveDirective.js @@ -1,53 +1,50 @@ -(function () { - 'use strict'; - angular - .module('material.components.chips') - .directive('mdChipRemove', MdChipRemove); +angular + .module('material.components.chips') + .directive('mdChipRemove', MdChipRemove); - /** - * @ngdoc directive - * @name mdChipRemove - * @module material.components.chips - * - * @description - * `` - * Designates a button as a trigger to remove the chip. - * - * @usage - * - * {{$chip}} - * - */ +/** + * @ngdoc directive + * @name mdChipRemove + * @module material.components.chips + * + * @description + * `` + * Designates a button as a trigger to remove the chip. + * + * @usage + * + * {{$chip}} + * + */ - /** - * - * @param $compile - * @param $timeout - * @returns {{restrict: string, require: string[], link: Function, scope: boolean}} - * @constructor - */ - function MdChipRemove ($timeout) { - return { - restrict: 'A', - require: '^mdChips', - scope: false, - link: postLink - }; +/** + * + * @param $compile + * @param $timeout + * @returns {{restrict: string, require: string[], link: Function, scope: boolean}} + * @constructor + */ +function MdChipRemove ($timeout) { + return { + restrict: 'A', + require: '^mdChips', + scope: false, + link: postLink + }; - function postLink(scope, element, attr, ctrl) { - element.on('click', function(event) { - scope.$apply(function() { - ctrl.removeChip(scope.$$replacedScope.$index); - }); + function postLink(scope, element, attr, ctrl) { + element.on('click', function(event) { + scope.$apply(function() { + ctrl.removeChip(scope.$$replacedScope.$index); }); + }); - // Child elements aren't available until after a $timeout tick as they are hidden by an - // `ng-if`. see http://goo.gl/zIWfuw - $timeout(function() { - element.attr({ tabindex: -1, ariaHidden: true }); - element.find('button').attr('tabindex', '-1'); - }); - } + // Child elements aren't available until after a $timeout tick as they are hidden by an + // `ng-if`. see http://goo.gl/zIWfuw + $timeout(function() { + element.attr({ tabindex: -1, ariaHidden: true }); + element.find('button').attr('tabindex', '-1'); + }); } -})(); +} diff --git a/src/components/chips/js/chipTranscludeDirective.js b/src/components/chips/js/chipTranscludeDirective.js index 830f031b3f5..f2cce54b0b8 100644 --- a/src/components/chips/js/chipTranscludeDirective.js +++ b/src/components/chips/js/chipTranscludeDirective.js @@ -1,24 +1,21 @@ -(function () { - 'use strict'; - angular - .module('material.components.chips') - .directive('mdChipTransclude', MdChipTransclude); +angular + .module('material.components.chips') + .directive('mdChipTransclude', MdChipTransclude); - function MdChipTransclude ($compile, $mdUtil) { - return { - restrict: 'EA', - terminal: true, - link: link, - scope: false - }; - function link (scope, element, attr) { - var ctrl = scope.$parent.$mdChipsCtrl, - newScope = ctrl.parent.$new(false, ctrl.parent); - newScope.$$replacedScope = scope; - newScope.$chip = scope.$chip; - newScope.$mdChipsCtrl = ctrl; - element.html(ctrl.$scope.$eval(attr.mdChipTransclude)); - $compile(element.contents())(newScope); - } +function MdChipTransclude ($compile, $mdUtil) { + return { + restrict: 'EA', + terminal: true, + link: link, + scope: false + }; + function link (scope, element, attr) { + var ctrl = scope.$parent.$mdChipsCtrl, + newScope = ctrl.parent.$new(false, ctrl.parent); + newScope.$$replacedScope = scope; + newScope.$chip = scope.$chip; + newScope.$mdChipsCtrl = ctrl; + element.html(ctrl.$scope.$eval(attr.mdChipTransclude)); + $compile(element.contents())(newScope); } -})(); +} diff --git a/src/components/chips/js/chipsController.js b/src/components/chips/js/chipsController.js index 66bb20e163e..f2f3a823eb1 100644 --- a/src/components/chips/js/chipsController.js +++ b/src/components/chips/js/chipsController.js @@ -1,360 +1,357 @@ -(function () { - 'use strict'; - angular - .module('material.components.chips') - .controller('MdChipsCtrl', MdChipsCtrl); +angular + .module('material.components.chips') + .controller('MdChipsCtrl', MdChipsCtrl); - /** - * Controller for the MdChips component. Responsible for adding to and - * removing from the list of chips, marking chips as selected, and binding to - * the models of various input components. - * - * @param $scope - * @param $mdConstant - * @param $log - * @param $element - * @constructor - */ - function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) { - /** @type {$timeout} **/ - this.$timeout = $timeout; - - /** @type {Object} */ - this.$mdConstant = $mdConstant; - - /** @type {angular.$scope} */ - this.$scope = $scope; - - /** @type {angular.$scope} */ - this.parent = $scope.$parent; - - /** @type {$log} */ - this.$log = $log; +/** + * Controller for the MdChips component. Responsible for adding to and + * removing from the list of chips, marking chips as selected, and binding to + * the models of various input components. + * + * @param $scope + * @param $mdConstant + * @param $log + * @param $element + * @constructor + */ +function MdChipsCtrl ($scope, $mdConstant, $log, $element, $timeout) { + /** @type {$timeout} **/ + this.$timeout = $timeout; - /** @type {$element} */ - this.$element = $element; + /** @type {Object} */ + this.$mdConstant = $mdConstant; - /** @type {angular.NgModelController} */ - this.ngModelCtrl = null; + /** @type {angular.$scope} */ + this.$scope = $scope; - /** @type {angular.NgModelController} */ - this.userInputNgModelCtrl = null; + /** @type {angular.$scope} */ + this.parent = $scope.$parent; - /** @type {Element} */ - this.userInputElement = null; + /** @type {$log} */ + this.$log = $log; - /** @type {Array.} */ - this.items = []; + /** @type {$element} */ + this.$element = $element; - /** @type {number} */ - this.selectedChip = -1; + /** @type {angular.NgModelController} */ + this.ngModelCtrl = null; + /** @type {angular.NgModelController} */ + this.userInputNgModelCtrl = null; - /** - * Hidden hint text for how to delete a chip. Used to give context to screen readers. - * @type {string} - */ - this.deleteHint = 'Press delete to remove this chip.'; - - /** - * Hidden label for the delete button. Used to give context to screen readers. - * @type {string} - */ - this.deleteButtonLabel = 'Remove'; - - /** - * Model used by the input element. - * @type {string} - */ - this.chipBuffer = ''; - - /** - * Whether to use the mdOnAppend expression to transform the chip buffer - * before appending it to the list. - * @type {boolean} - */ - this.useMdOnAppend = false; - } - - /** - * Handles the keydown event on the input element: appends the - * buffer to the chip list, while backspace removes the last chip in the list - * if the current buffer is empty. - * @param event - */ - MdChipsCtrl.prototype.inputKeydown = function(event) { - var chipBuffer = this.getChipBuffer(); - switch (event.keyCode) { - case this.$mdConstant.KEY_CODE.ENTER: - if (this.$scope.requireMatch || !chipBuffer) break; - event.preventDefault(); - this.appendChip(chipBuffer); - this.resetChipBuffer(); - break; - case this.$mdConstant.KEY_CODE.BACKSPACE: - if (chipBuffer) break; - event.stopPropagation(); - if (this.items.length) this.selectAndFocusChipSafe(this.items.length - 1); - break; - } - }; - - /** - * Handles the keydown event on the chip elements: backspace removes the selected chip, arrow - * keys switch which chips is active - * @param event - */ - MdChipsCtrl.prototype.chipKeydown = function (event) { - if (this.getChipBuffer()) return; - switch (event.keyCode) { - case this.$mdConstant.KEY_CODE.BACKSPACE: - case this.$mdConstant.KEY_CODE.DELETE: - if (this.selectedChip < 0) return; - event.preventDefault(); - this.removeAndSelectAdjacentChip(this.selectedChip); - break; - case this.$mdConstant.KEY_CODE.LEFT_ARROW: - event.preventDefault(); - if (this.selectedChip < 0) this.selectedChip = this.items.length; - if (this.items.length) this.selectAndFocusChipSafe(this.selectedChip - 1); - break; - case this.$mdConstant.KEY_CODE.RIGHT_ARROW: - event.preventDefault(); - this.selectAndFocusChipSafe(this.selectedChip + 1); - break; - case this.$mdConstant.KEY_CODE.ESCAPE: - case this.$mdConstant.KEY_CODE.TAB: - if (this.selectedChip < 0) return; - event.preventDefault(); - this.onFocus(); - break; - } - }; - - /** - * Get the input's placeholder - uses `placeholder` when list is empty and `secondary-placeholder` - * when the list is non-empty. If `secondary-placeholder` is not provided, `placeholder` is used - * always. - */ - MdChipsCtrl.prototype.getPlaceholder = function() { - // Allow `secondary-placeholder` to be blank. - var useSecondary = (this.items.length && - (this.secondaryPlaceholder == '' || this.secondaryPlaceholder)); - return useSecondary ? this.placeholder : this.secondaryPlaceholder; - }; + /** @type {Element} */ + this.userInputElement = null; - /** - * Removes chip at {@code index} and selects the adjacent chip. - * @param index - */ - MdChipsCtrl.prototype.removeAndSelectAdjacentChip = function(index) { - var selIndex = this.getAdjacentChipIndex(index); - this.removeChip(index); - this.$timeout(function () { this.selectAndFocusChipSafe(selIndex); }.bind(this)); - }; + /** @type {Array.} */ + this.items = []; - /** - * Sets the selected chip index to -1. - */ - MdChipsCtrl.prototype.resetSelectedChip = function() { - this.selectedChip = -1; - }; + /** @type {number} */ + this.selectedChip = -1; - /** - * Gets the index of an adjacent chip to select after deletion. Adjacency is - * determined as the next chip in the list, unless the target chip is the - * last in the list, then it is the chip immediately preceding the target. If - * there is only one item in the list, -1 is returned (select none). - * The number returned is the index to select AFTER the target has been - * removed. - * If the current chip is not selected, then -1 is returned to select none. - */ - MdChipsCtrl.prototype.getAdjacentChipIndex = function(index) { - var len = this.items.length - 1; - return (len == 0) ? -1 : - (index == len) ? index -1 : index; - }; /** - * Append the contents of the buffer to the chip list. This method will first - * call out to the md-on-append method, if provided - * @param newChip + * Hidden hint text for how to delete a chip. Used to give context to screen readers. + * @type {string} */ - MdChipsCtrl.prototype.appendChip = function(newChip) { - if (this.items.indexOf(newChip) + 1) return; - if (this.useMdOnAppend && this.mdOnAppend) { - newChip = this.mdOnAppend({'$chip': newChip}); - } - this.items.push(newChip); - }; + this.deleteHint = 'Press delete to remove this chip.'; /** - * Sets whether to use the md-on-append expression. This expression is - * bound to scope and controller in {@code MdChipsDirective} as - * {@code mdOnAppend}. Due to the nature of directive scope bindings, the - * controller cannot know on its own/from the scope whether an expression was - * actually provided. + * Hidden label for the delete button. Used to give context to screen readers. + * @type {string} */ - MdChipsCtrl.prototype.useMdOnAppendExpression = function() { - this.useMdOnAppend = true; - }; + this.deleteButtonLabel = 'Remove'; /** - * Gets the input buffer. The input buffer can be the model bound to the - * default input item {@code this.chipBuffer}, the {@code selectedItem} - * model of an {@code md-autocomplete}, or, through some magic, the model - * bound to any inpput or text area element found within a - * {@code md-input-container} element. - * @return {Object|string} + * Model used by the input element. + * @type {string} */ - MdChipsCtrl.prototype.getChipBuffer = function() { - return !this.userInputElement ? this.chipBuffer : - this.userInputNgModelCtrl ? this.userInputNgModelCtrl.$viewValue : - this.userInputElement[0].value; - }; + this.chipBuffer = ''; /** - * Resets the input buffer for either the internal input or user provided input element. + * Whether to use the mdOnAppend expression to transform the chip buffer + * before appending it to the list. + * @type {boolean} */ - MdChipsCtrl.prototype.resetChipBuffer = function() { - if (this.userInputElement) { - if (this.userInputNgModelCtrl) { - this.userInputNgModelCtrl.$setViewValue(''); - this.userInputNgModelCtrl.$render(); - } else { - this.userInputElement[0].value = ''; - } + this.useMdOnAppend = false; +} + +/** + * Handles the keydown event on the input element: appends the + * buffer to the chip list, while backspace removes the last chip in the list + * if the current buffer is empty. + * @param event + */ +MdChipsCtrl.prototype.inputKeydown = function(event) { + var chipBuffer = this.getChipBuffer(); + switch (event.keyCode) { + case this.$mdConstant.KEY_CODE.ENTER: + if (this.$scope.requireMatch || !chipBuffer) break; + event.preventDefault(); + this.appendChip(chipBuffer); + this.resetChipBuffer(); + break; + case this.$mdConstant.KEY_CODE.BACKSPACE: + if (chipBuffer) break; + event.stopPropagation(); + if (this.items.length) this.selectAndFocusChipSafe(this.items.length - 1); + break; + } +}; + +/** + * Handles the keydown event on the chip elements: backspace removes the selected chip, arrow + * keys switch which chips is active + * @param event + */ +MdChipsCtrl.prototype.chipKeydown = function (event) { + if (this.getChipBuffer()) return; + switch (event.keyCode) { + case this.$mdConstant.KEY_CODE.BACKSPACE: + case this.$mdConstant.KEY_CODE.DELETE: + if (this.selectedChip < 0) return; + event.preventDefault(); + this.removeAndSelectAdjacentChip(this.selectedChip); + break; + case this.$mdConstant.KEY_CODE.LEFT_ARROW: + event.preventDefault(); + if (this.selectedChip < 0) this.selectedChip = this.items.length; + if (this.items.length) this.selectAndFocusChipSafe(this.selectedChip - 1); + break; + case this.$mdConstant.KEY_CODE.RIGHT_ARROW: + event.preventDefault(); + this.selectAndFocusChipSafe(this.selectedChip + 1); + break; + case this.$mdConstant.KEY_CODE.ESCAPE: + case this.$mdConstant.KEY_CODE.TAB: + if (this.selectedChip < 0) return; + event.preventDefault(); + this.onFocus(); + break; + } +}; + +/** + * Get the input's placeholder - uses `placeholder` when list is empty and `secondary-placeholder` + * when the list is non-empty. If `secondary-placeholder` is not provided, `placeholder` is used + * always. + */ +MdChipsCtrl.prototype.getPlaceholder = function() { + // Allow `secondary-placeholder` to be blank. + var useSecondary = (this.items.length && + (this.secondaryPlaceholder == '' || this.secondaryPlaceholder)); + return useSecondary ? this.placeholder : this.secondaryPlaceholder; +}; + +/** + * Removes chip at {@code index} and selects the adjacent chip. + * @param index + */ +MdChipsCtrl.prototype.removeAndSelectAdjacentChip = function(index) { + var selIndex = this.getAdjacentChipIndex(index); + this.removeChip(index); + this.$timeout(function () { this.selectAndFocusChipSafe(selIndex); }.bind(this)); +}; + +/** + * Sets the selected chip index to -1. + */ +MdChipsCtrl.prototype.resetSelectedChip = function() { + this.selectedChip = -1; +}; + +/** + * Gets the index of an adjacent chip to select after deletion. Adjacency is + * determined as the next chip in the list, unless the target chip is the + * last in the list, then it is the chip immediately preceding the target. If + * there is only one item in the list, -1 is returned (select none). + * The number returned is the index to select AFTER the target has been + * removed. + * If the current chip is not selected, then -1 is returned to select none. + */ +MdChipsCtrl.prototype.getAdjacentChipIndex = function(index) { + var len = this.items.length - 1; + return (len == 0) ? -1 : + (index == len) ? index -1 : index; +}; + +/** + * Append the contents of the buffer to the chip list. This method will first + * call out to the md-on-append method, if provided + * @param newChip + */ +MdChipsCtrl.prototype.appendChip = function(newChip) { + if (this.items.indexOf(newChip) + 1) return; + if (this.useMdOnAppend && this.mdOnAppend) { + newChip = this.mdOnAppend({'$chip': newChip}); + } + this.items.push(newChip); +}; + +/** + * Sets whether to use the md-on-append expression. This expression is + * bound to scope and controller in {@code MdChipsDirective} as + * {@code mdOnAppend}. Due to the nature of directive scope bindings, the + * controller cannot know on its own/from the scope whether an expression was + * actually provided. + */ +MdChipsCtrl.prototype.useMdOnAppendExpression = function() { + this.useMdOnAppend = true; +}; + +/** + * Gets the input buffer. The input buffer can be the model bound to the + * default input item {@code this.chipBuffer}, the {@code selectedItem} + * model of an {@code md-autocomplete}, or, through some magic, the model + * bound to any inpput or text area element found within a + * {@code md-input-container} element. + * @return {Object|string} + */ +MdChipsCtrl.prototype.getChipBuffer = function() { + return !this.userInputElement ? this.chipBuffer : + this.userInputNgModelCtrl ? this.userInputNgModelCtrl.$viewValue : + this.userInputElement[0].value; +}; + +/** + * Resets the input buffer for either the internal input or user provided input element. + */ +MdChipsCtrl.prototype.resetChipBuffer = function() { + if (this.userInputElement) { + if (this.userInputNgModelCtrl) { + this.userInputNgModelCtrl.$setViewValue(''); + this.userInputNgModelCtrl.$render(); } else { - this.chipBuffer = ''; + this.userInputElement[0].value = ''; } - }; - - /** - * Removes the chip at the given index. - * @param index - */ - MdChipsCtrl.prototype.removeChip = function(index) { - this.items.splice(index, 1); - }; - - MdChipsCtrl.prototype.removeChipAndFocusInput = function (index) { - this.removeChip(index); + } else { + this.chipBuffer = ''; + } +}; + +/** + * Removes the chip at the given index. + * @param index + */ +MdChipsCtrl.prototype.removeChip = function(index) { + this.items.splice(index, 1); +}; + +MdChipsCtrl.prototype.removeChipAndFocusInput = function (index) { + this.removeChip(index); + this.onFocus(); +}; +/** + * Selects the chip at `index`, + * @param index + */ +MdChipsCtrl.prototype.selectAndFocusChipSafe = function(index) { + if (!this.items.length) { + this.selectChip(-1); this.onFocus(); - }; - /** - * Selects the chip at `index`, - * @param index - */ - MdChipsCtrl.prototype.selectAndFocusChipSafe = function(index) { - if (!this.items.length) { - this.selectChip(-1); - this.onFocus(); - return; - } - if (index === this.items.length) return this.onFocus(); - index = Math.max(index, 0); - index = Math.min(index, this.items.length - 1); - this.selectChip(index); + return; + } + if (index === this.items.length) return this.onFocus(); + index = Math.max(index, 0); + index = Math.min(index, this.items.length - 1); + this.selectChip(index); + this.focusChip(index); +}; + +/** + * Marks the chip at the given index as selected. + * @param index + */ +MdChipsCtrl.prototype.selectChip = function(index) { + if (index >= -1 && index <= this.items.length) { + this.selectedChip = index; + } else { + this.$log.warn('Selected Chip index out of bounds; ignoring.'); + } +}; + +/** + * Selects the chip at `index` and gives it focus. + * @param index + */ +MdChipsCtrl.prototype.selectAndFocusChip = function(index) { + this.selectChip(index); + if (index != -1) { this.focusChip(index); + } +}; + +/** + * Call `focus()` on the chip at `index` + */ +MdChipsCtrl.prototype.focusChip = function(index) { + this.$element[0].querySelector('md-chip[index="' + index + '"] .md-chip-content').focus(); +}; + +/** + * Configures the required interactions with the ngModel Controller. + * Specifically, set {@code this.items} to the {@code NgModelCtrl#$viewVale}. + * @param ngModelCtrl + */ +MdChipsCtrl.prototype.configureNgModel = function(ngModelCtrl) { + this.ngModelCtrl = ngModelCtrl; + + var self = this; + ngModelCtrl.$render = function() { + // model is updated. do something. + self.items = self.ngModelCtrl.$viewValue; }; +}; + +MdChipsCtrl.prototype.onFocus = function () { + var input = this.$element[0].querySelector('input'); + input && input.focus(); + this.resetSelectedChip(); +}; + +MdChipsCtrl.prototype.onInputFocus = function () { + this.inputHasFocus = true; + this.resetSelectedChip(); +}; + +MdChipsCtrl.prototype.onInputBlur = function () { + this.inputHasFocus = false; +}; + +/** + * Configure event bindings on a user-provided input element. + * @param inputElement + */ +MdChipsCtrl.prototype.configureUserInput = function(inputElement) { + this.userInputElement = inputElement; + + // Find the NgModelCtrl for the input element + var ngModelCtrl = inputElement.controller('ngModel'); + // `.controller` will look in the parent as well. + if (ngModelCtrl != this.ngModelCtrl) { + this.userInputNgModelCtrl = ngModelCtrl; + } - /** - * Marks the chip at the given index as selected. - * @param index - */ - MdChipsCtrl.prototype.selectChip = function(index) { - if (index >= -1 && index <= this.items.length) { - this.selectedChip = index; - } else { - this.$log.warn('Selected Chip index out of bounds; ignoring.'); - } - }; - - /** - * Selects the chip at `index` and gives it focus. - * @param index - */ - MdChipsCtrl.prototype.selectAndFocusChip = function(index) { - this.selectChip(index); - if (index != -1) { - this.focusChip(index); - } - }; - - /** - * Call `focus()` on the chip at `index` - */ - MdChipsCtrl.prototype.focusChip = function(index) { - this.$element[0].querySelector('md-chip[index="' + index + '"] .md-chip-content').focus(); - }; - - /** - * Configures the required interactions with the ngModel Controller. - * Specifically, set {@code this.items} to the {@code NgModelCtrl#$viewVale}. - * @param ngModelCtrl - */ - MdChipsCtrl.prototype.configureNgModel = function(ngModelCtrl) { - this.ngModelCtrl = ngModelCtrl; - - var self = this; - ngModelCtrl.$render = function() { - // model is updated. do something. - self.items = self.ngModelCtrl.$viewValue; - }; - }; - - MdChipsCtrl.prototype.onFocus = function () { - var input = this.$element[0].querySelector('input'); - input && input.focus(); - this.resetSelectedChip(); - }; - - MdChipsCtrl.prototype.onInputFocus = function () { - this.inputHasFocus = true; - this.resetSelectedChip(); - }; - - MdChipsCtrl.prototype.onInputBlur = function () { - this.inputHasFocus = false; - }; - - /** - * Configure event bindings on a user-provided input element. - * @param inputElement - */ - MdChipsCtrl.prototype.configureUserInput = function(inputElement) { - this.userInputElement = inputElement; - - // Find the NgModelCtrl for the input element - var ngModelCtrl = inputElement.controller('ngModel'); - // `.controller` will look in the parent as well. - if (ngModelCtrl != this.ngModelCtrl) { - this.userInputNgModelCtrl = ngModelCtrl; + // Bind to keydown and focus events of input + var scope = this.$scope; + var ctrl = this; + inputElement + .attr({ tabindex: 0 }) + .on('keydown', function(event) { scope.$apply(function() { ctrl.inputKeydown(event); }); }) + .on('focus', function () { this.$scope.$apply(this.onInputFocus.bind(this)); }.bind(this)) + .on('blur', function () { this.$scope.$apply(this.onInputBlur.bind(this)); }.bind(this)); +}; + +MdChipsCtrl.prototype.configureAutocomplete = function(ctrl) { + ctrl.registerSelectedItemWatcher(function (item) { + if (item) { + this.appendChip(item); + this.resetChipBuffer(); } - - // Bind to keydown and focus events of input - var scope = this.$scope; - var ctrl = this; - inputElement - .attr({ tabindex: 0 }) - .on('keydown', function(event) { scope.$apply(function() { ctrl.inputKeydown(event); }); }) - .on('focus', function () { this.$scope.$apply(this.onInputFocus.bind(this)); }.bind(this)) - .on('blur', function () { this.$scope.$apply(this.onInputBlur.bind(this)); }.bind(this)); - }; - - MdChipsCtrl.prototype.configureAutocomplete = function(ctrl) { - ctrl.registerSelectedItemWatcher(function (item) { - if (item) { - this.appendChip(item); - this.resetChipBuffer(); - } - }.bind(this)); - this.$element.find('input') - .on('focus', function () { this.$scope.$apply(this.onInputFocus.bind(this)); }.bind(this)) - .on('blur', function () { this.$scope.$apply(this.onInputBlur.bind(this)); }.bind(this)); - }; - - MdChipsCtrl.prototype.hasFocus = function () { - return this.inputHasFocus || this.selectedChip >= 0; - }; -})(); + }.bind(this)); + this.$element.find('input') + .on('focus', function () { this.$scope.$apply(this.onInputFocus.bind(this)); }.bind(this)) + .on('blur', function () { this.$scope.$apply(this.onInputBlur.bind(this)); }.bind(this)); +}; + +MdChipsCtrl.prototype.hasFocus = function () { + return this.inputHasFocus || this.selectedChip >= 0; +}; diff --git a/src/components/chips/js/chipsDirective.js b/src/components/chips/js/chipsDirective.js index c8f802a7b00..9291b57193c 100644 --- a/src/components/chips/js/chipsDirective.js +++ b/src/components/chips/js/chipsDirective.js @@ -1,271 +1,268 @@ -(function () { - 'use strict'; - angular - .module('material.components.chips') - .directive('mdChips', MdChips); +angular + .module('material.components.chips') + .directive('mdChips', MdChips); + +/** + * @ngdoc directive + * @name mdChips + * @module material.components.chips + * + * @description + * `` is an input component for building lists of strings or objects. The list items are + * displayed as 'chips'. This component can make use of an `` element or an + * `` element. + * + * Custom `` template + * A custom template may be provided to render the content of each chip. This is achieved by + * specifying an `` element as a child of ``. Note: Any attributes on + * `` will be dropped as only the innerHTML is used for the chip template. The + * variables `$chip` and `$index` are available in the scope of ``, representing + * the chip object and its index in the list of chips, respectively. + * To override the chip delete control, include an element (ideally a button) with the attribute + * `md-chip-remove`. A click listener to remove the chip will be added automatically. The element + * is also placed as a sibling to the chip content (on which there are also click listeners) to + * avoid a nested ng-click situation. + * + *

Pending Features

+ *
    + * + *
      Style + *
    • Colours for hover, press states (ripple?).
    • + *
    + * + *
      List Manipulation + *
    • delete item via DEL or backspace keys when selected
    • + *
    + * + *
      Validation + *
    • de-dupe values (or support duplicates, but fix the ng-repeat duplicate key issue)
    • + *
    • allow a validation callback
    • + *
    • hilighting style for invalid chips
    • + *
    + * + *
      Item mutation + *
    • Support ` + * ` template, show/hide the edit element on tap/click? double tap/double + * click? + *
    • + *
    + * + *
      Truncation and Disambiguation (?) + *
    • Truncate chip text where possible, but do not truncate entries such that two are + * indistinguishable.
    • + *
    + * + *
      Drag and Drop + *
    • Drag and drop chips between related `` elements. + *
    • + *
    + *
+ * + * + * Warning: This component is a WORK IN PROGRESS. If you use it now, + * it will probably break on you in the future. + * + * + * @param {string=|object=} ng-model A model to bind the list of items to + * @param {string=} placeholder Placeholder text that will be forwarded to the input. + * @param {string=} secondary-placeholder Placeholder text that will be forwarded to the input, + * displayed when there is at least on item in the list + * @param {boolean=} readonly Disables list manipulation (deleting or adding list items), hiding + * the input and delete buttons + * @param {expression} md-on-append An expression expected to convert the input string into an + * object when adding a chip. + * @param {string=} delete-hint A string read by screen readers instructing users that pressing + * the delete key will remove the chip. + * @param {string=} delete-button-label A label for the delete button. Also hidden and read by + * screen readers. + * + * @usage + * + * + * + * + * + */ + + +var MD_CHIPS_TEMPLATE = '\ + \ + \ + \ +
\ +
\ +
\ + \ + '; + +var CHIP_INPUT_TEMPLATE = '\ + '; + +var CHIP_DEFAULT_TEMPLATE = '\ + {{$chip}}'; + +var CHIP_REMOVE_TEMPLATE = '\ +
\ + \ +
\ + {{$chip[$mdContactChipsCtrl.contactName]}}\ +
\ +
\ + {{$chip[$mdContactChipsCtrl.contactName]}}\ +
\ +
\ +
'; - /** - * MDContactChips Directive Definition - * - * @param $mdTheming - * @returns {*} - * @ngInject - */ - function MdContactChips ($mdTheming) { - return { - template: function(element, attrs) { - return MD_CONTACT_CHIPS_TEMPLATE; - }, - restrict: 'E', - controller: 'MdContactChipsCtrl', - controllerAs: '$mdContactChipsCtrl', - bindToController: true, - compile: compile, - scope: { - contactQuery: '&mdContacts', - placeholder: '@', - secondaryPlaceholder: '@', - contactName: '@mdContactName', - contactImage: '@mdContactImage', - contactEmail: '@mdContactEmail', - filterSelected: '=', - contacts: '=ngModel', - requireMatch: '=?mdRequireMatch' - } - }; +/** + * MDContactChips Directive Definition + * + * @param $mdTheming + * @returns {*} + * @ngInject + */ +function MdContactChips ($mdTheming) { + return { + template: function(element, attrs) { + return MD_CONTACT_CHIPS_TEMPLATE; + }, + restrict: 'E', + controller: 'MdContactChipsCtrl', + controllerAs: '$mdContactChipsCtrl', + bindToController: true, + compile: compile, + scope: { + contactQuery: '&mdContacts', + placeholder: '@', + secondaryPlaceholder: '@', + contactName: '@mdContactName', + contactImage: '@mdContactImage', + contactEmail: '@mdContactEmail', + filterSelected: '=', + contacts: '=ngModel', + requireMatch: '=?mdRequireMatch' + } + }; - function compile(element, attr) { - return function postLink(scope, element, attrs, controllers) { + function compile(element, attr) { + return function postLink(scope, element, attrs, controllers) { - //-- give optional properties with no value a boolean true by default - angular.forEach(scope.$$isolateBindings, function (binding, key) { - if (binding.optional && angular.isUndefined(scope[key])) { - scope[key] = attr.hasOwnProperty(attr.$normalize(binding.attrName)); - } - }); + //-- give optional properties with no value a boolean true by default + angular.forEach(scope.$$isolateBindings, function (binding, key) { + if (binding.optional && angular.isUndefined(scope[key])) { + scope[key] = attr.hasOwnProperty(attr.$normalize(binding.attrName)); + } + }); - $mdTheming(element); - element.attr('tabindex', '-1'); - }; - } + $mdTheming(element); + element.attr('tabindex', '-1'); + }; } -})(); +} diff --git a/src/components/content/content.js b/src/components/content/content.js index cf1755772b6..9d21e51faba 100644 --- a/src/components/content/content.js +++ b/src/components/content/content.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.content @@ -74,4 +71,3 @@ function iosScrollFix(node) { } }); } -})(); diff --git a/src/components/dialog/dialog.js b/src/components/dialog/dialog.js index ba53356a186..a95ad3ffe15 100644 --- a/src/components/dialog/dialog.js +++ b/src/components/dialog/dialog.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.dialog @@ -655,5 +652,3 @@ function MdDialogProvider($$interimElementProvider) { } } - -})(); diff --git a/src/components/divider/divider.js b/src/components/divider/divider.js index 638f17c9312..ed1e4d4bde9 100644 --- a/src/components/divider/divider.js +++ b/src/components/divider/divider.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.divider @@ -35,4 +32,3 @@ function MdDividerDirective($mdTheming) { link: $mdTheming }; } -})(); diff --git a/src/components/gridList/gridList.js b/src/components/gridList/gridList.js index 6bf460f3d71..94c508b305f 100644 --- a/src/components/gridList/gridList.js +++ b/src/components/gridList/gridList.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.gridList @@ -763,5 +760,3 @@ function GridTileCaptionDirective() { transclude: true }; } - -})(); diff --git a/src/components/icon/iconDirective.js b/src/components/icon/iconDirective.js index 37f125d61d6..3d1c8cffed4 100644 --- a/src/components/icon/iconDirective.js +++ b/src/components/icon/iconDirective.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.icon @@ -101,5 +98,3 @@ function mdIconDirective($mdIcon, $mdTheming, $mdAria ) { } } } - -})(); diff --git a/src/components/icon/iconService.js b/src/components/icon/iconService.js index 328ed279c9c..aece9eff938 100644 --- a/src/components/icon/iconService.js +++ b/src/components/icon/iconService.js @@ -1,6 +1,3 @@ -(function() { - 'use strict'; - angular .module('material.components.icon' ) .provider('$mdIcon', MdIconProvider); @@ -463,5 +460,3 @@ } } - -})(); diff --git a/src/components/list/list.js b/src/components/list/list.js index 8cf0e32aff6..d9802f5efc5 100644 --- a/src/components/list/list.js +++ b/src/components/list/list.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.list @@ -251,4 +248,3 @@ function MdListController($scope, $element, $mdInkRipple) { $mdInkRipple.attachListControlBehavior(scope, element, options); } } -})(); diff --git a/src/components/progressCircular/progressCircular.js b/src/components/progressCircular/progressCircular.js index 19e348bb418..67b46527211 100644 --- a/src/components/progressCircular/progressCircular.js +++ b/src/components/progressCircular/progressCircular.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.progressCircular @@ -99,4 +96,3 @@ function MdProgressCircularDirective($mdConstant, $mdTheming) { return Math.max(0, Math.min(value || 0, 100)); } } -})(); diff --git a/src/components/progressLinear/progressLinear.js b/src/components/progressLinear/progressLinear.js index a9e989f7292..e21696dfff2 100644 --- a/src/components/progressLinear/progressLinear.js +++ b/src/components/progressLinear/progressLinear.js @@ -1,7 +1,3 @@ -(function() { -'use strict'; - - /** * @ngdoc module * @name material.components.progressLinear @@ -117,5 +113,3 @@ var transforms = (function() { return 'translateX(' + translateX.toString() + '%) scale(' + scale.toString() + ', 1)'; } })(); - -})(); diff --git a/src/components/radioButton/radioButton.js b/src/components/radioButton/radioButton.js index 00a7612114a..7f67c713dd3 100644 --- a/src/components/radioButton/radioButton.js +++ b/src/components/radioButton/radioButton.js @@ -1,7 +1,3 @@ -(function() { -'use strict'; - - /** * @ngdoc module * @name material.components.radioButton @@ -302,5 +298,3 @@ function mdRadioButtonDirective($mdAria, $mdUtil, $mdTheming) { } } } - -})(); diff --git a/src/components/select/select.js b/src/components/select/select.js index 6b49aaa6378..7f802e08884 100755 --- a/src/components/select/select.js +++ b/src/components/select/select.js @@ -1,5 +1,3 @@ -(function() { -'use strict'; /** * @ngdoc module * @name material.components.select @@ -1036,5 +1034,3 @@ function nodesToArray(nodes) { } return results; } -})(); - diff --git a/src/components/sidenav/sidenav.js b/src/components/sidenav/sidenav.js index 12f4b77f66a..1afe039bfbd 100644 --- a/src/components/sidenav/sidenav.js +++ b/src/components/sidenav/sidenav.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.sidenav @@ -411,7 +408,3 @@ function SidenavController($scope, $element, $attrs, $mdComponentRegistry, $q) { self.destroy = $mdComponentRegistry.register(self, $attrs.mdComponentId); } - - - -})(); diff --git a/src/components/slider/slider.js b/src/components/slider/slider.js index f11a9bf5583..f4a51d54f5e 100644 --- a/src/components/slider/slider.js +++ b/src/components/slider/slider.js @@ -1,6 +1,3 @@ -(function() { - 'use strict'; - /** * @ngdoc module * @name material.components.slider @@ -391,5 +388,3 @@ function SliderDirective($$rAF, $window, $mdAria, $mdUtil, $mdConstant, $mdThemi } } } - -})(); diff --git a/src/components/sticky/sticky.js b/src/components/sticky/sticky.js index 1358ab7a2b4..a56936daf83 100644 --- a/src/components/sticky/sticky.js +++ b/src/components/sticky/sticky.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /* * @ngdoc module * @name material.components.sticky @@ -301,4 +298,3 @@ function MdSticky($document, $mdConstant, $compile, $$rAF, $mdUtil) { } } -})(); diff --git a/src/components/subheader/subheader.js b/src/components/subheader/subheader.js index a7c899efceb..f5a85eb20fb 100644 --- a/src/components/subheader/subheader.js +++ b/src/components/subheader/subheader.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.subheader @@ -82,4 +79,3 @@ function MdSubheaderDirective($mdSticky, $compile, $mdTheming) { } }; } -})(); diff --git a/src/components/swipe/swipe.js b/src/components/swipe/swipe.js index 2c4602e3b24..bc6293cad3a 100644 --- a/src/components/swipe/swipe.js +++ b/src/components/swipe/swipe.js @@ -1,7 +1,3 @@ -(function() { -'use strict'; - - /** * @ngdoc module * @name material.components.swipe @@ -23,7 +19,6 @@ *
Swipe me left!
* */ - /** * @ngdoc directive * @module material.components.swipe @@ -41,31 +36,20 @@ * */ -var module = angular.module('material.components.swipe',[]); +angular.module('material.components.swipe', []) + .directive('mdSwipeLeft', getDirective('SwipeLeft')) + .directive('mdSwipeRight', getDirective('SwipeRight')); -['SwipeLeft', 'SwipeRight'].forEach(function(name) { +function getDirective(name) { var directiveName = 'md' + name; var eventName = '$md.' + name.toLowerCase(); - - module.directive(directiveName, /*@ngInject*/ function($parse) { - return { - restrict: 'A', - link: postLink - }; - + return function($parse) { + return { restrict: 'A', link: postLink }; function postLink(scope, element, attr) { var fn = $parse(attr[directiveName]); - element.on(eventName, function(ev) { - scope.$apply(function() { - fn(scope, { - $event: ev - }); - }); + scope.$apply(function() { fn(scope, { $event: ev }); }); }); - } - }); -}); - -})(); + }; +} diff --git a/src/components/switch/switch.js b/src/components/switch/switch.js index 906ac0b14fc..ae7cc150492 100644 --- a/src/components/switch/switch.js +++ b/src/components/switch/switch.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @private * @ngdoc module @@ -157,5 +154,3 @@ function MdSwitch(mdCheckboxDirective, $mdTheming, $mdUtil, $document, $mdConsta } - -})(); diff --git a/src/components/tabs/js/tabDirective.js b/src/components/tabs/js/tabDirective.js index 4ac621a6e28..962503eea56 100644 --- a/src/components/tabs/js/tabDirective.js +++ b/src/components/tabs/js/tabDirective.js @@ -51,69 +51,64 @@ * * */ +angular + .module('material.components.tabs') + .directive('mdTab', MdTab); -(function () { - 'use strict'; +function MdTab () { + return { + require: '^?mdTabs', + terminal: true, + scope: { + label: '@', + active: '=?mdActive', + disabled: '=?ngDisabled', + select: '&?mdOnSelect', + deselect: '&?mdOnDeselect' + }, + link: postLink + }; - angular - .module('material.components.tabs') - .directive('mdTab', MdTab); + function postLink (scope, element, attr, ctrl) { + if (!ctrl) return; + var tabs = element.parent()[0].getElementsByTagName('md-tab'), + index = Array.prototype.indexOf.call(tabs, element[0]), + data = ctrl.insertTab({ + scope: scope, + parent: scope.$parent, + index: index, + template: getTemplate(), + label: getLabel() + }, index); - function MdTab () { - return { - require: '^?mdTabs', - terminal: true, - scope: { - label: '@', - active: '=?mdActive', - disabled: '=?ngDisabled', - select: '&?mdOnSelect', - deselect: '&?mdOnDeselect' - }, - link: postLink - }; + scope.deselect = scope.deselect || angular.noop; + scope.select = scope.select || angular.noop; - function postLink (scope, element, attr, ctrl) { - if (!ctrl) return; - var tabs = element.parent()[0].getElementsByTagName('md-tab'), - index = Array.prototype.indexOf.call(tabs, element[0]), - data = ctrl.insertTab({ - scope: scope, - parent: scope.$parent, - index: index, - template: getTemplate(), - label: getLabel() - }, index); + scope.$watch('active', function (active) { if (active) ctrl.select(data.getIndex()); }); + scope.$watch('disabled', function () { ctrl.refreshIndex(); }); + scope.$on('$destroy', function () { ctrl.removeTab(data); }); - scope.deselect = scope.deselect || angular.noop; - scope.select = scope.select || angular.noop; - - scope.$watch('active', function (active) { if (active) ctrl.select(data.getIndex()); }); - scope.$watch('disabled', function () { ctrl.refreshIndex(); }); - scope.$on('$destroy', function () { ctrl.removeTab(data); }); - - function getLabel () { - var label = attr.label || (element.find('md-tab-label')[0] || element[0]).innerHTML; - return getLabelAttribute() || getLabelElement() || getElementContents(); - function getLabelAttribute () { return attr.label; } - function getLabelElement () { - var label = element.find('md-tab-label'); - if (label.length) return label.remove().html(); - } - function getElementContents () { - var html = element.html(); - element.empty(); - return html; - } + function getLabel () { + var label = attr.label || (element.find('md-tab-label')[0] || element[0]).innerHTML; + return getLabelAttribute() || getLabelElement() || getElementContents(); + function getLabelAttribute () { return attr.label; } + function getLabelElement () { + var label = element.find('md-tab-label'); + if (label.length) return label.remove().html(); } - - function getTemplate () { - var content = element.find('md-tab-body'), - template = content.length ? content.html() : attr.label ? element.html() : null; - if (content.length) content.remove(); - else if (attr.label) element.empty(); - return template; + function getElementContents () { + var html = element.html(); + element.empty(); + return html; } } + + function getTemplate () { + var content = element.find('md-tab-body'), + template = content.length ? content.html() : attr.label ? element.html() : null; + if (content.length) content.remove(); + else if (attr.label) element.empty(); + return template; + } } -})(); +} diff --git a/src/components/tabs/js/tabItemDirective.js b/src/components/tabs/js/tabItemDirective.js index 7a9df779c6f..993153df4ca 100644 --- a/src/components/tabs/js/tabItemDirective.js +++ b/src/components/tabs/js/tabItemDirective.js @@ -1,15 +1,11 @@ -(function () { - 'use strict'; +angular + .module('material.components.tabs') + .directive('mdTabItem', MdTabItem); - angular - .module('material.components.tabs') - .directive('mdTabItem', MdTabItem); - - function MdTabItem () { - return { require: '^?mdTabs', link: link }; - function link (scope, element, attr, ctrl) { - if (!ctrl) return; - ctrl.attachRipple(scope, element); - } +function MdTabItem () { + return { require: '^?mdTabs', link: link }; + function link (scope, element, attr, ctrl) { + if (!ctrl) return; + ctrl.attachRipple(scope, element); } -})(); \ No newline at end of file +} diff --git a/src/components/tabs/js/tabScroll.js b/src/components/tabs/js/tabScroll.js index ef97260ea45..16add62a68f 100644 --- a/src/components/tabs/js/tabScroll.js +++ b/src/components/tabs/js/tabScroll.js @@ -1,19 +1,16 @@ -(function () { - 'use strict'; - angular.module('material.components.tabs') - .directive('mdTabScroll', MdTabScroll); +angular.module('material.components.tabs') + .directive('mdTabScroll', MdTabScroll); - function MdTabScroll ($parse) { - return { - restrict: 'A', - compile: function ($element, attr) { - var fn = $parse(attr.mdTabScroll, null, true); - return function ngEventHandler (scope, element) { - element.on('mousewheel', function (event) { - scope.$apply(function () { fn(scope, { $event: event }); }); - }); - }; - } +function MdTabScroll ($parse) { + return { + restrict: 'A', + compile: function ($element, attr) { + var fn = $parse(attr.mdTabScroll, null, true); + return function ngEventHandler (scope, element) { + element.on('mousewheel', function (event) { + scope.$apply(function () { fn(scope, { $event: event }); }); + }); + }; } } -})(); \ No newline at end of file +} diff --git a/src/components/tabs/js/tabsController.js b/src/components/tabs/js/tabsController.js index 0a3ddfcfcb7..6f2c4b78a4e 100644 --- a/src/components/tabs/js/tabsController.js +++ b/src/components/tabs/js/tabsController.js @@ -1,354 +1,350 @@ -(function () { - 'use strict'; - - angular - .module('material.components.tabs') - .controller('MdTabsController', MdTabsController); - - function MdTabsController ($scope, $element, $window, $timeout, $mdConstant, $mdInkRipple, - $mdUtil, $animate) { - var ctrl = this, - locked = false, - elements = getElements(), - queue = []; - - ctrl.scope = $scope; - ctrl.parent = $scope.$parent; - ctrl.tabs = []; - ctrl.lastSelectedIndex = null; - ctrl.focusIndex = 0; - ctrl.offsetLeft = 0; - ctrl.hasContent = false; - ctrl.hasFocus = false; - ctrl.lastClick = false; - - ctrl.redirectFocus = redirectFocus; - ctrl.attachRipple = attachRipple; - ctrl.shouldStretchTabs = shouldStretchTabs; - ctrl.shouldPaginate = shouldPaginate; - ctrl.shouldCenterTabs = shouldCenterTabs; - ctrl.insertTab = insertTab; - ctrl.removeTab = removeTab; - ctrl.select = select; - ctrl.scroll = scroll; - ctrl.nextPage = nextPage; - ctrl.previousPage = previousPage; - ctrl.keydown = keydown; - ctrl.canPageForward = canPageForward; - ctrl.canPageBack = canPageBack; - ctrl.refreshIndex = refreshIndex; - ctrl.incrementSelectedIndex = incrementSelectedIndex; - ctrl.updateInkBarStyles = updateInkBarStyles; - - init(); - - function init () { - $scope.$watch('selectedIndex', handleSelectedIndexChange); - $scope.$watch('$mdTabsCtrl.focusIndex', handleFocusIndexChange); - $scope.$watch('$mdTabsCtrl.offsetLeft', handleOffsetChange); - $scope.$watch('$mdTabsCtrl.hasContent', handleHasContent); - angular.element($window).on('resize', function () { $scope.$apply(handleWindowResize); }); - $timeout(updateInkBarStyles, 0, false); - $timeout(updateHeightFromContent, 0, false); - } +angular + .module('material.components.tabs') + .controller('MdTabsController', MdTabsController); + +function MdTabsController ($scope, $element, $window, $timeout, $mdConstant, $mdInkRipple, + $mdUtil, $animate) { + var ctrl = this, + locked = false, + elements = getElements(), + queue = []; + + ctrl.scope = $scope; + ctrl.parent = $scope.$parent; + ctrl.tabs = []; + ctrl.lastSelectedIndex = null; + ctrl.focusIndex = 0; + ctrl.offsetLeft = 0; + ctrl.hasContent = false; + ctrl.hasFocus = false; + ctrl.lastClick = false; + + ctrl.redirectFocus = redirectFocus; + ctrl.attachRipple = attachRipple; + ctrl.shouldStretchTabs = shouldStretchTabs; + ctrl.shouldPaginate = shouldPaginate; + ctrl.shouldCenterTabs = shouldCenterTabs; + ctrl.insertTab = insertTab; + ctrl.removeTab = removeTab; + ctrl.select = select; + ctrl.scroll = scroll; + ctrl.nextPage = nextPage; + ctrl.previousPage = previousPage; + ctrl.keydown = keydown; + ctrl.canPageForward = canPageForward; + ctrl.canPageBack = canPageBack; + ctrl.refreshIndex = refreshIndex; + ctrl.incrementSelectedIndex = incrementSelectedIndex; + ctrl.updateInkBarStyles = updateInkBarStyles; + + init(); + + function init () { + $scope.$watch('selectedIndex', handleSelectedIndexChange); + $scope.$watch('$mdTabsCtrl.focusIndex', handleFocusIndexChange); + $scope.$watch('$mdTabsCtrl.offsetLeft', handleOffsetChange); + $scope.$watch('$mdTabsCtrl.hasContent', handleHasContent); + angular.element($window).on('resize', function () { $scope.$apply(handleWindowResize); }); + $timeout(updateInkBarStyles, 0, false); + $timeout(updateHeightFromContent, 0, false); + } - function handleHasContent (hasContent) { - $element[hasContent ? 'removeClass' : 'addClass']('md-no-tab-content'); - } + function handleHasContent (hasContent) { + $element[hasContent ? 'removeClass' : 'addClass']('md-no-tab-content'); + } - function getElements () { - var elements = {}; + function getElements () { + var elements = {}; - //-- gather tab bar elements - elements.wrapper = $element[0].getElementsByTagName('md-tabs-wrapper')[0]; - elements.canvas = elements.wrapper.getElementsByTagName('md-tabs-canvas')[0]; - elements.paging = elements.canvas.getElementsByTagName('md-pagination-wrapper')[0]; - elements.tabs = elements.paging.getElementsByTagName('md-tab-item'); - elements.dummies = elements.canvas.getElementsByTagName('md-dummy-tab'); - elements.inkBar = elements.paging.getElementsByTagName('md-ink-bar')[0]; + //-- gather tab bar elements + elements.wrapper = $element[0].getElementsByTagName('md-tabs-wrapper')[0]; + elements.canvas = elements.wrapper.getElementsByTagName('md-tabs-canvas')[0]; + elements.paging = elements.canvas.getElementsByTagName('md-pagination-wrapper')[0]; + elements.tabs = elements.paging.getElementsByTagName('md-tab-item'); + elements.dummies = elements.canvas.getElementsByTagName('md-dummy-tab'); + elements.inkBar = elements.paging.getElementsByTagName('md-ink-bar')[0]; - //-- gather tab content elements - elements.contentsWrapper = $element[0].getElementsByTagName('md-tabs-content-wrapper')[0]; - elements.contents = elements.contentsWrapper.getElementsByTagName('md-tab-content'); + //-- gather tab content elements + elements.contentsWrapper = $element[0].getElementsByTagName('md-tabs-content-wrapper')[0]; + elements.contents = elements.contentsWrapper.getElementsByTagName('md-tab-content'); - return elements; - } + return elements; + } - function keydown (event) { - switch (event.keyCode) { - case $mdConstant.KEY_CODE.LEFT_ARROW: - event.preventDefault(); - incrementSelectedIndex(-1, true); - break; - case $mdConstant.KEY_CODE.RIGHT_ARROW: - event.preventDefault(); - incrementSelectedIndex(1, true); - break; - case $mdConstant.KEY_CODE.SPACE: - case $mdConstant.KEY_CODE.ENTER: - event.preventDefault(); - if (!locked) $scope.selectedIndex = ctrl.focusIndex; - break; - } - ctrl.lastClick = false; + function keydown (event) { + switch (event.keyCode) { + case $mdConstant.KEY_CODE.LEFT_ARROW: + event.preventDefault(); + incrementSelectedIndex(-1, true); + break; + case $mdConstant.KEY_CODE.RIGHT_ARROW: + event.preventDefault(); + incrementSelectedIndex(1, true); + break; + case $mdConstant.KEY_CODE.SPACE: + case $mdConstant.KEY_CODE.ENTER: + event.preventDefault(); + if (!locked) $scope.selectedIndex = ctrl.focusIndex; + break; } + ctrl.lastClick = false; + } - function incrementSelectedIndex (inc, focus) { - var newIndex, - index = focus ? ctrl.focusIndex : $scope.selectedIndex; - for (newIndex = index + inc; - ctrl.tabs[newIndex] && ctrl.tabs[newIndex].scope.disabled; - newIndex += inc) {} - if (ctrl.tabs[newIndex]) { - if (focus) ctrl.focusIndex = newIndex; - else $scope.selectedIndex = newIndex; - } + function incrementSelectedIndex (inc, focus) { + var newIndex, + index = focus ? ctrl.focusIndex : $scope.selectedIndex; + for (newIndex = index + inc; + ctrl.tabs[newIndex] && ctrl.tabs[newIndex].scope.disabled; + newIndex += inc) {} + if (ctrl.tabs[newIndex]) { + if (focus) ctrl.focusIndex = newIndex; + else $scope.selectedIndex = newIndex; } + } - function handleOffsetChange (left) { - var newValue = shouldCenterTabs() ? '' : '-' + left + 'px'; - angular.element(elements.paging).css('left', newValue); - $scope.$broadcast('$mdTabsPaginationChanged'); - } + function handleOffsetChange (left) { + var newValue = shouldCenterTabs() ? '' : '-' + left + 'px'; + angular.element(elements.paging).css('left', newValue); + $scope.$broadcast('$mdTabsPaginationChanged'); + } - function handleFocusIndexChange (newIndex, oldIndex) { - if (newIndex === oldIndex) return; - if (!elements.tabs[newIndex]) return; - adjustOffset(); - redirectFocus(); - } + function handleFocusIndexChange (newIndex, oldIndex) { + if (newIndex === oldIndex) return; + if (!elements.tabs[newIndex]) return; + adjustOffset(); + redirectFocus(); + } - function redirectFocus () { - elements.dummies[ctrl.focusIndex].focus(); - } + function redirectFocus () { + elements.dummies[ctrl.focusIndex].focus(); + } - function adjustOffset () { - if (shouldCenterTabs()) return; - var tab = elements.tabs[ctrl.focusIndex], - left = tab.offsetLeft, - right = tab.offsetWidth + left; - ctrl.offsetLeft = Math.max(ctrl.offsetLeft, fixOffset(right - elements.canvas.clientWidth)); - ctrl.offsetLeft = Math.min(ctrl.offsetLeft, fixOffset(left)); - } + function adjustOffset () { + if (shouldCenterTabs()) return; + var tab = elements.tabs[ctrl.focusIndex], + left = tab.offsetLeft, + right = tab.offsetWidth + left; + ctrl.offsetLeft = Math.max(ctrl.offsetLeft, fixOffset(right - elements.canvas.clientWidth)); + ctrl.offsetLeft = Math.min(ctrl.offsetLeft, fixOffset(left)); + } - function handleWindowResize () { - ctrl.lastSelectedIndex = $scope.selectedIndex; - updateInkBarStyles(); - ctrl.offsetLeft = fixOffset(ctrl.offsetLeft); - } + function handleWindowResize () { + ctrl.lastSelectedIndex = $scope.selectedIndex; + updateInkBarStyles(); + ctrl.offsetLeft = fixOffset(ctrl.offsetLeft); + } - function processQueue () { - queue.forEach(function (func) { $timeout(func); }); - queue = []; - } + function processQueue () { + queue.forEach(function (func) { $timeout(func); }); + queue = []; + } - function insertTab (tabData, index) { - var proto = { - getIndex: function () { return ctrl.tabs.indexOf(tab); }, - isActive: function () { return this.getIndex() === $scope.selectedIndex; }, - isLeft: function () { return this.getIndex() < $scope.selectedIndex; }, - isRight: function () { return this.getIndex() > $scope.selectedIndex; }, - hasFocus: function () { return !ctrl.lastClick && ctrl.hasFocus && this.getIndex() === ctrl.focusIndex; }, - id: $mdUtil.nextUid() - }, - tab = angular.extend(proto, tabData); - if (angular.isDefined(index)) { - ctrl.tabs.splice(index, 0, tab); - } else { - ctrl.tabs.push(tab); - } - processQueue(); - updateHasContent(); - return tab; - } + function insertTab (tabData, index) { + var proto = { + getIndex: function () { return ctrl.tabs.indexOf(tab); }, + isActive: function () { return this.getIndex() === $scope.selectedIndex; }, + isLeft: function () { return this.getIndex() < $scope.selectedIndex; }, + isRight: function () { return this.getIndex() > $scope.selectedIndex; }, + hasFocus: function () { return !ctrl.lastClick && ctrl.hasFocus && this.getIndex() === ctrl.focusIndex; }, + id: $mdUtil.nextUid() + }, + tab = angular.extend(proto, tabData); + if (angular.isDefined(index)) { + ctrl.tabs.splice(index, 0, tab); + } else { + ctrl.tabs.push(tab); + } + processQueue(); + updateHasContent(); + return tab; + } - function updateHasContent () { - var hasContent = false; - angular.forEach(ctrl.tabs, function (tab) { - if (tab.template) hasContent = true; - }); - ctrl.hasContent = hasContent; - } + function updateHasContent () { + var hasContent = false; + angular.forEach(ctrl.tabs, function (tab) { + if (tab.template) hasContent = true; + }); + ctrl.hasContent = hasContent; + } - function removeTab (tabData) { - ctrl.tabs.splice(tabData.getIndex(), 1); - refreshIndex(); - $timeout(function () { - updateInkBarStyles(); - ctrl.offsetLeft = fixOffset(ctrl.offsetLeft); - }); - } + function removeTab (tabData) { + ctrl.tabs.splice(tabData.getIndex(), 1); + refreshIndex(); + $timeout(function () { + updateInkBarStyles(); + ctrl.offsetLeft = fixOffset(ctrl.offsetLeft); + }); + } - function refreshIndex () { - $scope.selectedIndex = getNearestSafeIndex($scope.selectedIndex); - ctrl.focusIndex = getNearestSafeIndex(ctrl.focusIndex); - } + function refreshIndex () { + $scope.selectedIndex = getNearestSafeIndex($scope.selectedIndex); + ctrl.focusIndex = getNearestSafeIndex(ctrl.focusIndex); + } - function handleSelectedIndexChange (newValue, oldValue) { - if (newValue === oldValue) return; + function handleSelectedIndexChange (newValue, oldValue) { + if (newValue === oldValue) return; - $scope.selectedIndex = getNearestSafeIndex(newValue); - ctrl.lastSelectedIndex = oldValue; - updateInkBarStyles(); - updateHeightFromContent(); - $scope.$broadcast('$mdTabsChanged'); - ctrl.tabs[oldValue] && ctrl.tabs[oldValue].scope.deselect(); - ctrl.tabs[newValue] && ctrl.tabs[newValue].scope.select(); - } + $scope.selectedIndex = getNearestSafeIndex(newValue); + ctrl.lastSelectedIndex = oldValue; + updateInkBarStyles(); + updateHeightFromContent(); + $scope.$broadcast('$mdTabsChanged'); + ctrl.tabs[oldValue] && ctrl.tabs[oldValue].scope.deselect(); + ctrl.tabs[newValue] && ctrl.tabs[newValue].scope.select(); + } - function handleResizeWhenVisible () { - //-- if there is already a watcher waiting for resize, do nothing - if (handleResizeWhenVisible.watcher) return; - //-- otherwise, we will abuse the $watch function to check for visible - handleResizeWhenVisible.watcher = $scope.$watch(function () { - //-- since we are checking for DOM size, we use $timeout to wait for after the DOM updates - $timeout(function () { - //-- if the watcher has already run (ie. multiple digests in one cycle), do nothing - if (!handleResizeWhenVisible.watcher) return; - - if ($element.prop('offsetParent')) { - handleResizeWhenVisible.watcher(); - handleResizeWhenVisible.watcher = null; - - //-- we have to trigger our own $apply so that the DOM bindings will update - $scope.$apply(handleWindowResize); - } - }, 0, false); - }); - } + function handleResizeWhenVisible () { + //-- if there is already a watcher waiting for resize, do nothing + if (handleResizeWhenVisible.watcher) return; + //-- otherwise, we will abuse the $watch function to check for visible + handleResizeWhenVisible.watcher = $scope.$watch(function () { + //-- since we are checking for DOM size, we use $timeout to wait for after the DOM updates + $timeout(function () { + //-- if the watcher has already run (ie. multiple digests in one cycle), do nothing + if (!handleResizeWhenVisible.watcher) return; + + if ($element.prop('offsetParent')) { + handleResizeWhenVisible.watcher(); + handleResizeWhenVisible.watcher = null; + + //-- we have to trigger our own $apply so that the DOM bindings will update + $scope.$apply(handleWindowResize); + } + }, 0, false); + }); + } - function updateHeightFromContent () { - if (!$scope.dynamicHeight) return $element.css('height', ''); - if (!ctrl.tabs.length) return queue.push(updateHeightFromContent); - var tabContent = elements.contents[$scope.selectedIndex], - contentHeight = tabContent ? tabContent.offsetHeight : 0, - tabsHeight = elements.wrapper.offsetHeight, - newHeight = contentHeight + tabsHeight, - currentHeight = $element.prop('clientHeight'); - if (currentHeight === newHeight) return; - locked = true; - $animate - .animate( - $element, - { height: currentHeight + 'px' }, - { height: newHeight + 'px'} - ) - .then(function () { - $element.css('height', ''); - locked = false; - }); - } + function updateHeightFromContent () { + if (!$scope.dynamicHeight) return $element.css('height', ''); + if (!ctrl.tabs.length) return queue.push(updateHeightFromContent); + var tabContent = elements.contents[$scope.selectedIndex], + contentHeight = tabContent ? tabContent.offsetHeight : 0, + tabsHeight = elements.wrapper.offsetHeight, + newHeight = contentHeight + tabsHeight, + currentHeight = $element.prop('clientHeight'); + if (currentHeight === newHeight) return; + locked = true; + $animate + .animate( + $element, + { height: currentHeight + 'px' }, + { height: newHeight + 'px'} + ) + .then(function () { + $element.css('height', ''); + locked = false; + }); + } - function updateInkBarStyles () { - if (!ctrl.tabs.length) return queue.push(updateInkBarStyles); - //-- if the element is not visible, we will not be able to calculate sizes until it is - //-- we should treat that as a resize event rather than just updating the ink bar - if (!$element.prop('offsetParent')) return handleResizeWhenVisible(); - var index = $scope.selectedIndex, - totalWidth = elements.paging.offsetWidth, - tab = elements.tabs[index], - left = tab.offsetLeft, - right = totalWidth - left - tab.offsetWidth; - updateInkBarClassName(); - angular.element(elements.inkBar).css({ left: left + 'px', right: right + 'px' }); - } + function updateInkBarStyles () { + if (!ctrl.tabs.length) return queue.push(updateInkBarStyles); + //-- if the element is not visible, we will not be able to calculate sizes until it is + //-- we should treat that as a resize event rather than just updating the ink bar + if (!$element.prop('offsetParent')) return handleResizeWhenVisible(); + var index = $scope.selectedIndex, + totalWidth = elements.paging.offsetWidth, + tab = elements.tabs[index], + left = tab.offsetLeft, + right = totalWidth - left - tab.offsetWidth; + updateInkBarClassName(); + angular.element(elements.inkBar).css({ left: left + 'px', right: right + 'px' }); + } - function updateInkBarClassName () { - var newIndex = $scope.selectedIndex, - oldIndex = ctrl.lastSelectedIndex, - ink = angular.element(elements.inkBar); - ink.removeClass('md-left md-right'); - if (!angular.isNumber(oldIndex)) return; - if (newIndex < oldIndex) { - ink.addClass('md-left'); - } else if (newIndex > oldIndex) { - ink.addClass('md-right'); - } + function updateInkBarClassName () { + var newIndex = $scope.selectedIndex, + oldIndex = ctrl.lastSelectedIndex, + ink = angular.element(elements.inkBar); + ink.removeClass('md-left md-right'); + if (!angular.isNumber(oldIndex)) return; + if (newIndex < oldIndex) { + ink.addClass('md-left'); + } else if (newIndex > oldIndex) { + ink.addClass('md-right'); } + } - function getNearestSafeIndex(newIndex) { - var maxOffset = Math.max(ctrl.tabs.length - newIndex, newIndex), - i, tab; - for (i = 0; i <= maxOffset; i++) { - tab = ctrl.tabs[newIndex + i]; - if (tab && (tab.scope.disabled !== true)) return tab.getIndex(); - tab = ctrl.tabs[newIndex - i]; - if (tab && (tab.scope.disabled !== true)) return tab.getIndex(); - } - return newIndex; + function getNearestSafeIndex(newIndex) { + var maxOffset = Math.max(ctrl.tabs.length - newIndex, newIndex), + i, tab; + for (i = 0; i <= maxOffset; i++) { + tab = ctrl.tabs[newIndex + i]; + if (tab && (tab.scope.disabled !== true)) return tab.getIndex(); + tab = ctrl.tabs[newIndex - i]; + if (tab && (tab.scope.disabled !== true)) return tab.getIndex(); } + return newIndex; + } - function shouldStretchTabs () { - switch ($scope.stretchTabs) { - case 'always': return true; - case 'never': return false; - default: return !shouldPaginate() && $window.matchMedia('(max-width: 600px)').matches; - } + function shouldStretchTabs () { + switch ($scope.stretchTabs) { + case 'always': return true; + case 'never': return false; + default: return !shouldPaginate() && $window.matchMedia('(max-width: 600px)').matches; } + } - function shouldCenterTabs () { - return $scope.centerTabs && !shouldPaginate(); - } + function shouldCenterTabs () { + return $scope.centerTabs && !shouldPaginate(); + } - function shouldPaginate () { - if ($scope.noPagination) return false; - var canvasWidth = $element.prop('clientWidth'); - angular.forEach(elements.tabs, function (tab) { canvasWidth -= tab.offsetWidth; }); - return canvasWidth < 0; - } + function shouldPaginate () { + if ($scope.noPagination) return false; + var canvasWidth = $element.prop('clientWidth'); + angular.forEach(elements.tabs, function (tab) { canvasWidth -= tab.offsetWidth; }); + return canvasWidth < 0; + } - function select (index) { - if (!locked) ctrl.focusIndex = $scope.selectedIndex = index; - ctrl.lastClick = true; - } + function select (index) { + if (!locked) ctrl.focusIndex = $scope.selectedIndex = index; + ctrl.lastClick = true; + } - function scroll (event) { - if (!shouldPaginate()) return; - event.preventDefault(); - ctrl.offsetLeft = fixOffset(ctrl.offsetLeft - event.wheelDelta); - } + function scroll (event) { + if (!shouldPaginate()) return; + event.preventDefault(); + ctrl.offsetLeft = fixOffset(ctrl.offsetLeft - event.wheelDelta); + } - function fixOffset (value) { - if (!elements.tabs.length || !shouldPaginate()) return 0; - var lastTab = elements.tabs[elements.tabs.length - 1], - totalWidth = lastTab.offsetLeft + lastTab.offsetWidth; - value = Math.max(0, value); - value = Math.min(totalWidth - elements.canvas.clientWidth, value); - return value; - } + function fixOffset (value) { + if (!elements.tabs.length || !shouldPaginate()) return 0; + var lastTab = elements.tabs[elements.tabs.length - 1], + totalWidth = lastTab.offsetLeft + lastTab.offsetWidth; + value = Math.max(0, value); + value = Math.min(totalWidth - elements.canvas.clientWidth, value); + return value; + } - function nextPage () { - var viewportWidth = elements.canvas.clientWidth, - totalWidth = viewportWidth + ctrl.offsetLeft, - i, tab; - for (i = 0; i < elements.tabs.length; i++) { - tab = elements.tabs[i]; - if (tab.offsetLeft + tab.offsetWidth > totalWidth) break; - } - ctrl.offsetLeft = fixOffset(tab.offsetLeft); + function nextPage () { + var viewportWidth = elements.canvas.clientWidth, + totalWidth = viewportWidth + ctrl.offsetLeft, + i, tab; + for (i = 0; i < elements.tabs.length; i++) { + tab = elements.tabs[i]; + if (tab.offsetLeft + tab.offsetWidth > totalWidth) break; } + ctrl.offsetLeft = fixOffset(tab.offsetLeft); + } - function previousPage () { - var i, tab; - for (i = 0; i < elements.tabs.length; i++) { - tab = elements.tabs[i]; - if (tab.offsetLeft + tab.offsetWidth >= ctrl.offsetLeft) break; - } - ctrl.offsetLeft = fixOffset(tab.offsetLeft + tab.offsetWidth - elements.canvas.clientWidth); + function previousPage () { + var i, tab; + for (i = 0; i < elements.tabs.length; i++) { + tab = elements.tabs[i]; + if (tab.offsetLeft + tab.offsetWidth >= ctrl.offsetLeft) break; } + ctrl.offsetLeft = fixOffset(tab.offsetLeft + tab.offsetWidth - elements.canvas.clientWidth); + } - function canPageBack () { - return ctrl.offsetLeft > 0; - } + function canPageBack () { + return ctrl.offsetLeft > 0; + } - function canPageForward () { - var lastTab = elements.tabs[elements.tabs.length - 1]; - return lastTab && lastTab.offsetLeft + lastTab.offsetWidth > elements.canvas.clientWidth + ctrl.offsetLeft; - } + function canPageForward () { + var lastTab = elements.tabs[elements.tabs.length - 1]; + return lastTab && lastTab.offsetLeft + lastTab.offsetWidth > elements.canvas.clientWidth + ctrl.offsetLeft; + } - function attachRipple (scope, element) { - var options = { colorElement: angular.element(elements.inkBar) }; - $mdInkRipple.attachTabBehavior(scope, element, options); - } + function attachRipple (scope, element) { + var options = { colorElement: angular.element(elements.inkBar) }; + $mdInkRipple.attachTabBehavior(scope, element, options); } -})(); +} diff --git a/src/components/tabs/js/tabsDirective.js b/src/components/tabs/js/tabsDirective.js index f8da39a0861..3801bc6f44b 100644 --- a/src/components/tabs/js/tabsDirective.js +++ b/src/components/tabs/js/tabsDirective.js @@ -81,130 +81,125 @@ * * */ +angular + .module('material.components.tabs') + .directive('mdTabs', MdTabs); -(function () { - 'use strict'; - - angular - .module('material.components.tabs') - .directive('mdTabs', MdTabs); - - function MdTabs ($mdTheming) { - return { - scope: { - noPagination: '=?mdNoPagination', - dynamicHeight: '=?mdDynamicHeight', - centerTabs: '=?mdCenterTabs', - selectedIndex: '=?mdSelected', - stretchTabs: '@?mdStretchTabs' - }, - transclude: true, - template: '\ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ - \ -
\ - \ -
\ - \ -
\ - \ - \ - \ - ', - controller: 'MdTabsController', - controllerAs: '$mdTabsCtrl', - link: function (scope, element, attr) { - angular.forEach(scope.$$isolateBindings, function (binding, key) { - if (binding.optional && angular.isUndefined(scope[key])) { - scope[key] = attr.hasOwnProperty(attr.$normalize(binding.attrName)); - } - }); - //-- watch attributes - attr.$observe('mdNoBar', function (value) { scope.noInkBar = angular.isDefined(value); }); - //-- set default value for selectedIndex - scope.selectedIndex = angular.isNumber(scope.selectedIndex) ? scope.selectedIndex : 0; - //-- apply themes - $mdTheming(element); - } - }; - } -})(); \ No newline at end of file +function MdTabs ($mdTheming) { + return { + scope: { + noPagination: '=?mdNoPagination', + dynamicHeight: '=?mdDynamicHeight', + centerTabs: '=?mdCenterTabs', + selectedIndex: '=?mdSelected', + stretchTabs: '@?mdStretchTabs' + }, + transclude: true, + template: '\ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +
\ + \ +
\ + \ +
\ + \ + \ + \ + ', + controller: 'MdTabsController', + controllerAs: '$mdTabsCtrl', + link: function (scope, element, attr) { + angular.forEach(scope.$$isolateBindings, function (binding, key) { + if (binding.optional && angular.isUndefined(scope[key])) { + scope[key] = attr.hasOwnProperty(attr.$normalize(binding.attrName)); + } + }); + //-- watch attributes + attr.$observe('mdNoBar', function (value) { scope.noInkBar = angular.isDefined(value); }); + //-- set default value for selectedIndex + scope.selectedIndex = angular.isNumber(scope.selectedIndex) ? scope.selectedIndex : 0; + //-- apply themes + $mdTheming(element); + } + }; +} diff --git a/src/components/tabs/js/templateDirective.js b/src/components/tabs/js/templateDirective.js index 39359a649f4..067e302de53 100644 --- a/src/components/tabs/js/templateDirective.js +++ b/src/components/tabs/js/templateDirective.js @@ -1,23 +1,20 @@ -(function () { - 'use strict'; - angular - .module('material.components.tabs') - .directive('mdTemplate', MdTemplate); +angular + .module('material.components.tabs') + .directive('mdTemplate', MdTemplate); - function MdTemplate ($compile) { - return { - restrict: 'A', - link: link, - scope: { - template: '=mdTemplate', - compileScope: '=mdScope' - }, - require: '^?mdTabs' - }; - function link (scope, element, attr, ctrl) { - if (!ctrl) return; - element.html(scope.template); - $compile(element.contents())(scope.compileScope); - } +function MdTemplate ($compile) { + return { + restrict: 'A', + link: link, + scope: { + template: '=mdTemplate', + compileScope: '=mdScope' + }, + require: '^?mdTabs' + }; + function link (scope, element, attr, ctrl) { + if (!ctrl) return; + element.html(scope.template); + $compile(element.contents())(scope.compileScope); } -})(); \ No newline at end of file +} diff --git a/src/components/tabs/tabs.js b/src/components/tabs/tabs.js index 83f9b3a2752..9dd3d9ff524 100644 --- a/src/components/tabs/tabs.js +++ b/src/components/tabs/tabs.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.tabs @@ -28,5 +25,3 @@ angular.module('material.components.tabs', [ 'material.core', 'material.components.icon' ]); - -})(); diff --git a/src/components/toast/toast.js b/src/components/toast/toast.js index 049b8d40f2d..82b720ae10e 100644 --- a/src/components/toast/toast.js +++ b/src/components/toast/toast.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.toast @@ -253,5 +250,3 @@ function MdToastProvider($$interimElementProvider) { } } - -})(); diff --git a/src/components/toolbar/toolbar.js b/src/components/toolbar/toolbar.js index 29ebe17304e..407a2b70889 100644 --- a/src/components/toolbar/toolbar.js +++ b/src/components/toolbar/toolbar.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.toolbar @@ -148,4 +145,3 @@ function mdToolbarDirective($$rAF, $mdConstant, $mdUtil, $mdTheming) { }; } -})(); diff --git a/src/components/tooltip/tooltip.js b/src/components/tooltip/tooltip.js index 9e785723819..bd60edff4f3 100644 --- a/src/components/tooltip/tooltip.js +++ b/src/components/tooltip/tooltip.js @@ -1,6 +1,3 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.tooltip @@ -230,4 +227,3 @@ function MdTooltipDirective($timeout, $window, $$rAF, $document, $mdUtil, $mdThe } } -})(); diff --git a/src/components/whiteframe/whiteframe.js b/src/components/whiteframe/whiteframe.js index b56e3913ac4..b90ac304009 100644 --- a/src/components/whiteframe/whiteframe.js +++ b/src/components/whiteframe/whiteframe.js @@ -1,9 +1,5 @@ -(function() { -'use strict'; - /** * @ngdoc module * @name material.components.whiteframe */ angular.module('material.components.whiteframe', []); -})();