1,3 → 1,4 |
"use strict"; |
/** |
* @fileOverview <title>Basic Object Library</title> |
* @file $Id$ |
177,6 → 178,8 |
* @namespace |
*/ |
jsx.object = (/** @constructor */ function () { |
var _MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; |
|
var |
rxUnknown = /^unknown$/, |
rxMethod = /^(function|object)$/; |
574,16 → 577,23 |
*/ |
var _COPY_INHERIT = 4; |
|
function _createTypedObject (oOriginal) |
function _getProto (o) |
{ |
if (oOriginal.constructor) |
if (typeof Object.getPrototypeOf == "function" |
&& !Object.getPrototypeOf._emulated) |
{ |
return _inheritFrom(oOriginal.constructor.prototype); |
return Object.getPrototypeOf(o); |
} |
|
return new Object(); |
return o.__proto__ || (o.constructor && o.constructor.prototype); |
} |
|
function _createTypedObject (oOriginal) |
{ |
var prototype = _getProto(oOriginal); |
return (prototype ? _inheritFrom(prototype) : _inheritFrom()); |
} |
|
/** |
* Creates a duplicate (clone) of an object |
* |
634,7 → 644,7 |
|
for (var p in oSource) |
{ |
if (_hasOwnProperty(oSource, i)) |
if (_hasOwnProperty(oSource, p)) |
{ |
if (iLevel && _isObject(oSource[p])) |
{ |
1127,6 → 1137,118 |
clone: _clone, |
|
/** |
* Exchanges an objects keys and their values and returns |
* the new object. |
* |
* @param {Object} obj |
* The object to be flipped. |
* @param {boolean} bAccumulate (optional) |
* If <code>true</code> and different keys have the same |
* value, the key-values are accumulated in an {@link Array} |
* (a {@link jsx.array.BigArray} if possible) in the resulting |
* object. Otherwise key-values will be overwritten, so that |
* the value-key has the last matching key as its value. |
* @param {Function} flipper (optional) |
* Function that should be called to determine whether |
* the property should be flipped. Is passed the key as |
* argument and the object as <code>this</code> value. |
* The property is flipped only if <var>flipper</var> |
* returns a true-value. |
* @return {Object} |
* A new object (a {@link jsx.map.Map} if possible) with |
* the original object's keys and values exchanged. |
*/ |
flip: function (obj, bAccumulate, flipper) { |
if (flipper && typeof flipper != "function") |
{ |
return jsx.throwThis(jsx.InvalidArgumentError, |
["", typeof flipper, "Function"]); |
} |
|
var _Map = _getFeature(jsx, "map", "Map"); |
var flipped = _Map ? new _Map() : _createTypedObject(obj); |
var keys = _getKeys(obj); |
var _BigArray = _getFeature(jsx, "array", "BigArray"); |
var _Array = _BigArray || Array; |
|
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
var key = keys[i]; |
|
if (flipper && !flipper.call(obj, key)) |
{ |
continue; |
} |
|
var value = obj[key]; |
|
var value_is_object = _isObject(value); |
if (value_is_object && !_Map) |
{ |
jsx.warn("Information loss because value is an object." |
+ " Load jsx.map.Map to avoid."); |
} |
|
var has_value_key = _Map |
? flipped.hasKey(value) |
: _hasOwnProperty(flipped, value); |
|
var key_value = _Map |
? flipped.get(value) |
: flipped[value]; |
|
if (has_value_key && bAccumulate) |
{ |
if (!_isArray(key_value)) |
{ |
var a = new _Array(); |
a.push(key_value); |
|
if (_Map) |
{ |
flipped.put(value, a); |
} |
else |
{ |
flipped[value] = a; |
} |
} |
|
if (flipped.length == _MAX_ARRAY_LENGTH && !_BigArray) |
{ |
jsx.warn("Possible information loss due to Array limits." |
+ " Provide jsx.array.BigArray to avoid."); |
} |
|
key_value = _Map |
? flipped.get(value) |
: flipped[value]; |
|
key_value.push(key); |
} |
else |
{ |
if (has_value_key) |
{ |
jsx.warn("Information loss due to same value." |
+ " Pass bAccumulate === true to avoid."); |
} |
|
if (_Map) |
{ |
flipped.put(value, key); |
} |
else |
{ |
flipped[value] = key; |
} |
} |
} |
|
return flipped; |
}, |
|
/** |
* @deprecated in favor of {@link #extend} |
*/ |
setProperties: _extend, |
1347,7 → 1469,7 |
* |
* Returns a reference to a new object that, if supported, |
* does not inherit or have any properties other than those |
* provided by the keys of <var>source</var>. This is |
* provided by the keys of <var>oSource</var>. This is |
* accomplished by either cutting off its existing prototype |
* chain or not creating one for it in the first place. |
* |
1355,7 → 1477,7 |
* <var>oSource</var> are created with the attributes |
* <code>[[Writable]]</code>, <code>[[Enumerable]]</code> |
* and <code>[[Configurable]]</code>. Attributes of the |
* properties of <var>oSource</var> are _not_ copied. |
* properties of <var>oSource</var> are <em>not</em> copied. |
* Property values of the resulting object are a shallow copy |
* of the property values of <var>oSource</var> unless |
* specified otherwise with <var>iFlags</var>. |
1362,6 → 1484,7 |
* |
* @param {Object} oSource (optional) |
* @param {Number} iFlags (optional) |
* See {@link #clone()}. |
* @return {Object} |
* @see Object.create() |
* @see jsx.object.clone() |
1374,8 → 1497,13 |
for (var i = 0, keys = _getKeys(oSource), len = keys.length; |
i < len; ++i) |
{ |
var property_name = oSource[keys[i]]; |
obj[property_name] = _clone(oSource[property_name], iFlags); |
var name = keys[i]; |
var value = oSource[name]; |
|
/* NOTE: formerly, numeric flags was first argument of _clone() */ |
obj[name] = (typeof value != "number" |
? _clone(value, iFlags) |
: value); |
} |
} |
|
1424,20 → 1552,6 |
* with <var>Constructor</var>, <code>false</code> otherwise. |
*/ |
isInstanceOf: function jsx_object_isInstanceOf (obj, Constructor) { |
var _hasGetPrototypeOf; |
|
function _getProto (o) |
{ |
if (typeof _hasGetPrototypeOf == "undefined") |
{ |
_hasGetPrototypeOf = (typeof Object.getPrototypeOf == "function"); |
} |
|
return (_hasGetPrototypeOf |
? Object.getPrototypeOf(o) |
: o.__proto__); |
} |
|
if (!_isObject(obj)) |
{ |
return false; |
2121,7 → 2235,7 |
|
var result = ''; |
|
if (typeof arguments.caller != 'undefined') |
if (jsx.object.hasOwnProperty(arguments, "caller") && arguments.caller) |
{ |
/* JScript and older JavaScript */ |
for (var a = arguments.caller; a != null; a = a.caller) |
2474,7 → 2588,7 |
* @param {string|Array} dependencies |
* URI-reference or <code>Array</code> of URI-references |
* specifying the dependency/dependencies |
* @param {Function} callback |
* @param {Function} callback (optional) |
* Function to be executed |
* @return {any} |
* The return value of <var>callback</var>, |
2496,7 → 2610,19 |
if (typeof _addEventListener == "undefined") |
{ |
_addEventListener = _getFeature(jsx, ["dom", "addEventListener"]); |
|
if (!_addEventListener) |
{ |
/* no wrapper, try W3C DOM directly */ |
_addEventListener = function (target, eventType, listener) { |
return jsx.tryThis( |
function () { |
target.addEventListener(eventType, listener, false); |
return listener; |
}); |
}; |
} |
} |
|
if (_addEventListener) |
{ |
2507,9 → 2633,14 |
if (dependencies.length == 0) |
{ |
/* All dependencies loaded successfully */ |
if (typeof callback == "function") |
{ |
return callback(); |
} |
|
return true; |
} |
|
jsx_require(dependencies, callback); |
}); |
} |
3437,7 → 3568,7 |
return ( |
(_class == "Array" |
? "[" + value.map(jsx_debugValue).join(", ") + "]" |
: (jsx.object.isInstanceOf(value, String) |
: (jsx.object.isString(value) |
? '"' + value.replace(/["\\]/g, "\\$&") + '"' |
: value)) |
+ " : " |