@@ -21,7 +21,85 @@ define([
2121 * @returns {Array }
2222 */
2323 function compact ( container ) {
24- return container . filter ( utils . isObject ) ;
24+ return _ . values ( container ) . filter ( utils . isObject ) ;
25+ }
26+
27+ /**
28+ * Defines index of an item in a specified container.
29+ *
30+ * @param {* } item - Item whose index should be defined.
31+ * @param {Array } container - Container upon which to perform search.
32+ * @returns {Number }
33+ */
34+ function _findIndex ( item , container ) {
35+ var index = _ . findKey ( container , function ( value ) {
36+ return value === item ;
37+ } ) ;
38+
39+ if ( typeof index === 'undefined' ) {
40+ index = _ . findKey ( container , function ( value ) {
41+ return value && value . name === item ;
42+ } ) ;
43+ }
44+
45+ return typeof index === 'undefined' ? - 1 : index ;
46+ }
47+
48+ /**
49+ * Inserts specified item into container at a specified position.
50+ *
51+ * @param {* } item - Item to be inserted into container.
52+ * @param {Array } container - Container of items.
53+ * @param {* } [position=-1] - Position at which item should be inserted.
54+ * Position can represent:
55+ * - specific index in container
56+ * - item which might already be present in container
57+ * - structure with one of these properties: after, before
58+ * @returns {Boolean|* }
59+ * - true if element has changed its' position
60+ * - false if nothing has changed
61+ * - inserted value if it wasn't present in container
62+ */
63+ function _insertAt ( item , container , position ) {
64+ var currentIndex = _findIndex ( item , container ) ,
65+ newIndex ,
66+ target ;
67+
68+ if ( typeof position === 'undefined' ) {
69+ position = - 1 ;
70+ } else if ( typeof position === 'string' ) {
71+ position = isNaN ( + position ) ? position : + position ;
72+ }
73+
74+ newIndex = position ;
75+
76+ if ( ~ currentIndex ) {
77+ target = container . splice ( currentIndex , 1 ) [ 0 ] ;
78+
79+ if ( typeof item === 'string' ) {
80+ item = target ;
81+ }
82+ }
83+
84+ if ( typeof position !== 'number' ) {
85+ target = position . after || position . before || position ;
86+
87+ newIndex = _findIndex ( target , container ) ;
88+
89+ if ( ~ newIndex && ( position . after || newIndex >= currentIndex ) ) {
90+ newIndex ++ ;
91+ }
92+ }
93+
94+ if ( newIndex < 0 ) {
95+ newIndex += container . length + 1 ;
96+ }
97+
98+ container [ newIndex ] ?
99+ container . splice ( newIndex , 0 , item ) :
100+ container [ newIndex ] = item ;
101+
102+ return ! ~ currentIndex ? item : currentIndex !== newIndex ;
25103 }
26104
27105 return Element . extend ( {
@@ -90,8 +168,8 @@ define([
90168
91169 elems . map ( function ( item ) {
92170 return item . elem ?
93- utils . insert ( item . elem , container , item . position ) :
94- utils . insert ( item , container , position ) ;
171+ _insertAt ( item . elem , container , item . position ) :
172+ _insertAt ( item , container , position ) ;
95173 } ) . forEach ( function ( item ) {
96174 if ( item === true ) {
97175 update = true ;
@@ -257,9 +335,11 @@ define([
257335 * @param {Object } elem - Element to insert.
258336 */
259337 _insert : function ( elem ) {
260- var index = this . _elems . indexOf ( elem . name ) ;
338+ var index = _ . findKey ( this . _elems , function ( value ) {
339+ return value === elem . name ;
340+ } ) ;
261341
262- if ( ~ index ) {
342+ if ( typeof index !== 'undefined' ) {
263343 this . _elems [ index ] = elem ;
264344 }
265345
0 commit comments