2011-11-05 16:46:53 +00:00
|
|
|
'use strict';
|
|
|
|
|
2011-10-07 01:04:47 +00:00
|
|
|
/*@
|
|
|
|
Ox.extend <function> Extends an object with one or more other objects
|
|
|
|
> Ox.extend({a: 1, b: 1, c: 1}, {b: 2, c: 2}, {c: 3})
|
|
|
|
{a: 1, b: 2, c: 3}
|
2012-05-31 10:35:09 +00:00
|
|
|
> Ox.extend({a: 1}, 'b', 2)
|
|
|
|
{a: 1, b: 2}
|
2013-11-29 20:13:04 +00:00
|
|
|
> Ox.extend({a: 1}, 'b')
|
|
|
|
{a: 1, b: void 0}
|
2011-10-07 01:04:47 +00:00
|
|
|
@*/
|
2012-05-25 12:32:17 +00:00
|
|
|
Ox.extend = function(object) {
|
2012-05-31 10:35:09 +00:00
|
|
|
var args = Ox.slice(arguments, 1);
|
2013-11-29 20:13:04 +00:00
|
|
|
if (!Ox.isObject(args[0])) {
|
2012-05-31 10:35:09 +00:00
|
|
|
args = [Ox.makeObject(args)];
|
|
|
|
}
|
2013-11-29 20:13:04 +00:00
|
|
|
Ox.forEach(args, function(arg, i) {
|
|
|
|
Ox.forEach(arg, function(value, key) {
|
2012-05-25 12:32:17 +00:00
|
|
|
object[key] = value;
|
2011-10-07 01:04:47 +00:00
|
|
|
});
|
|
|
|
});
|
2012-05-25 12:32:17 +00:00
|
|
|
return object;
|
2011-10-07 01:04:47 +00:00
|
|
|
};
|
|
|
|
|
2012-05-25 07:32:11 +00:00
|
|
|
/*@
|
|
|
|
Ox.getset <f> Generic getter and setter function
|
|
|
|
See examples for details.
|
|
|
|
# Usage --------------------------------------------------------------------
|
2012-06-02 10:36:25 +00:00
|
|
|
(options, args=[]) -> <o> all options
|
|
|
|
(options, args=[key]) -> <*> options[key]
|
|
|
|
(options, args=[key, value], callback, that) -> <o> that
|
2012-05-25 07:32:11 +00:00
|
|
|
sets options[key] to value and calls fn(key, value)
|
|
|
|
if the key/value pair was added or modified
|
2012-06-02 10:36:25 +00:00
|
|
|
(options, args=[{key: value}], callback, that) -> <o> that
|
2012-05-25 07:32:11 +00:00
|
|
|
sets multiple options and calls fn(key, value)
|
|
|
|
for every key/value pair that was added or modified
|
|
|
|
# Arguments ----------------------------------------------------------------
|
|
|
|
options <obj> Options object (key/value pairs)
|
|
|
|
args <arr> The arguments "array" of the caller function
|
|
|
|
callback <fun> Callback function
|
|
|
|
The callback is called for every key/value pair that was added or
|
|
|
|
modified.
|
|
|
|
key <s> Key
|
|
|
|
value <*> Value
|
|
|
|
that <obj> The this object of the caller function (for chaining)
|
|
|
|
# Examples -----------------------------------------------------------------
|
|
|
|
<script>
|
|
|
|
Ox.test.object = new function() {
|
|
|
|
var options = {},
|
|
|
|
setOption = function(key, value) {
|
|
|
|
// handle added or modified options
|
|
|
|
},
|
|
|
|
that = this;
|
|
|
|
that.options = function() {
|
|
|
|
return Ox.getset(options, arguments, setOption, that);
|
|
|
|
};
|
|
|
|
return that;
|
|
|
|
};
|
|
|
|
</script>
|
|
|
|
> Ox.test.object.options("key", "val").options("key")
|
|
|
|
"val"
|
|
|
|
> Ox.test.object.options({foo: "foo", bar: "bar"}).options()
|
|
|
|
{"key": "val", "foo": "foo", "bar": "bar"}
|
|
|
|
@*/
|
|
|
|
Ox.getset = function(object, args, callback, that) {
|
|
|
|
var object_ = Ox.clone(object), ret;
|
|
|
|
if (args.length == 0) {
|
|
|
|
// []
|
|
|
|
ret = object_;
|
|
|
|
} else if (args.length == 1 && !Ox.isObject(args[0])) {
|
|
|
|
// [key]
|
|
|
|
ret = Ox.clone(object[args[0]]);
|
|
|
|
} else {
|
|
|
|
// [key, val] or [{key: val, ...}]
|
|
|
|
args = Ox.makeObject(args);
|
|
|
|
object = Ox.extend(object, args);
|
|
|
|
Ox.forEach(args, function(value, key) {
|
|
|
|
if (!object_ || !Ox.isEqual(object_[key], value)) {
|
|
|
|
callback && callback(key, value);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
ret = that;
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
|
2012-05-25 12:32:17 +00:00
|
|
|
Ox.hasOwn = function(object, value) {
|
|
|
|
return Object.prototype.hasOwnProperty.call(object, value)
|
2012-05-19 09:39:25 +00:00
|
|
|
};
|
|
|
|
|
2011-10-27 18:50:23 +00:00
|
|
|
/*@
|
2012-01-04 07:42:48 +00:00
|
|
|
Ox.keyOf <f> Equivalent of [].indexOf for objects
|
|
|
|
> Ox.keyOf({a: 1, b: 2, c: 3}, 1)
|
|
|
|
'a'
|
2011-10-27 18:50:23 +00:00
|
|
|
@*/
|
2012-05-25 12:32:17 +00:00
|
|
|
Ox.keyOf = function(object, value) {
|
2011-10-27 18:50:23 +00:00
|
|
|
var key;
|
2012-05-25 12:32:17 +00:00
|
|
|
Ox.forEach(object, function(v, k) {
|
|
|
|
if (v === value) {
|
2011-10-27 18:50:23 +00:00
|
|
|
key = k;
|
2012-07-05 08:58:08 +00:00
|
|
|
return false; // break
|
2011-10-27 18:50:23 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
return key;
|
|
|
|
};
|
|
|
|
|
2012-05-25 07:32:11 +00:00
|
|
|
/*@
|
|
|
|
Ox.makeObject <f> Takes an array and returns an object
|
2012-06-02 11:06:44 +00:00
|
|
|
`Ox.makeObject` is a helper for functions with two alternative signatures
|
|
|
|
like `('key', 'val')` and `({key: 'val'})`.
|
2012-05-25 07:32:11 +00:00
|
|
|
> (function() { return Ox.makeObject(arguments); }({foo: 1, bar: 2}))
|
|
|
|
{foo: 1, bar: 2}
|
|
|
|
> (function() { return Ox.makeObject(arguments); }('foo', 1))
|
|
|
|
{foo: 1}
|
|
|
|
> (function() { return Ox.makeObject(arguments); }('foo'))
|
|
|
|
{foo: void 0}
|
|
|
|
> (function() { return Ox.makeObject(arguments); }())
|
|
|
|
{}
|
|
|
|
@*/
|
|
|
|
Ox.makeObject = function(array) {
|
|
|
|
var ret = {};
|
|
|
|
if (Ox.isObject(array[0])) {
|
2013-11-29 20:13:04 +00:00
|
|
|
// [{foo: 'bar'}]
|
2012-05-25 07:32:11 +00:00
|
|
|
ret = array[0];
|
|
|
|
} else if (array.length) {
|
2013-11-29 20:13:04 +00:00
|
|
|
// ['foo', 'bar']
|
2012-05-25 07:32:11 +00:00
|
|
|
ret[array[0]] = array[1];
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
};
|
|
|
|
|
2012-01-07 07:20:02 +00:00
|
|
|
/*@
|
|
|
|
Ox.methods <f> Returns a sorted list of all method names of an object
|
|
|
|
> Ox.methods({a: [], b: false, f: function() {}, n: 0, o: {}, s: ''})
|
|
|
|
['f']
|
|
|
|
@*/
|
2012-05-25 12:32:17 +00:00
|
|
|
Ox.methods = function(object, includePrototype) {
|
2012-05-21 20:04:22 +00:00
|
|
|
var key, keys;
|
|
|
|
if (includePrototype) {
|
|
|
|
keys = [];
|
2012-05-25 12:32:17 +00:00
|
|
|
for (var key in object) {
|
2012-05-21 20:04:22 +00:00
|
|
|
keys.push(key);
|
|
|
|
}
|
|
|
|
} else {
|
2012-05-25 12:32:17 +00:00
|
|
|
keys = Object.keys(object);
|
2012-05-21 20:04:22 +00:00
|
|
|
}
|
|
|
|
return keys.filter(function(key) {
|
2012-05-25 12:32:17 +00:00
|
|
|
return Ox.isFunction(object[key]);
|
2012-01-07 07:20:02 +00:00
|
|
|
}).sort();
|
|
|
|
};
|
|
|
|
|
2011-10-07 01:04:47 +00:00
|
|
|
/*@
|
|
|
|
Ox.serialize <f> Parses an object into query parameters
|
2013-02-18 06:08:31 +00:00
|
|
|
> Ox.serialize({a: 1, b: 2.3, c: -4})
|
|
|
|
'a=1&b=2.3&c=-4'
|
|
|
|
> Ox.serialize({a: [], n: null, o: {}, s: '', u: void 0})
|
|
|
|
''
|
|
|
|
> Ox.serialize({a: [1, 2], b: true, n: 1, o: {k: 'v'}, s: 'foo'}, true)
|
|
|
|
'a=[1,2]&b=true&n=1&o={"k":"v"}&s="foo"'
|
2011-10-07 01:04:47 +00:00
|
|
|
@*/
|
2013-02-18 06:08:31 +00:00
|
|
|
Ox.serialize = function(object, isJSON) {
|
2012-05-25 12:32:17 +00:00
|
|
|
var ret = [];
|
|
|
|
Ox.forEach(object, function(value, key) {
|
2013-02-18 06:08:31 +00:00
|
|
|
var value;
|
|
|
|
if (isJSON) {
|
|
|
|
try {
|
|
|
|
value = JSON.stringify(value);
|
|
|
|
} catch(e) {}
|
|
|
|
}
|
2012-05-25 12:32:17 +00:00
|
|
|
if (!Ox.isEmpty(value) && !Ox.isNull(value) && !Ox.isUndefined(value)) {
|
|
|
|
ret.push(key + '=' + value);
|
2011-10-07 01:04:47 +00:00
|
|
|
}
|
|
|
|
});
|
2012-05-25 12:32:17 +00:00
|
|
|
return ret.join('&');
|
2011-10-07 01:04:47 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/*@
|
|
|
|
Ox.unserialize <f> Parses query parameters into an object
|
2013-02-18 06:08:31 +00:00
|
|
|
> Ox.unserialize('a=1&b=2.3&c=-4')
|
|
|
|
{a: '1', b: '2.3', c: '-4'}
|
|
|
|
> Ox.unserialize('a=foo&b=&c&a=bar')
|
|
|
|
{a: 'bar'}
|
2013-02-18 07:13:59 +00:00
|
|
|
> Ox.unserialize('a=[1,2]&b=true&n=1.2&o={"k":"v"}&s1="foo"&s2=bar', true)
|
|
|
|
{a: [1, 2], b: true, n: 1.2, o: {k: 'v'}, s1: 'foo', s2: 'bar'}
|
2013-02-18 06:08:31 +00:00
|
|
|
|
2011-10-07 01:04:47 +00:00
|
|
|
@*/
|
2013-02-18 06:08:31 +00:00
|
|
|
Ox.unserialize = function(string, isJSON) {
|
2012-05-25 12:32:17 +00:00
|
|
|
var ret = {};
|
|
|
|
Ox.filter(string.split('&')).forEach(function(value) {
|
|
|
|
var array = value.split('=');
|
|
|
|
if (array[1]) {
|
2013-02-18 06:08:31 +00:00
|
|
|
if (isJSON) {
|
|
|
|
try {
|
|
|
|
ret[array[0]] = JSON.parse(array[1]);
|
|
|
|
} catch(e) {
|
|
|
|
ret[array[0]] = array[1];
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret[array[0]] = array[1];
|
|
|
|
}
|
2011-10-07 01:04:47 +00:00
|
|
|
}
|
|
|
|
});
|
2012-05-25 12:32:17 +00:00
|
|
|
return ret;
|
2012-05-25 16:28:05 +00:00
|
|
|
};
|
2014-08-18 17:09:41 +00:00
|
|
|
|
|
|
|
/*@
|
|
|
|
Ox.zipObject <f> Takes a keys and a values array, returns a new object
|
|
|
|
> Ox.zipObject(['a', 'b'], [1, 2])
|
|
|
|
{a: 1, b: 2}
|
|
|
|
@*/
|
|
|
|
Ox.zipObject = function(keys, values) {
|
|
|
|
var object = {};
|
|
|
|
keys.forEach(function(key, index) {
|
|
|
|
object[key] = values[index];
|
|
|
|
});
|
|
|
|
return object;
|
|
|
|
};
|