Skip to content

Commit af20e99

Browse files
committed
3.0.5
1 parent 34ad97f commit af20e99

File tree

2 files changed

+3891
-0
lines changed

2 files changed

+3891
-0
lines changed

dist/amd/can-list.js

Lines changed: 341 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,341 @@
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

Comments
 (0)