1+ /*can-list@3.0.4#can-list*/
2+ define ( function ( require , exports , module ) {
3+ require ( 'can-event' ) ;
4+ var namespace = require ( 'can-namespace' ) ;
5+ var Map = require ( 'can-map' ) ;
6+ var bubble = require ( 'can-map/bubble' ) ;
7+ var mapHelpers = require ( 'can-map/map-helpers' ) ;
8+ var canBatch = require ( 'can-event/batch' ) ;
9+ var canEvent = require ( 'can-event' ) ;
10+ var Observation = require ( 'can-observation' ) ;
11+ var CID = require ( 'can-cid' ) ;
12+ var isPromise = require ( 'can-util/js/is-promise' ) ;
13+ var makeArray = require ( 'can-util/js/make-array' ) ;
14+ var assign = require ( 'can-util/js/assign' ) ;
15+ var types = require ( 'can-types' ) ;
16+ var each = require ( 'can-util/js/each' ) ;
17+ var splice = [ ] . splice , spliceRemovesProps = function ( ) {
18+ var obj = {
19+ 0 : 'a' ,
20+ length : 1
21+ } ;
22+ splice . call ( obj , 0 , 1 ) ;
23+ return ! obj [ 0 ] ;
24+ } ( ) ;
25+ var serializeNonTypes = function ( MapType , arg , args ) {
26+ if ( arg && arg . serialize && ! ( arg instanceof MapType ) ) {
27+ args . push ( new MapType ( arg . serialize ( ) ) ) ;
28+ } else {
29+ args . push ( arg ) ;
30+ }
31+ } ;
32+ var List = Map . extend ( { Map : Map } , {
33+ setup : function ( instances , options ) {
34+ this . length = 0 ;
35+ CID ( this , '.map' ) ;
36+ this . _setupComputedProperties ( ) ;
37+ instances = instances || [ ] ;
38+ var teardownMapping ;
39+ if ( isPromise ( instances ) ) {
40+ this . replace ( instances ) ;
41+ } else {
42+ teardownMapping = instances . length && mapHelpers . addToMap ( instances , this ) ;
43+ this . push . apply ( this , makeArray ( instances || [ ] ) ) ;
44+ }
45+ if ( teardownMapping ) {
46+ teardownMapping ( ) ;
47+ }
48+ assign ( this , options ) ;
49+ } ,
50+ _triggerChange : function ( attr , how , newVal , oldVal ) {
51+ Map . prototype . _triggerChange . apply ( this , arguments ) ;
52+ var index = + attr ;
53+ if ( ! ~ ( '' + attr ) . indexOf ( '.' ) && ! isNaN ( index ) ) {
54+ if ( how === 'add' ) {
55+ canEvent . dispatch . call ( this , how , [
56+ newVal ,
57+ index
58+ ] ) ;
59+ canEvent . dispatch . call ( this , 'length' , [ this . length ] ) ;
60+ } else if ( how === 'remove' ) {
61+ canEvent . dispatch . call ( this , how , [
62+ oldVal ,
63+ index
64+ ] ) ;
65+ canEvent . dispatch . call ( this , 'length' , [ this . length ] ) ;
66+ } else {
67+ canEvent . dispatch . call ( this , how , [
68+ newVal ,
69+ index
70+ ] ) ;
71+ }
72+ }
73+ } ,
74+ ___get : function ( attr ) {
75+ if ( attr ) {
76+ var computedAttr = this . _computedAttrs [ attr ] ;
77+ if ( computedAttr && computedAttr . compute ) {
78+ return computedAttr . compute ( ) ;
79+ }
80+ if ( this [ attr ] && this [ attr ] . isComputed && typeof this . constructor . prototype [ attr ] === 'function' ) {
81+ return this [ attr ] ( ) ;
82+ } else {
83+ return this [ attr ] ;
84+ }
85+ } else {
86+ return this ;
87+ }
88+ } ,
89+ __set : function ( prop , value , current ) {
90+ prop = isNaN ( + prop ) || prop % 1 ? prop : + prop ;
91+ if ( typeof prop === 'number' ) {
92+ if ( prop > this . length - 1 ) {
93+ var newArr = new Array ( prop + 1 - this . length ) ;
94+ newArr [ newArr . length - 1 ] = value ;
95+ this . push . apply ( this , newArr ) ;
96+ return newArr ;
97+ } else {
98+ this . splice ( prop , 1 , value ) ;
99+ return this ;
100+ }
101+ }
102+ return Map . prototype . __set . call ( this , '' + prop , value , current ) ;
103+ } ,
104+ ___set : function ( attr , val ) {
105+ this [ attr ] = val ;
106+ if ( + attr >= this . length ) {
107+ this . length = + attr + 1 ;
108+ }
109+ } ,
110+ __remove : function ( prop , current ) {
111+ if ( isNaN ( + prop ) ) {
112+ delete this [ prop ] ;
113+ this . _triggerChange ( prop , 'remove' , undefined , current ) ;
114+ } else {
115+ this . splice ( prop , 1 ) ;
116+ }
117+ } ,
118+ _each : function ( callback ) {
119+ var data = this . ___get ( ) ;
120+ for ( var i = 0 ; i < data . length ; i ++ ) {
121+ callback ( data [ i ] , i ) ;
122+ }
123+ } ,
124+ serialize : function ( ) {
125+ return mapHelpers . serialize ( this , 'serialize' , [ ] ) ;
126+ } ,
127+ splice : function ( index , howMany ) {
128+ var args = makeArray ( arguments ) , added = [ ] , i , len , listIndex , allSame = args . length > 2 ;
129+ index = index || 0 ;
130+ for ( i = 0 , len = args . length - 2 ; i < len ; i ++ ) {
131+ listIndex = i + 2 ;
132+ args [ listIndex ] = this . __type ( args [ listIndex ] , listIndex ) ;
133+ added . push ( args [ listIndex ] ) ;
134+ if ( this [ i + index ] !== args [ listIndex ] ) {
135+ allSame = false ;
136+ }
137+ }
138+ if ( allSame && this . length <= added . length ) {
139+ return added ;
140+ }
141+ if ( howMany === undefined ) {
142+ howMany = args [ 1 ] = this . length - index ;
143+ }
144+ var removed = splice . apply ( this , args ) ;
145+ if ( ! spliceRemovesProps ) {
146+ for ( i = this . length ; i < removed . length + this . length ; i ++ ) {
147+ delete this [ i ] ;
148+ }
149+ }
150+ canBatch . start ( ) ;
151+ if ( howMany > 0 ) {
152+ bubble . removeMany ( this , removed ) ;
153+ this . _triggerChange ( '' + index , 'remove' , undefined , removed ) ;
154+ }
155+ if ( args . length > 2 ) {
156+ bubble . addMany ( this , added ) ;
157+ this . _triggerChange ( '' + index , 'add' , added , removed ) ;
158+ }
159+ canBatch . stop ( ) ;
160+ return removed ;
161+ } ,
162+ _getAttrs : function ( ) {
163+ return mapHelpers . serialize ( this , 'attr' , [ ] ) ;
164+ } ,
165+ _setAttrs : function ( items , remove ) {
166+ items = makeArray ( items ) ;
167+ canBatch . start ( ) ;
168+ this . _updateAttrs ( items , remove ) ;
169+ canBatch . stop ( ) ;
170+ } ,
171+ _updateAttrs : function ( items , remove ) {
172+ var len = Math . min ( items . length , this . length ) ;
173+ for ( var prop = 0 ; prop < len ; prop ++ ) {
174+ var curVal = this [ prop ] , newVal = items [ prop ] ;
175+ if ( types . isMapLike ( curVal ) && mapHelpers . canMakeObserve ( newVal ) ) {
176+ curVal . attr ( newVal , remove ) ;
177+ } else if ( curVal !== newVal ) {
178+ this . _set ( prop + '' , newVal ) ;
179+ } else {
180+ }
181+ }
182+ if ( items . length > this . length ) {
183+ this . push . apply ( this , items . slice ( this . length ) ) ;
184+ } else if ( items . length < this . length && remove ) {
185+ this . splice ( items . length ) ;
186+ }
187+ }
188+ } ) , getArgs = function ( args ) {
189+ return args [ 0 ] && Array . isArray ( args [ 0 ] ) ? args [ 0 ] : makeArray ( args ) ;
190+ } ;
191+ each ( {
192+ push : 'length' ,
193+ unshift : 0
194+ } , function ( where , name ) {
195+ var orig = [ ] [ name ] ;
196+ List . prototype [ name ] = function ( ) {
197+ var args = [ ] , len = where ? this . length : 0 , i = arguments . length , res , val ;
198+ while ( i -- ) {
199+ val = arguments [ i ] ;
200+ args [ i ] = bubble . set ( this , i , this . __type ( val , i ) ) ;
201+ }
202+ res = orig . apply ( this , args ) ;
203+ if ( ! this . comparator || args . length ) {
204+ this . _triggerChange ( '' + len , 'add' , args , undefined ) ;
205+ }
206+ return res ;
207+ } ;
208+ } ) ;
209+ each ( {
210+ pop : 'length' ,
211+ shift : 0
212+ } , function ( where , name ) {
213+ List . prototype [ name ] = function ( ) {
214+ if ( ! this . length ) {
215+ return undefined ;
216+ }
217+ var args = getArgs ( arguments ) , len = where && this . length ? this . length - 1 : 0 ;
218+ var res = [ ] [ name ] . apply ( this , args ) ;
219+ this . _triggerChange ( '' + len , 'remove' , undefined , [ res ] ) ;
220+ if ( res && res . removeEventListener ) {
221+ bubble . remove ( this , res ) ;
222+ }
223+ return res ;
224+ } ;
225+ } ) ;
226+ assign ( List . prototype , {
227+ indexOf : function ( item , fromIndex ) {
228+ Observation . add ( this , 'length' ) ;
229+ for ( var i = fromIndex || 0 , len = this . length ; i < len ; i ++ ) {
230+ if ( this . attr ( i ) === item ) {
231+ return i ;
232+ }
233+ }
234+ return - 1 ;
235+ } ,
236+ join : function ( ) {
237+ Observation . add ( this , 'length' ) ;
238+ return [ ] . join . apply ( this , arguments ) ;
239+ } ,
240+ reverse : function ( ) {
241+ var list = [ ] . reverse . call ( makeArray ( this ) ) ;
242+ return this . replace ( list ) ;
243+ } ,
244+ slice : function ( ) {
245+ Observation . add ( this , 'length' ) ;
246+ var temp = Array . prototype . slice . apply ( this , arguments ) ;
247+ return new this . constructor ( temp ) ;
248+ } ,
249+ concat : function ( ) {
250+ var args = [ ] , MapType = this . constructor . Map ;
251+ each ( arguments , function ( arg ) {
252+ if ( types . isListLike ( arg ) || Array . isArray ( arg ) ) {
253+ var arr = types . isListLike ( arg ) ? makeArray ( arg ) : arg ;
254+ each ( arr , function ( innerArg ) {
255+ serializeNonTypes ( MapType , innerArg , args ) ;
256+ } ) ;
257+ } else {
258+ serializeNonTypes ( MapType , arg , args ) ;
259+ }
260+ } ) ;
261+ return new this . constructor ( Array . prototype . concat . apply ( makeArray ( this ) , args ) ) ;
262+ } ,
263+ forEach : function ( cb , thisarg ) {
264+ var item ;
265+ for ( var i = 0 , len = this . attr ( 'length' ) ; i < len ; i ++ ) {
266+ item = this . attr ( i ) ;
267+ if ( item !== undefined && cb . call ( thisarg || item , item , i , this ) === false ) {
268+ break ;
269+ }
270+ }
271+ return this ;
272+ } ,
273+ replace : function ( newList ) {
274+ if ( isPromise ( newList ) ) {
275+ if ( this . _promise ) {
276+ this . _promise . __isCurrentPromise = false ;
277+ }
278+ var promise = this . _promise = newList ;
279+ promise . __isCurrentPromise = true ;
280+ var self = this ;
281+ newList . then ( function ( newList ) {
282+ if ( promise . __isCurrentPromise ) {
283+ self . replace ( newList ) ;
284+ }
285+ } ) ;
286+ } else {
287+ this . splice . apply ( this , [
288+ 0 ,
289+ this . length
290+ ] . concat ( makeArray ( newList || [ ] ) ) ) ;
291+ }
292+ return this ;
293+ } ,
294+ filter : function ( callback , thisArg ) {
295+ var filteredList = new this . constructor ( ) , self = this , filtered ;
296+ this . each ( function ( item , index , list ) {
297+ filtered = callback . call ( thisArg || self , item , index , self ) ;
298+ if ( filtered ) {
299+ filteredList . push ( item ) ;
300+ }
301+ } ) ;
302+ return filteredList ;
303+ } ,
304+ map : function ( callback , thisArg ) {
305+ var filteredList = new List ( ) , self = this ;
306+ this . each ( function ( item , index , list ) {
307+ var mapped = callback . call ( thisArg || self , item , index , self ) ;
308+ filteredList . push ( mapped ) ;
309+ } ) ;
310+ return filteredList ;
311+ }
312+ } ) ;
313+ var oldIsListLike = types . isListLike ;
314+ types . isListLike = function ( obj ) {
315+ return obj instanceof List || oldIsListLike . apply ( this , arguments ) ;
316+ } ;
317+ var oldType = Map . prototype . __type ;
318+ Map . prototype . __type = function ( value , prop ) {
319+ if ( typeof value === 'object' && Array . isArray ( value ) ) {
320+ var cached = mapHelpers . getMapFromObject ( value ) ;
321+ if ( cached ) {
322+ return cached ;
323+ }
324+ return new List ( value ) ;
325+ }
326+ return oldType . apply ( this , arguments ) ;
327+ } ;
328+ var oldSetup = Map . setup ;
329+ Map . setup = function ( ) {
330+ oldSetup . apply ( this , arguments ) ;
331+ if ( ! ( this . prototype instanceof List ) ) {
332+ this . List = Map . List . extend ( { Map : this } , { } ) ;
333+ }
334+ } ;
335+ if ( ! types . DefaultList ) {
336+ types . DefaultList = List ;
337+ }
338+ List . prototype . each = List . prototype . forEach ;
339+ Map . List = List ;
340+ module . exports = namespace . List = List ;
341+ } ) ;
0 commit comments