@@ -154,6 +154,7 @@ function mdListDirective($mdTheming) {
154154 * The recognized `md-switch` will toggle its state, when the user clicks on the `md-list-item`.
155155 *
156156 * It is also possible to have a `md-menu` inside of a `md-list-item`.
157+ *
157158 * <hljs lang="html">
158159 * <md-list-item>
159160 * <p>Click anywhere to fire the secondary action</p>
@@ -185,12 +186,13 @@ function mdListDirective($mdTheming) {
185186 *
186187 * The menu will automatically open, when the users clicks on the `md-list-item`.<br/>
187188 *
188- * If the developer didn't specify any position mode on the menu, the `md-list-item` will automatically detect the
189- * position mode and applies it to the `md-menu`.
189+ * If the developer didn't specify any position mode on the menu, the `md-list-item` will
190+ * automatically detect the position mode and apply it to the `md-menu`.
190191 *
191192 * ### Avatars
192- * Sometimes you may want to have some avatars inside of the `md-list-item `.<br/>
193- * You are able to create a optimized icon for the list item, by applying the `.md-avatar` class on the `<img>` element.
193+ * Sometimes you may want to have avatars inside of the `md-list-item `.<br/>
194+ * You are able to create an optimized icon for the list item, by applying the `.md-avatar` class on
195+ * the `<img>` element.
194196 *
195197 * <hljs lang="html">
196198 * <md-list-item>
@@ -199,15 +201,16 @@ function mdListDirective($mdTheming) {
199201 * </hljs>
200202 *
201203 * When using `<md-icon>` for an avatar, you have to use the `.md-avatar-icon` class.
204+ *
202205 * <hljs lang="html">
203206 * <md-list-item>
204207 * <md-icon class="md-avatar-icon" md-svg-icon="social:person"></md-icon>
205208 * <span>Timothy Kopra</span>
206209 * </md-list-item>
207210 * </hljs>
208211 *
209- * In cases, you have a `md-list-item`, which doesn't have any avatar,
210- * but you want to align it with the other avatar items, you have to use the `.md-offset` class.
212+ * In cases where you have a `md-list-item`, which doesn't have an avatar,
213+ * but you want to align it with the other avatar items, you need to use the `.md-offset` class.
211214 *
212215 * <hljs lang="html">
213216 * <md-list-item class="md-offset">
@@ -220,7 +223,7 @@ function mdListDirective($mdTheming) {
220223 *
221224 * ---
222225 * If the `md-list-item` is clickable, we wrap all content inside of a `<div>` and create
223- * an overlaying button, which will will execute the given actions (like `ng-href`, `ng-click`)
226+ * an overlaying button, which will will execute the given actions (like `ng-href`, `ng-click`).
224227 *
225228 * We create an overlaying button, instead of wrapping all content inside of the button,
226229 * because otherwise some elements may not be clickable inside of the button.
@@ -344,7 +347,7 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
344347 '<md-button class="md-no-style"></md-button>'
345348 ) ;
346349
347- copyAttributes ( tElement [ 0 ] , buttonWrap [ 0 ] ) ;
350+ moveAttributes ( tElement [ 0 ] , buttonWrap [ 0 ] ) ;
348351
349352 // If there is no aria-label set on the button (previously copied over if present)
350353 // we determine the label from the content and copy it to the button.
@@ -353,13 +356,14 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
353356 }
354357
355358 // We allow developers to specify the `md-no-focus` class, to disable the focus style
356- // on the button executor. Once more classes should be forwarded, we should probably make the
357- // class forward more generic.
359+ // on the button executor. Once more classes should be forwarded, we should probably make
360+ // the class forward more generic.
358361 if ( tElement . hasClass ( 'md-no-focus' ) ) {
359362 buttonWrap . addClass ( 'md-no-focus' ) ;
360363 }
361364
362- // Append the button wrap before our list-item content, because it will overlay in relative.
365+ // Append the button wrap before our list-item content, because it will overlay in
366+ // relative.
363367 itemContainer . prepend ( buttonWrap ) ;
364368 itemContainer . children ( ) . eq ( 1 ) . append ( tElement . contents ( ) ) ;
365369
@@ -392,10 +396,10 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
392396 $mdAria . expect ( secondaryItem , 'aria-label' ) ;
393397 var buttonWrapper = angular . element ( '<md-button class="md-secondary md-icon-button">' ) ;
394398
395- // Copy the attributes from the secondary item to the generated button.
399+ // Move the attributes from the secondary item to the generated button.
396400 // We also support some additional attributes from the secondary item,
397401 // because some developers may use a ngIf, ngHide, ngShow on their item.
398- copyAttributes ( secondaryItem , buttonWrapper [ 0 ] , [ 'ng-if' , 'ng-hide' , 'ng-show' ] ) ;
402+ moveAttributes ( secondaryItem , buttonWrapper [ 0 ] , [ 'ng-if' , 'ng-hide' , 'ng-show' ] ) ;
399403
400404 secondaryItem . setAttribute ( 'tabindex' , '-1' ) ;
401405 buttonWrapper . append ( secondaryItem ) ;
@@ -416,14 +420,14 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
416420 }
417421
418422 /**
419- * Copies attributes from a source element to the destination element
420- * By default the function will copy the most necessary attributes, supported
423+ * Moves attributes from a source element to the destination element.
424+ * By default, the function will copy the most necessary attributes, supported
421425 * by the button executor for clickable list items.
422426 * @param source Element with the specified attributes
423- * @param destination Element which will retrieve the attributes
424- * @param extraAttrs Additional attributes, which will be copied over.
427+ * @param destination Element which will receive the attributes
428+ * @param extraAttrs Additional attributes, which will be moved over
425429 */
426- function copyAttributes ( source , destination , extraAttrs ) {
430+ function moveAttributes ( source , destination , extraAttrs ) {
427431 var copiedAttrs = $mdUtil . prefixer ( [
428432 'ng-if' , 'ng-click' , 'ng-dblclick' , 'aria-label' , 'ng-disabled' , 'ui-sref' ,
429433 'href' , 'ng-href' , 'rel' , 'target' , 'ng-attr-ui-sref' , 'ui-sref-opts' , 'download'
@@ -466,7 +470,9 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
466470 function hasClickEvent ( element ) {
467471 var attr = element . attributes ;
468472 for ( var i = 0 ; i < attr . length ; i ++ ) {
469- if ( tAttrs . $normalize ( attr [ i ] . name ) === 'ngClick' ) return true ;
473+ if ( tAttrs . $normalize ( attr [ i ] . name ) === 'ngClick' ) {
474+ return true ;
475+ }
470476 }
471477 return false ;
472478 }
@@ -555,14 +561,19 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
555561 return false ;
556562 }
557563
558- var clickChildKeypressListener = function ( e ) {
559- if ( e . target . nodeName !== 'INPUT' && e . target . nodeName !== 'TEXTAREA' && ! e . target . isContentEditable ) {
560- var keyCode = e . which || e . keyCode ;
564+ /**
565+ * @param {KeyboardEvent } keypressEvent
566+ */
567+ var clickChildKeypressListener = function ( keypressEvent ) {
568+ if ( keypressEvent . target . nodeName !== 'INPUT' &&
569+ keypressEvent . target . nodeName !== 'TEXTAREA' &&
570+ ! keypressEvent . target . isContentEditable ) {
571+ var keyCode = keypressEvent . which || keypressEvent . keyCode ;
561572 if ( keyCode === $mdConstant . KEY_CODE . SPACE ) {
562573 if ( clickChild ) {
563574 clickChild . click ( ) ;
564- e . preventDefault ( ) ;
565- e . stopPropagation ( ) ;
575+ keypressEvent . preventDefault ( ) ;
576+ keypressEvent . stopPropagation ( ) ;
566577 }
567578 }
568579 }
@@ -574,6 +585,9 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
574585
575586 $element . off ( 'click' ) ;
576587 $element . off ( 'keypress' ) ;
588+ // Disable ng-aria's "helpful" keydown event that causes our ng-click handlers to be called
589+ // twice.
590+ $element . off ( 'keydown' ) ;
577591
578592 if ( proxies . length === 1 && clickChild ) {
579593 $element . children ( ) . eq ( 0 ) . on ( 'click' , function ( clickEvent ) {
0 commit comments