123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287 |
- /*!
- * Angular Material Design
- * https://github.com/angular/material
- * @license MIT
- * v0.11.4
- */
- (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 `<md-list>` directive is a list container for 1..n `<md-list-item>` tags.
- *
- * @usage
- * <hljs lang="html">
- * <md-list>
- * <md-list-item class="md-2-line" ng-repeat="item in todos">
- * <md-checkbox ng-model="item.done"></md-checkbox>
- * <div class="md-list-item-text">
- * <h3>{{item.title}}</h3>
- * <p>{{item.description}}</p>
- * </div>
- * </md-list-item>
- * </md-list>
- * </hljs>
- */
- 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 `<md-list-item>` directive is a container intended for row items in a `<md-list>` container.
- *
- * ## CSS
- * `.md-avatar` - class for image avatars
- *
- * `.md-avatar-icon` - class for icon avatars
- *
- * `.md-offset` - on content without an avatar
- *
- * @usage
- * <hljs lang="html">
- * <md-list>
- * <md-list-item>
- * <img class="md-avatar" ng-src="path/to/img"/>
- * <span>Item content in list</span>
- * </md-list-item>
- * <md-list-item>
- * <md-icon class="md-avatar-icon" md-svg-icon="communication:phone"></md-icon>
- * <span>Item content in list</span>
- * </md-list-item>
- * </md-list>
- * </hljs>
- *
- */
- function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $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('<div class="md-no-style md-list-item-inner">');
- container.append(tEl.contents());
- tEl.addClass('md-proxy-focus');
- } else {
- container = angular.element('<md-button class="md-no-style"><div class="md-list-item-inner"></div></md-button>');
- 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('<md-button class="md-secondary-container md-icon-button">');
- 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) {
- var parentButton = $mdUtil.getClosest(e.target, 'BUTTON');
- if (!parentButton && 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", "$mdUtil", "$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);
|