UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

111 lines (98 loc) 3.16 kB
steal('can/util', 'can/map', 'can/list', 'can/compute', function (can) { can.extend(can.List.prototype, { filter: function (callback, thisArg) { // The filtered list var filtered = new this.constructor(); var self = this; // Creates the binder for a single element at a given index var generator = function (element, index) { // The event handler that updates the filtered list var binder = function (ev, val) { var index = filtered.indexOf(element); // Remove it from the list if it exists but the new value is false if (!val && index !== -1) { filtered.splice(index, 1); } // Add it to the list if it isn't in there and the new value is true if (val && index === -1) { filtered.push(element); } }; // a can.compute that executes the callback var compute = can.compute(function () { return callback.call(thisArg || self, element, self.indexOf(element), self); }); // Update the filtered list on any compute change compute.bind('change', binder); // Call binder explicitly for the initial list binder(null, compute()); }; // We also want to know when something gets added to our original list this.bind('add', function (ev, data, index) { can.each(data, function (element, i) { // Call the generator for each newly added element // The index is the start index + the loop index generator(element, index + i); }); }); // Removed items should be removed from both lists this.bind('remove', function (ev, data, index) { can.each(data, function (element, i) { var index = filtered.indexOf(element); if (index !== -1) { filtered.splice(index, 1); } }); }); // Run the generator for each list element this.forEach(generator); return filtered; }, map: function (callback, thisArg) { var mapped = new can.List(); var self = this; // Again, lets run a generator function var generator = function (element, index) { // The can.compute for the mapping var compute = can.compute(function () { return callback.call(thisArg || self, element, index, self); }); compute.bind('change', function (ev, val) { // On change, replace the current value with the new one mapped.splice(index, 1, val); }); mapped.splice(index, 0, compute()); }; this.forEach(generator); // We also want to know when something gets added to our original list this.bind('add', function (ev, data, index) { can.each(data, function (element, i) { // Call the generator for each newly added element // The index is the start index + the loop index generator(element, index + i); }); }); this.bind('remove', function (ev, data, index) { // The indices in the mapped list are the same so lets just splice it out mapped.splice(index, data.length); }); return mapped; } /* TODO , every : function() { }, some : function(callback) { }, reduce : function() { }, reduceRight : function() { }, max : function() { }, min : function() { } */ }); return can.List; });