@@ -88,10 +88,12 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
88
88
restrict : 'E' ,
89
89
controller : 'MdListController' ,
90
90
compile : function ( tEl , tAttrs ) {
91
+
91
92
// Check for proxy controls (no ng-click on parent, and a control inside)
92
93
var secondaryItems = tEl [ 0 ] . querySelectorAll ( '.md-secondary' ) ;
93
94
var hasProxiedElement ;
94
95
var proxyElement ;
96
+ var itemContainer = tEl ;
95
97
96
98
tEl [ 0 ] . setAttribute ( 'role' , 'listitem' ) ;
97
99
@@ -130,14 +132,13 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
130
132
}
131
133
132
134
function wrapIn ( type ) {
133
- var container ;
134
135
if ( type == 'div' ) {
135
- container = angular . element ( '<div class="_md-no-style _md-list-item-inner">' ) ;
136
- container . append ( tEl . contents ( ) ) ;
136
+ itemContainer = angular . element ( '<div class="_md-no-style _md-list-item-inner">' ) ;
137
+ itemContainer . append ( tEl . contents ( ) ) ;
137
138
tEl . addClass ( '_md-proxy-focus' ) ;
138
139
} else {
139
140
// Element which holds the default list-item content.
140
- container = angular . element (
141
+ itemContainer = angular . element (
141
142
'<div class="md-button _md-no-style">' +
142
143
' <div class="_md-list-item-inner"></div>' +
143
144
'</div>'
@@ -152,58 +153,48 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
152
153
copyAttributes ( tEl [ 0 ] , buttonWrap [ 0 ] ) ;
153
154
154
155
// Append the button wrap before our list-item content, because it will overlay in relative.
155
- container . prepend ( buttonWrap ) ;
156
- container . children ( ) . eq ( 1 ) . append ( tEl . contents ( ) ) ;
156
+ itemContainer . prepend ( buttonWrap ) ;
157
+ itemContainer . children ( ) . eq ( 1 ) . append ( tEl . contents ( ) ) ;
157
158
158
159
tEl . addClass ( '_md-button-wrap' ) ;
159
160
}
160
161
161
162
tEl [ 0 ] . setAttribute ( 'tabindex' , '-1' ) ;
162
- tEl . append ( container ) ;
163
+ tEl . append ( itemContainer ) ;
163
164
}
164
165
165
166
function wrapSecondaryItems ( ) {
166
- if ( secondaryItems . length === 1 ) {
167
- wrapSecondaryItem ( secondaryItems [ 0 ] , tEl ) ;
168
- } else if ( secondaryItems . length > 1 ) {
169
- var secondaryItemsWrapper = angular . element ( '<div class="_md-secondary-container">' ) ;
170
- angular . forEach ( secondaryItems , function ( secondaryItem ) {
171
- wrapSecondaryItem ( secondaryItem , secondaryItemsWrapper , true ) ;
172
- } ) ;
173
- tEl . append ( secondaryItemsWrapper ) ;
174
- }
167
+ var secondaryItemsWrapper = angular . element ( '<div class="_md-secondary-container">' ) ;
168
+
169
+ angular . forEach ( secondaryItems , function ( secondaryItem ) {
170
+ wrapSecondaryItem ( secondaryItem , secondaryItemsWrapper ) ;
171
+ } ) ;
172
+
173
+ // Since the secondary item container is static we need to fill the remaing space.
174
+ var spaceFiller = angular . element ( '<div class="flex"></div>' ) ;
175
+ itemContainer . append ( spaceFiller ) ;
176
+
177
+ itemContainer . append ( secondaryItemsWrapper ) ;
175
178
}
176
179
177
- function wrapSecondaryItem ( secondaryItem , container , hasSecondaryItemsWrapper ) {
180
+ function wrapSecondaryItem ( secondaryItem , container ) {
178
181
if ( secondaryItem && ! isButton ( secondaryItem ) && secondaryItem . hasAttribute ( 'ng-click' ) ) {
179
182
$mdAria . expect ( secondaryItem , 'aria-label' ) ;
180
- var buttonWrapper ;
181
- if ( hasSecondaryItemsWrapper ) {
182
- buttonWrapper = angular . element ( '<md-button class="md-icon-button">' ) ;
183
- } else {
184
- buttonWrapper = angular . element ( '<md-button class="_md-secondary-container md-icon-button">' ) ;
185
- }
183
+ var buttonWrapper = angular . element ( '<md-button class="md-secondary md-icon-button">' ) ;
186
184
copyAttributes ( secondaryItem , buttonWrapper [ 0 ] ) ;
187
185
secondaryItem . setAttribute ( 'tabindex' , '-1' ) ;
188
- secondaryItem . classList . remove ( 'md-secondary' ) ;
189
186
buttonWrapper . append ( secondaryItem ) ;
190
187
secondaryItem = buttonWrapper [ 0 ] ;
191
188
}
192
189
193
- // Check for a secondary item and move it outside
194
- if ( secondaryItem && (
195
- secondaryItem . hasAttribute ( 'ng-click' ) ||
196
- ( tAttrs . ngClick &&
197
- isProxiedElement ( secondaryItem ) )
198
- ) ) {
199
- // When using multiple secondary items we need to remove their secondary class to be
200
- // orderd correctly in the list-item
201
- if ( hasSecondaryItemsWrapper ) {
202
- secondaryItem . classList . remove ( 'md-secondary' ) ;
203
- }
204
- tEl . addClass ( 'md-with-secondary' ) ;
205
- container . append ( secondaryItem ) ;
190
+ if ( secondaryItem && ( ! hasClickEvent ( secondaryItem ) || ( ! tAttrs . ngClick && isProxiedElement ( secondaryItem ) ) ) ) {
191
+ // In this case we remove the secondary class, so we can identify it later, when we searching for the
192
+ // proxy items.
193
+ angular . element ( secondaryItem ) . removeClass ( 'md-secondary' ) ;
206
194
}
195
+
196
+ tEl . addClass ( 'md-with-secondary' ) ;
197
+ container . append ( secondaryItem ) ;
207
198
}
208
199
209
200
function copyAttributes ( item , wrapper ) {
@@ -228,14 +219,23 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
228
219
return nodeName == "MD-BUTTON" || nodeName == "BUTTON" ;
229
220
}
230
221
222
+ function hasClickEvent ( element ) {
223
+ var attr = element . attributes ;
224
+ for ( var i = 0 ; i < attr . length ; i ++ ) {
225
+ if ( tAttrs . $normalize ( attr [ i ] . name ) === 'ngClick' ) return true ;
226
+ }
227
+ return false ;
228
+ }
229
+
231
230
return postLink ;
232
231
233
232
function postLink ( $scope , $element , $attr , ctrl ) {
234
233
235
- var proxies = [ ] ,
236
- firstChild = $element [ 0 ] . firstElementChild ,
237
- hasClick = firstChild && firstChild . firstElementChild &&
238
- hasClickEvent ( firstChild . firstElementChild ) ;
234
+ var proxies = [ ] ,
235
+ firstElement = $element [ 0 ] . firstElementChild ,
236
+ isButtonWrap = $element . hasClass ( '_md-button-wrap' ) ,
237
+ clickChild = isButtonWrap ? firstElement . firstElementChild : firstElement ,
238
+ hasClick = clickChild && hasClickEvent ( clickChild ) ;
239
239
240
240
computeProxies ( ) ;
241
241
computeClickable ( ) ;
@@ -261,22 +261,19 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
261
261
} ) ;
262
262
}
263
263
264
- function hasClickEvent ( element ) {
265
- var attr = element . attributes ;
266
- for ( var i = 0 ; i < attr . length ; i ++ ) {
267
- if ( $attr . $normalize ( attr [ i ] . name ) === 'ngClick' ) return true ;
268
- }
269
- return false ;
270
- }
271
264
272
265
function computeProxies ( ) {
273
- var children = $element . children ( ) ;
274
- if ( children . length && ! children [ 0 ] . hasAttribute ( 'ng-click' ) ) {
266
+ if ( firstElement && firstElement . children && ! hasClick ) {
267
+
275
268
angular . forEach ( proxiedTypes , function ( type ) {
276
- angular . forEach ( firstChild . querySelectorAll ( type ) , function ( child ) {
269
+
270
+ // All elements which are not capable for being used a proxy have the .md-secondary class
271
+ // applied. These items had been sorted out in the secondary wrap function.
272
+ angular . forEach ( firstElement . querySelectorAll ( type + ':not(.md-secondary)' ) , function ( child ) {
277
273
proxies . push ( child ) ;
278
274
} ) ;
279
275
} ) ;
276
+
280
277
}
281
278
}
282
279
function computeClickable ( ) {
@@ -289,12 +286,12 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
289
286
}
290
287
}
291
288
292
- var firstChildKeypressListener = function ( e ) {
289
+ var clickChildKeypressListener = function ( e ) {
293
290
if ( e . target . nodeName != 'INPUT' && e . target . nodeName != 'TEXTAREA' && ! e . target . isContentEditable ) {
294
291
var keyCode = e . which || e . keyCode ;
295
292
if ( keyCode == $mdConstant . KEY_CODE . SPACE ) {
296
- if ( firstChild ) {
297
- firstChild . click ( ) ;
293
+ if ( clickChild ) {
294
+ clickChild . click ( ) ;
298
295
e . preventDefault ( ) ;
299
296
e . stopPropagation ( ) ;
300
297
}
@@ -303,16 +300,16 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
303
300
} ;
304
301
305
302
if ( ! hasClick && ! proxies . length ) {
306
- firstChild && firstChild . addEventListener ( 'keypress' , firstChildKeypressListener ) ;
303
+ clickChild && clickChild . addEventListener ( 'keypress' , clickChildKeypressListener ) ;
307
304
}
308
305
309
306
$element . off ( 'click' ) ;
310
307
$element . off ( 'keypress' ) ;
311
308
312
- if ( proxies . length == 1 && firstChild ) {
309
+ if ( proxies . length == 1 && clickChild ) {
313
310
$element . children ( ) . eq ( 0 ) . on ( 'click' , function ( e ) {
314
311
var parentButton = $mdUtil . getClosest ( e . target , 'BUTTON' ) ;
315
- if ( ! parentButton && firstChild . contains ( e . target ) ) {
312
+ if ( ! parentButton && clickChild . contains ( e . target ) ) {
316
313
angular . forEach ( proxies , function ( proxy ) {
317
314
if ( e . target !== proxy && ! proxy . contains ( e . target ) ) {
318
315
angular . element ( proxy ) . triggerHandler ( 'click' ) ;
@@ -323,7 +320,7 @@ function mdListItemDirective($mdAria, $mdConstant, $mdUtil, $timeout) {
323
320
}
324
321
325
322
$scope . $on ( '$destroy' , function ( ) {
326
- firstChild && firstChild . removeEventListener ( 'keypress' , firstChildKeypressListener ) ;
323
+ clickChild && clickChild . removeEventListener ( 'keypress' , clickChildKeypressListener ) ;
327
324
} ) ;
328
325
}
329
326
}
0 commit comments