AUI.add('aui-data-set', function(A) {
var Lang = A.Lang;
var DataSet = function() {
DataSet.superclass.constructor.apply(this, arguments);
};
DataSet.NAME = 'dataset';
DataSet.ATTRS = {
keys: {
getter: function(value) {
var instance = this;
return instance.keys;
}
},
first: {
getter: function() {
var instance = this;
var values = instance.values;
return values[0];
}
},
includeFunctions: {
value: false
},
items: {
value: null,
getter: function() {
var instance = this;
return instance.collection || {};
}
},
last: {
getter: function() {
var instance = this;
var values = instance.values;
return values[values.length - 1];
}
},
getKey: {
lazyAdd: false,
value: null,
getter: function(value) {
var instance = this;
return value || instance.getKey;
},
setter: function(value) {
var instance = this;
if (Lang.isFunction(value)) {
instance.getKey = value;
}
return instance.getKey;
}
},
values: {
getter: function(value) {
var instance = this;
return instance.values;
},
readOnly: true
}
};
A.extend(
DataSet,
A.Base,
{
initializer: function() {
var instance = this;
instance.collection = {};
instance.keys = [];
instance.values = [];
instance.length = 0;
instance.publish(
'add',
{
defaultFn: instance._defaultAddFn
}
);
instance.publish(
'clear',
{
defaultFn: instance._defaultClearFn
}
);
instance.publish(
'remove',
{
defaultFn: instance._defaultRemoveFn
}
);
instance.publish(
'replace',
{
defaultFn: instance._defaultReplaceFn
}
);
instance.publish(
'sort',
{
defaultFn: instance._defaultSortFn
}
);
},
add: function(key, obj) {
var instance = this;
if (arguments.length == 1) {
obj = key;
key = instance.getKey(obj);
}
if (!Lang.isNull(key) && !Lang.isUndefined(key)) {
var prevVal = instance.collection[key];
if (!Lang.isUndefined(prevVal)) {
return instance.replace(key, obj);
}
}
var length = instance.length;
instance.fire(
'add',
{
index: length,
attrName: key,
item: obj,
newVal: obj
}
);
},
addAll: function(obj) {
var instance = this;
var args = arguments;
var length = args.length;
if (length == 1) {
args = obj;
}
if (length > 1 || Lang.isArray(obj)) {
length = args.length;
for (var i = 0; i < length; i++) {
instance.add(args[i]);
}
}
else {
for (var i in obj) {
var item = obj[i];
instance.add(i, item);
}
}
},
clear: function() {
var instance = this;
instance.fire('clear');
},
clone: function() {
var instance = this;
var clone = new DataSet();
var keys = instance.keys;
var values = instance.values;
var length = values.length;
for (var i = 0; i < length; i++) {
clone.add(keys[i], values[i]);
}
clone.set('getKey', instance.get('getKey'));
return clone;
},
contains: function(obj) {
var instance = this;
return instance.indexOf(obj) > -1;
},
containsKey: function(key) {
var instance = this;
return !(Lang.isUndefined(instance.collection[key]));
},
each: function(fn, context) {
var instance = this;
return instance._each(instance.values, fn, context);
},
eachKey: function(fn, context) {
var instance = this;
var keys = instance.keys;
return instance._each(keys, fn, context);
},
filter: function(fn, context) {
var instance = this;
var filtered = new DataSet();
filtered.set('getKey', instance.get('getKey'));
var collection = instance.collection;
var keys = instance.keys;
var values = instance.values;
context = context || instance;
var filteredDataSet = filtered.collection;
var filteredValues = filtered.values;
var length = values.length;
var item;
for (var i = 0; i < length; i++) {
item = values[i];
if (fn.call(context, item, i, collection)) {
filtered.add(keys[i], item);
}
}
filtered.length = filteredValues.length;
return filtered;
},
filterBy: function(key, value, startsWith, caseSensitive) {
var instance = this;
if (Lang.isUndefined(value) ||
Lang.isNull(value) ||
((Lang.isArray(value) ||
Lang.isString(value)) && !value.length)) {
return instance.clone();
}
value = instance._generateRegEx(value, startsWith, caseSensitive);
var keyFilter = A.bind(instance._keyFilter, instance, key, value);
return instance.filter(keyFilter);
},
find: function(fn, context) {
var instance = this;
return A.Array.find(instance.values, fn, context);
},
findIndex: function(fn, context, start) {
var instance = this;
var collection = instance.collection;
var values = instance.values;
var length = instance.length;
start = start || 0;
for (var i = start; i < length; i++) {
if (fn.call(context, values[i], i, collection)) {
return i;
}
}
return -1;
},
findIndexBy: function(key, value, start, startsWith, caseSensitive) {
var instance = this;
if (Lang.isUndefined(value) ||
Lang.isNull(value) ||
((Lang.isArray(value) ||
Lang.isString(value)) && !value.length)) {
return -1;
}
value = instance._generateRegEx(value, startsWith, caseSensitive);
var keyFilter = A.bind(instance._keyFilter, instance, key, value);
return instance.findIndex(keyFilter, null, start);
},
getKey: function(obj) {
var instance = this;
return (obj.get && obj.get('id')) || obj.id;
},
indexOf: function(obj) {
var instance = this;
return A.Array.indexOf(instance.values, obj);
},
indexOfKey: function(key) {
var instance = this;
return A.Array.indexOf(instance.keys, key);
},
insert: function(index, key, obj) {
var instance = this;
if (arguments.length == 2) {
obj = arguments[1];
key = instance.getKey(obj);
}
if (instance.containsKey(key)) {
instance.removeKey(key);
}
instance.fire(
'add',
{
index: index,
attrName: key,
item: obj,
newVal: obj
}
);
},
invoke: function(method, args) {
var instance = this;
var values = instance.values;
var length = values.length;
if (!args) {
args = [];
}
else {
args = [].concat(args);
}
for (var i = 0; i < length; i++) {
var item = values[i];
var itemMethod = item && item[method];
if (Lang.isFunction(itemMethod)) {
itemMethod.apply(item, args);
}
}
return instance;
},
item: function(key) {
var instance = this;
var item;
if (Lang.isNumber(key)) {
var values = instance.values;
item = values[key];
}
else {
item = instance.collection[key];
}
return item;
},
keySort: function(direction, fn) {
var instance = this;
instance.fire(
'sort',
{
direction: direction,
fn: fn || instance._keySorter,
type: 'key'
}
);
},
remove: function(obj) {
var instance = this;
var index = instance.indexOf(obj);
return instance.removeAt(index);
},
removeAt: function(index) {
var instance = this;
if (index < instance.length && index >= 0) {
var obj = instance.values[index];
var key = instance.keys[index];
instance.fire(
'remove',
{
index: index,
attrName: key,
item: obj,
prevVal: obj
}
);
}
},
removeKey: function(key) {
var instance = this;
var index = instance.indexOfKey(key);
return instance.removeAt(index);
},
replace: function(key, obj) {
var instance = this;
if (arguments.length == 1) {
obj = key;
key = instance.getKey(obj);
}
var prevVal = instance.collection[key];
if (Lang.isUndefined(key) || Lang.isNull(key) || Lang.isUndefined(prevVal)) {
return instance.add(key, obj);
}
var index = instance.indexOfKey(key);
instance.fire(
'replace',
{
attrName: key,
index: index,
item: obj,
prevVal: prevVal,
newVal: obj
}
);
},
size: function() {
var instance = this;
return instance.length;
},
slice: function(start, end) {
var instance = this;
var values = instance.values;
return values.slice.apply(values, arguments);
},
sort: function(direction, fn) {
var instance = this;
instance.fire(
'sort',
{
direction: direction,
fn: fn,
type: 'value'
}
);
},
_defaultAddFn: function(event) {
var instance = this;
var key = event.attrName;
var obj = event.item;
var index = event.index;
if (!Lang.isNull(key) && !Lang.isUndefined(key)) {
if (instance.get('includeFunctions') || !Lang.isFunction(obj)) {
instance.collection[key] = obj;
}
}
instance.keys.splice(index, 0, key);
instance.values.splice(index, 0, obj);
++instance.length;
},
_defaultClearFn: function(event) {
var instance = this;
instance.collection = {};
instance.keys = [];
instance.values = [];
instance.length = 0;
},
_defaultRemoveFn: function(event) {
var instance = this;
var index = event.index;
var obj = event.item;
var key = event.attrName;
var collection = instance.collection;
var keys = instance.keys;
instance.values.splice(index, 1);
if (!Lang.isUndefined(key)) {
delete collection[key];
}
keys.splice(index, 1);
instance.length--;
},
_defaultReplaceFn: function(event) {
var instance = this;
var key = event.attrName;
var obj = event.item;
instance.collection[key] = obj;
},
_defaultSortFn: function(event) {
var instance = this;
instance._sortBy(event.type, event.direction, event.fn);
},
_each: function(arr, fn, context) {
var instance = this;
var values = arr.slice(0);
var length = values.length;
context = context || instance;
for (var i = 0; i < length; i++) {
if (fn.call(context, values[i], i, values) === false) {
return false;
}
}
return true;
},
_generateRegEx: function(value, startsWith, caseSensitive) {
var instance = this;
if (!(value instanceof RegExp)) {
value = String(value);
var regExBuffer = [];
if (startsWith !== false) {
regExBuffer.push('^');
}
regExBuffer.push(value);
var options;
if (!caseSensitive) {
options = 'i';
}
value = new RegExp(regExBuffer.join(''), options);
}
return value;
},
_keyFilter: function(key, value, item, index, collection) {
var instance = this;
return item && value.test(item[key]);
},
_keySorter: function(a, b) {
var instance = this;
var keyA = String(a).toLowerCase();
var keyB = String(b).toLowerCase();
var returnValue = 0;
if (keyA > keyB) {
returnValue = 1;
}
else if (keyA < keyB) {
returnValue = -1;
}
return returnValue;
},
_sortBy: function(property, direction, fn) {
var instance = this;
var asc = 1;
var tempValues = [];
var keys = instance.keys;
var values = instance.values;
var length = values.length;
fn = fn || A.Array.numericSort;
if (String(direction).toLowerCase() == 'desc') {
asc = -1;
}
for (var i = 0; i < length; i++) {
tempValues.push(
{
key: keys[i],
value: values[i],
index: i
}
);
}
tempValues.sort(
function(a, b) {
var value = fn(a[property], b[property]) * asc;
if (value === 0) {
value = 1;
if (a.index < b.index) {
value = -1;
}
}
return value;
}
);
length = tempValues.length;
var collection = {};
for (var i = 0; i < length; i++) {
var item = tempValues[i];
var key = item.key;
var value = item.value;
collection[key] = value;
keys[i] = key;
values[i] = value;
}
instance.collection = collection;
}
}
);
A.DataSet = DataSet;
}, '@VERSION@' ,{skinnable:false, requires:['oop','collection','base']});