@@ -310,131 +310,127 @@ var htmlAnchorDirective = valueFn({
310310 </doc:scenario>
311311 </doc:example>
312312 */
313- var ngRepeatDirective = [ '$compile' , function ( $compile ) {
314- return {
315- priority : 1000 ,
316- terminal : true ,
317- compile : function ( element , attr ) {
313+ var ngRepeatDirective = valueFn ( {
314+ transclude : 'element' ,
315+ priority : 1000 ,
316+ terminal : true ,
317+ compile : function ( element , attr , linker ) {
318+ return function ( scope , iterStartElement , attr ) {
318319 var expression = attr . ngRepeat ;
319- attr . $set ( attr . $attr . ngRepeat ) ;
320- element . replaceWith ( jqLite ( '<!-- ng:repeat: ' + expression + ' -->' ) ) ;
321- var linker = $compile ( element ) ;
322- return function ( scope , iterStartElement , attr ) {
323- var match = expression . match ( / ^ \s * ( .+ ) \s + i n \s + ( .* ) \s * $ / ) ,
324- lhs , rhs , valueIdent , keyIdent ;
325- if ( ! match ) {
326- throw Error ( "Expected ng:repeat in form of '_item_ in _collection_' but got '" +
327- expression + "'." ) ;
328- }
329- lhs = match [ 1 ] ;
330- rhs = match [ 2 ] ;
331- match = lhs . match ( / ^ ( [ \$ \w ] + ) | \( ( [ \$ \w ] + ) \s * , \s * ( [ \$ \w ] + ) \) $ / ) ;
332- if ( ! match ) {
333- throw Error ( "'item' in 'item in collection' should be identifier or (key, value) but got '" +
334- keyValue + "'." ) ;
335- }
336- valueIdent = match [ 3 ] || match [ 1 ] ;
337- keyIdent = match [ 2 ] ;
338-
339- // Store a list of elements from previous run. This is a hash where key is the item from the
340- // iterator, and the value is an array of objects with following properties.
341- // - scope: bound scope
342- // - element: previous element.
343- // - index: position
344- // We need an array of these objects since the same object can be returned from the iterator.
345- // We expect this to be a rare case.
346- var lastOrder = new HashQueueMap ( ) ;
347- scope . $watch ( function ( scope ) {
348- var index , length ,
349- collection = scope . $eval ( rhs ) ,
350- collectionLength = size ( collection , true ) ,
351- childScope ,
352- // Same as lastOrder but it has the current state. It will become the
353- // lastOrder on the next iteration.
354- nextOrder = new HashQueueMap ( ) ,
355- key , value , // key/value of iteration
356- array , last , // last object information {scope, element, index}
357- cursor = iterStartElement ; // current position of the node
358-
359- if ( ! isArray ( collection ) ) {
360- // if object, extract keys, sort them and use to determine order of iteration over obj props
361- array = [ ] ;
362- for ( key in collection ) {
363- if ( collection . hasOwnProperty ( key ) && key . charAt ( 0 ) != '$' ) {
364- array . push ( key ) ;
365- }
320+ var match = expression . match ( / ^ \s * ( .+ ) \s + i n \s + ( .* ) \s * $ / ) ,
321+ lhs , rhs , valueIdent , keyIdent ;
322+ if ( ! match ) {
323+ throw Error ( "Expected ng:repeat in form of '_item_ in _collection_' but got '" +
324+ expression + "'." ) ;
325+ }
326+ lhs = match [ 1 ] ;
327+ rhs = match [ 2 ] ;
328+ match = lhs . match ( / ^ ( [ \$ \w ] + ) | \( ( [ \$ \w ] + ) \s * , \s * ( [ \$ \w ] + ) \) $ / ) ;
329+ if ( ! match ) {
330+ throw Error ( "'item' in 'item in collection' should be identifier or (key, value) but got '" +
331+ keyValue + "'." ) ;
332+ }
333+ valueIdent = match [ 3 ] || match [ 1 ] ;
334+ keyIdent = match [ 2 ] ;
335+
336+ // Store a list of elements from previous run. This is a hash where key is the item from the
337+ // iterator, and the value is an array of objects with following properties.
338+ // - scope: bound scope
339+ // - element: previous element.
340+ // - index: position
341+ // We need an array of these objects since the same object can be returned from the iterator.
342+ // We expect this to be a rare case.
343+ var lastOrder = new HashQueueMap ( ) ;
344+ scope . $watch ( function ( scope ) {
345+ var index , length ,
346+ collection = scope . $eval ( rhs ) ,
347+ collectionLength = size ( collection , true ) ,
348+ childScope ,
349+ // Same as lastOrder but it has the current state. It will become the
350+ // lastOrder on the next iteration.
351+ nextOrder = new HashQueueMap ( ) ,
352+ key , value , // key/value of iteration
353+ array , last , // last object information {scope, element, index}
354+ cursor = iterStartElement ; // current position of the node
355+
356+ if ( ! isArray ( collection ) ) {
357+ // if object, extract keys, sort them and use to determine order of iteration over obj props
358+ array = [ ] ;
359+ for ( key in collection ) {
360+ if ( collection . hasOwnProperty ( key ) && key . charAt ( 0 ) != '$' ) {
361+ array . push ( key ) ;
366362 }
367- array . sort ( ) ;
368- } else {
369- array = collection || [ ] ;
370363 }
364+ array . sort ( ) ;
365+ } else {
366+ array = collection || [ ] ;
367+ }
371368
372- // we are not using forEach for perf reasons (trying to avoid #call)
373- for ( index = 0 , length = array . length ; index < length ; index ++ ) {
374- key = ( collection === array ) ? index : array [ index ] ;
375- value = collection [ key ] ;
376- last = lastOrder . shift ( value ) ;
377- if ( last ) {
378- // if we have already seen this object, then we need to reuse the
379- // associated scope/element
380- childScope = last . scope ;
381- nextOrder . push ( value , last ) ;
382-
383- if ( index === last . index ) {
384- // do nothing
385- cursor = last . element ;
386- } else {
387- // existing item which got moved
388- last . index = index ;
389- // This may be a noop, if the element is next, but I don't know of a good way to
390- // figure this out, since it would require extra DOM access, so let's just hope that
391- // the browsers realizes that it is noop, and treats it as such.
392- cursor . after ( last . element ) ;
393- cursor = last . element ;
394- }
369+ // we are not using forEach for perf reasons (trying to avoid #call)
370+ for ( index = 0 , length = array . length ; index < length ; index ++ ) {
371+ key = ( collection === array ) ? index : array [ index ] ;
372+ value = collection [ key ] ;
373+ last = lastOrder . shift ( value ) ;
374+ if ( last ) {
375+ // if we have already seen this object, then we need to reuse the
376+ // associated scope/element
377+ childScope = last . scope ;
378+ nextOrder . push ( value , last ) ;
379+
380+ if ( index === last . index ) {
381+ // do nothing
382+ cursor = last . element ;
395383 } else {
396- // new item which we don't know about
397- childScope = scope . $new ( ) ;
384+ // existing item which got moved
385+ last . index = index ;
386+ // This may be a noop, if the element is next, but I don't know of a good way to
387+ // figure this out, since it would require extra DOM access, so let's just hope that
388+ // the browsers realizes that it is noop, and treats it as such.
389+ cursor . after ( last . element ) ;
390+ cursor = last . element ;
398391 }
392+ } else {
393+ // new item which we don't know about
394+ childScope = scope . $new ( ) ;
395+ }
399396
400- childScope [ valueIdent ] = value ;
401- if ( keyIdent ) childScope [ keyIdent ] = key ;
402- childScope . $index = index ;
403- childScope . $position = index === 0 ?
404- 'first' :
405- ( index == collectionLength - 1 ? 'last' : 'middle' ) ;
406-
407- if ( ! last ) {
408- linker ( childScope , function ( clone ) {
409- cursor . after ( clone ) ;
410- last = {
411- scope : childScope ,
412- element : ( cursor = clone ) ,
413- index : index
414- } ;
415- nextOrder . push ( value , last ) ;
416- } ) ;
417- }
397+ childScope [ valueIdent ] = value ;
398+ if ( keyIdent ) childScope [ keyIdent ] = key ;
399+ childScope . $index = index ;
400+ childScope . $position = index === 0 ?
401+ 'first' :
402+ ( index == collectionLength - 1 ? 'last' : 'middle' ) ;
403+
404+ if ( ! last ) {
405+ linker ( childScope , function ( clone ) {
406+ cursor . after ( clone ) ;
407+ last = {
408+ scope : childScope ,
409+ element : ( cursor = clone ) ,
410+ index : index
411+ } ;
412+ nextOrder . push ( value , last ) ;
413+ } ) ;
418414 }
415+ }
419416
420- //shrink children
421- for ( key in lastOrder ) {
422- if ( lastOrder . hasOwnProperty ( key ) ) {
423- array = lastOrder [ key ] ;
424- while ( array . length ) {
425- value = array . pop ( ) ;
426- value . element . remove ( ) ;
427- value . scope . $destroy ( ) ;
428- }
417+ //shrink children
418+ for ( key in lastOrder ) {
419+ if ( lastOrder . hasOwnProperty ( key ) ) {
420+ array = lastOrder [ key ] ;
421+ while ( array . length ) {
422+ value = array . pop ( ) ;
423+ value . element . remove ( ) ;
424+ value . scope . $destroy ( ) ;
429425 }
430426 }
427+ }
431428
432- lastOrder = nextOrder ;
433- } ) ;
434- } ;
435- }
436- } ;
437- } ] ;
429+ lastOrder = nextOrder ;
430+ } ) ;
431+ } ;
432+ }
433+ } ) ;
438434
439435
440436/**
0 commit comments