/*! * Angular Material Design * https://github.com/angular/material * @license MIT * v0.9.8 */ (function( window, angular, undefined ){ "use strict"; /** * @ngdoc module * @name material.components.list * @description * List module */ angular.module('material.components.list', [ 'material.core' ]) .controller('MdListController', MdListController) .directive('mdList', mdListDirective) .directive('mdListItem', mdListItemDirective); /** * @ngdoc directive * @name mdList * @module material.components.list * * @restrict E * * @description * The `` directive is a list container for 1..n `` tags. * * @usage * * * * *
*

{{item.title}}

*

{{item.description}}

*
*
*
*
*/ function mdListDirective($mdTheming) { return { restrict: 'E', compile: function(tEl) { tEl[0].setAttribute('role', 'list'); return $mdTheming; } }; } mdListDirective.$inject = ["$mdTheming"]; /** * @ngdoc directive * @name mdListItem * @module material.components.list * * @restrict E * * @description * The `` directive is a container intended for row items in a `` container. * * @usage * * * * Item content in list * * * * */ function mdListItemDirective($mdAria, $mdConstant, $timeout) { var proxiedTypes = ['md-checkbox', 'md-switch']; return { restrict: 'E', controller: 'MdListController', compile: function(tEl, tAttrs) { // Check for proxy controls (no ng-click on parent, and a control inside) var secondaryItem = tEl[0].querySelector('.md-secondary'); var hasProxiedElement; var proxyElement; tEl[0].setAttribute('role', 'listitem'); if (!tAttrs.ngClick) { for (var i = 0, type; type = proxiedTypes[i]; ++i) { if (proxyElement = tEl[0].querySelector(type)) { hasProxiedElement = true; break; } } if (hasProxiedElement) { wrapIn('div'); } else if (!tEl[0].querySelector('md-button')) { tEl.addClass('md-no-proxy'); } } else { wrapIn('button'); } setupToggleAria(); function setupToggleAria() { var toggleTypes = ['md-switch', 'md-checkbox']; var toggle; for (var i = 0, toggleType; toggleType = toggleTypes[i]; ++i) { if (toggle = tEl.find(toggleType)[0]) { if (!toggle.hasAttribute('aria-label')) { var p = tEl.find('p')[0]; if (!p) return; toggle.setAttribute('aria-label', 'Toggle ' + p.textContent); } } } } function wrapIn(type) { var container; if (type == 'div') { container = angular.element('
'); container.append(tEl.contents()); tEl.addClass('md-proxy-focus'); } else { container = angular.element('
'); var copiedAttrs = ['ng-click', 'aria-label', 'ng-disabled']; angular.forEach(copiedAttrs, function(attr) { if (tEl[0].hasAttribute(attr)) { container[0].setAttribute(attr, tEl[0].getAttribute(attr)); tEl[0].removeAttribute(attr); } }); container.children().eq(0).append(tEl.contents()); } tEl[0].setAttribute('tabindex', '-1'); tEl.append(container); if (secondaryItem && secondaryItem.hasAttribute('ng-click')) { $mdAria.expect(secondaryItem, 'aria-label'); var buttonWrapper = angular.element(''); buttonWrapper.attr('ng-click', secondaryItem.getAttribute('ng-click')); secondaryItem.removeAttribute('ng-click'); secondaryItem.setAttribute('tabindex', '-1'); secondaryItem.classList.remove('md-secondary'); buttonWrapper.append(secondaryItem); secondaryItem = buttonWrapper[0]; } // Check for a secondary item and move it outside if ( secondaryItem && ( secondaryItem.hasAttribute('ng-click') || ( tAttrs.ngClick && isProxiedElement(secondaryItem) ) )) { tEl.addClass('md-with-secondary'); tEl.append(secondaryItem); } } function isProxiedElement(el) { return proxiedTypes.indexOf(el.nodeName.toLowerCase()) != -1; } return postLink; function postLink($scope, $element, $attr, ctrl) { var proxies = [], firstChild = $element[0].firstElementChild, hasClick = firstChild && firstChild.hasAttribute('ng-click'); computeProxies(); computeClickable(); if ($element.hasClass('md-proxy-focus') && proxies.length) { angular.forEach(proxies, function(proxy) { proxy = angular.element(proxy); $scope.mouseActive = false; proxy.on('mousedown', function() { $scope.mouseActive = true; $timeout(function(){ $scope.mouseActive = false; }, 100); }) .on('focus', function() { if ($scope.mouseActive === false) { $element.addClass('md-focused'); } proxy.on('blur', function proxyOnBlur() { $element.removeClass('md-focused'); proxy.off('blur', proxyOnBlur); }); }); }); } function computeProxies() { var children = $element.children(); if (children.length && !children[0].hasAttribute('ng-click')) { angular.forEach(proxiedTypes, function(type) { angular.forEach(firstChild.querySelectorAll(type), function(child) { proxies.push(child); }); }); } } function computeClickable() { if (proxies.length || hasClick) { $element.addClass('md-clickable'); ctrl.attachRipple($scope, angular.element($element[0].querySelector('.md-no-style'))); } } if (!hasClick && !proxies.length) { firstChild && firstChild.addEventListener('keypress', function(e) { if (e.target.nodeName != 'INPUT' && e.target.nodeName != 'TEXTAREA') { var keyCode = e.which || e.keyCode; if (keyCode == $mdConstant.KEY_CODE.SPACE) { if (firstChild) { firstChild.click(); e.preventDefault(); e.stopPropagation(); } } } }); } $element.off('click'); $element.off('keypress'); if (proxies.length && firstChild) { $element.children().eq(0).on('click', function(e) { if (firstChild.contains(e.target)) { angular.forEach(proxies, function(proxy) { if (e.target !== proxy && !proxy.contains(e.target)) { angular.element(proxy).triggerHandler('click'); } }); } }); } } } }; } mdListItemDirective.$inject = ["$mdAria", "$mdConstant", "$timeout"]; /* * @private * @ngdoc controller * @name MdListController * @module material.components.list * */ function MdListController($scope, $element, $mdListInkRipple) { var ctrl = this; ctrl.attachRipple = attachRipple; function attachRipple (scope, element) { var options = {}; $mdListInkRipple.attach(scope, element, options); } } MdListController.$inject = ["$scope", "$element", "$mdListInkRipple"]; })(window, window.angular);