@@ -5,7 +5,6 @@ import { assert } from 'ember-metal/debug';
55@submodule ember-metal
66*/
77
8- var SPLIT_REGEX = / \{ | \} / ;
98var END_WITH_EACH_REGEX = / \. @ e a c h $ / ;
109
1110/**
@@ -42,31 +41,46 @@ export default function expandProperties(pattern, callback) {
4241 pattern . indexOf ( ' ' ) === - 1
4342 ) ;
4443
45- var parts = pattern . split ( SPLIT_REGEX ) ;
46- var properties = [ parts ] ;
44+ let properties = [ pattern ] ;
4745
48- for ( let i = 0 ; i < parts . length ; i ++ ) {
49- let part = parts [ i ] ;
50- if ( part . indexOf ( ',' ) >= 0 ) {
51- properties = duplicateAndReplace ( properties , part . split ( ',' ) , i ) ;
46+ // Iterating backward over the pattern makes dealing with indeces easier.
47+ let bookmark ;
48+ let inside = false ;
49+ for ( let i = pattern . length ; i > 0 ; -- i ) {
50+ let current = pattern [ i - 1 ] ;
51+
52+ switch ( current ) {
53+ // Closing curly brace will be the first character of the brace expansion we encounter.
54+ // Bookmark its index so long as we're not already inside a brace expansion.
55+ case '}' :
56+ if ( ! inside ) {
57+ bookmark = i - 1 ;
58+ inside = true ;
59+ }
60+ break ;
61+ // Opening curly brace will be the last character of the brace expansion we encounter.
62+ // Apply the brace expansion so long as we've already seen a closing curly brace.
63+ case '{' :
64+ if ( inside ) {
65+ let expansion = pattern . slice ( i , bookmark ) . split ( ',' ) ;
66+ // Iterating backward allows us to push new properties w/out affecting our "cursor".
67+ for ( let j = properties . length ; j > 0 ; -- j ) {
68+ // Extract the unexpanded property from the array.
69+ let property = properties . splice ( j - 1 , 1 ) [ 0 ] ;
70+ // Iterate over the expansion, pushing the newly formed properties onto the array.
71+ for ( let k = 0 ; k < expansion . length ; ++ k ) {
72+ properties . push ( property . slice ( 0 , i - 1 ) +
73+ expansion [ k ] +
74+ property . slice ( bookmark + 1 ) ) ;
75+ }
76+ }
77+ inside = false ;
78+ }
79+ break ;
5280 }
5381 }
5482
5583 for ( let i = 0 ; i < properties . length ; i ++ ) {
56- callback ( properties [ i ] . join ( '' ) . replace ( END_WITH_EACH_REGEX , '.[]' ) ) ;
84+ callback ( properties [ i ] . replace ( END_WITH_EACH_REGEX , '.[]' ) ) ;
5785 }
5886}
59-
60- function duplicateAndReplace ( properties , currentParts , index ) {
61- var all = [ ] ;
62-
63- properties . forEach ( ( property ) => {
64- currentParts . forEach ( ( part ) => {
65- var current = property . slice ( 0 ) ;
66- current [ index ] = part ;
67- all . push ( current ) ;
68- } ) ;
69- } ) ;
70-
71- return all ;
72- }
0 commit comments