1,4 → 1,3 |
"use strict"; |
/** |
* @fileOverview <title>Basic Object Library</title> |
* @file $Id$ |
174,1681 → 173,1685 |
}; |
//}()); |
|
/** |
* @namespace |
*/ |
jsx.object = (/** @constructor */ function () { |
var _MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; |
(function () { |
"use strict"; |
|
var |
rxUnknown = /^unknown$/, |
rxMethod = /^(function|object)$/; |
|
/** |
* Determines whether an object is, or several objects are, |
* likely to be callable. |
* |
* @author (C) 2003-2010 <a href="mailto:js@PointedEars.de">Thomas Lahn</a> |
* @param {Object} obj |
* Object which should be tested for a method, or checked |
* for being a method if no further arguments are provided. |
* <p> |
* <em>NOTE: If you pass a primitive value for this argument, |
* the properties of the object created from that value are considered. |
* In particular, if you pass a string value containing |
* a <i>MemberExpression</i>, the properties of the corresponding |
* <code>String</code> instance are considered, not of the object that |
* the <i>MemberExpression</i> might refer to. If you need to use such |
* a string to refer to an object (e.g., if you do not know whether it |
* is safe to refer to the object), use the return value of |
* {@link jsx#tryThis jsx.tryThis("<var>MemberExpression</var>")} |
* as argument to this method instead.</em> |
* </p> |
* @param {string|Array} prop (optional) |
* Path of the property to be determined a method, i.e. a reference to |
* a callable object assigned as property of another object. |
* Use a string argument for each component of the path, e.g. |
* the argument list <code>(o, "foo", "bar")</code> for testing whether |
* <code>o.foo.bar</code> is a method. |
* If the last argument is an {@link Array}, all elements of |
* this array are used for property names; e.g. |
* <code>(o, "foo", ["bar", "baz"])</code>. This allows for testing |
* several properties of the same object with one call. |
* @return {boolean} |
* <code>true</code> if all arguments refer to methods, |
* <code>false</code> otherwise. |
* @namespace |
*/ |
function _isMethod (obj, prop) |
{ |
var len = arguments.length; |
if (len < 1) |
{ |
jsx.throwThis("jsx.InvalidArgumentError", |
["Not enough arguments", "saw 0", "(obj : Object[, prop : string])"]); |
return false; |
} |
jsx.object = (/** @constructor */ function () { |
var _MAX_ARRAY_LENGTH = Math.pow(2, 32) - 1; |
|
/* |
* Determine if we were apply'd by jsx.object.isNativeMethod; |
var |
rxUnknown = /^unknown$/, |
rxMethod = /^(function|object)$/; |
|
/** |
* Determines whether an object is, or several objects are, |
* likely to be callable. |
* |
* @author (C) 2003-2010 <a href="mailto:js@PointedEars.de">Thomas Lahn</a> |
* @param {Object} obj |
* Object which should be tested for a method, or checked |
* for being a method if no further arguments are provided. |
* <p> |
* <em>NOTE: If you pass a primitive value for this argument, |
* the properties of the object created from that value are considered. |
* In particular, if you pass a string value containing |
* a <i>MemberExpression</i>, the properties of the corresponding |
* <code>String</code> instance are considered, not of the object that |
* the <i>MemberExpression</i> might refer to. If you need to use such |
* a string to refer to an object (e.g., if you do not know whether it |
* is safe to refer to the object), use the return value of |
* {@link jsx#tryThis jsx.tryThis("<var>MemberExpression</var>")} |
* as argument to this method instead.</em> |
* </p> |
* @param {string|Array} prop (optional) |
* Path of the property to be determined a method, i.e. a reference to |
* a callable object assigned as property of another object. |
* Use a string argument for each component of the path, e.g. |
* the argument list <code>(o, "foo", "bar")</code> for testing whether |
* <code>o.foo.bar</code> is a method. |
* If the last argument is an {@link Array}, all elements of |
* this array are used for property names; e.g. |
* <code>(o, "foo", ["bar", "baz"])</code>. This allows for testing |
* several properties of the same object with one call. |
* @return {boolean} |
* <code>true</code> if all arguments refer to methods, |
* <code>false</code> otherwise. |
*/ |
var checkNative = (this == _isNativeMethod); |
|
var t = typeof obj; |
|
/* When no property names are provided, test if the first argument is a method */ |
if (len < 2) |
function _isMethod (obj, prop) |
{ |
if (checkNative) |
var len = arguments.length; |
if (len < 1) |
{ |
return t == "function" && obj && true || false; |
jsx.throwThis("jsx.InvalidArgumentError", |
["Not enough arguments", "saw 0", "(obj : Object[, prop : string])"]); |
return false; |
} |
|
return rxUnknown.test(t) || rxMethod.test(t) && obj && true || false; |
} |
/* |
* Determine if we were apply'd by jsx.object.isNativeMethod; |
*/ |
var checkNative = (this == _isNativeMethod); |
|
/* otherwise the first argument must refer to a suitable object */ |
/* FIXME: Does not recognize the zero-length string as convertible */ |
if (rxUnknown.test(t) || !obj) |
{ |
return false; |
} |
var t = typeof obj; |
|
for (var i = 1; i < len; i++) |
{ |
prop = arguments[i]; |
/* When no property names are provided, test if the first argument is a method */ |
if (len < 2) |
{ |
if (checkNative) |
{ |
return t == "function" && obj && true || false; |
} |
|
/* NOTE: Handle null _and_ undefined */ |
if (prop == null) |
return rxUnknown.test(t) || rxMethod.test(t) && obj && true || false; |
} |
|
/* otherwise the first argument must refer to a suitable object */ |
/* FIXME: Does not recognize the zero-length string as convertible */ |
if (rxUnknown.test(t) || !obj) |
{ |
return false; |
} |
|
var isLastSeg = (i == len - 1); |
if (isLastSeg) |
for (var i = 1; i < len; i++) |
{ |
if (typeof prop.valueOf() == "string") |
prop = arguments[i]; |
|
/* NOTE: Handle null _and_ undefined */ |
if (prop == null) |
{ |
prop = [prop]; |
return false; |
} |
|
var aProp = prop; |
} |
|
for (var j = (isLastSeg && aProp.length || 1); j--;) |
{ |
var isLastSeg = (i == len - 1); |
if (isLastSeg) |
{ |
prop = aProp[j]; |
if (typeof prop.valueOf() == "string") |
{ |
prop = [prop]; |
} |
|
var aProp = prop; |
} |
|
t = typeof obj[prop]; |
|
/* |
* NOTE: Test for "unknown" required in any case; |
* this order speeds up evaluation |
*/ |
if (rxUnknown.test(t) || (rxMethod.test(t) && obj[prop])) |
for (var j = (isLastSeg && aProp.length || 1); j--;) |
{ |
if (i < len - 1) |
if (isLastSeg) |
{ |
obj = obj[prop]; |
if (!(rxUnknown.test(typeof obj) || obj)) |
prop = aProp[j]; |
} |
|
t = typeof obj[prop]; |
|
/* |
* NOTE: Test for "unknown" required in any case; |
* this order speeds up evaluation |
*/ |
if (rxUnknown.test(t) || (rxMethod.test(t) && obj[prop])) |
{ |
if (i < len - 1) |
{ |
obj = obj[prop]; |
if (!(rxUnknown.test(typeof obj) || obj)) |
{ |
return false; |
} |
} |
else if (checkNative && t != "function") |
{ |
return false; |
} |
} |
else if (checkNative && t != "function") |
else |
{ |
return false; |
} |
} |
else |
{ |
return false; |
} |
} |
|
return true; |
} |
|
return true; |
} |
|
/** |
* Determines whether an object is, or several objects are, |
* likely to be a native method. |
* |
* @author (C) 2011 <a href="mailto:js@PointedEars.de">Thomas Lahn</a> |
* @param {Object} obj |
* Object which should be tested for a method, or checked |
* for being a method if no further arguments are provided. |
* <p> |
* <em>NOTE: If you pass a primitive value for this argument, |
* the properties of the object created from that value are considered. |
* In particular, if you pass a string value containing |
* a <i>MemberExpression</i>, the properties of the corresponding |
* <code>String</code> instance are considered, not of the object that |
* the <i>MemberExpression</i> might refer to. If you need to use such |
* a string to refer to an object (e.g., if you do not know whether it |
* is safe to refer to the object), use the return value of |
* {@link jsx#tryThis jsx.tryThis("<var>MemberExpression</var>")} |
* as argument to this method instead.</em> |
* </p> |
* @param {string|Array} prop (optional) |
* Path of the property to be determined a method, i.e. a reference to |
* a callable object assigned as property of another object. |
* Use a string argument for each component of the path, e.g. |
* the argument list <code>(o, "foo", "bar")</code> for testing whether |
* <code>o.foo.bar</code> is a method. |
* If the last argument is an {@link Array}, all elements of |
* this array are used for property names; e.g. |
* <code>(o, "foo", ["bar", "baz"])</code>. This allows for testing |
* several properties of the same object with one call. |
* @return {boolean} |
* <code>true</code> if all arguments refer to methods, |
* <code>false</code> otherwise. |
*/ |
function _isNativeMethod (obj, prop) |
{ |
/* NOTE: Thread-safe, argument-safe code reuse -- `this' is our ID */ |
return _isMethod.apply(_isNativeMethod, arguments); |
} |
|
/** |
* Determines if an object has a (non-inherited) property. |
* |
* @param {Object} obj (optional) |
* Object which property should be checked for existence. |
* @param {string} sProperty |
* Name of the property to check. |
* @return {boolean} |
* <code>true</code> if there is such a property; |
* <code>false</code> otherwise. |
*/ |
function _hasOwnProperty (obj, sProperty) |
{ |
if (arguments.length < 2 && obj) |
/** |
* Determines whether an object is, or several objects are, |
* likely to be a native method. |
* |
* @author (C) 2011 <a href="mailto:js@PointedEars.de">Thomas Lahn</a> |
* @param {Object} obj |
* Object which should be tested for a method, or checked |
* for being a method if no further arguments are provided. |
* <p> |
* <em>NOTE: If you pass a primitive value for this argument, |
* the properties of the object created from that value are considered. |
* In particular, if you pass a string value containing |
* a <i>MemberExpression</i>, the properties of the corresponding |
* <code>String</code> instance are considered, not of the object that |
* the <i>MemberExpression</i> might refer to. If you need to use such |
* a string to refer to an object (e.g., if you do not know whether it |
* is safe to refer to the object), use the return value of |
* {@link jsx#tryThis jsx.tryThis("<var>MemberExpression</var>")} |
* as argument to this method instead.</em> |
* </p> |
* @param {string|Array} prop (optional) |
* Path of the property to be determined a method, i.e. a reference to |
* a callable object assigned as property of another object. |
* Use a string argument for each component of the path, e.g. |
* the argument list <code>(o, "foo", "bar")</code> for testing whether |
* <code>o.foo.bar</code> is a method. |
* If the last argument is an {@link Array}, all elements of |
* this array are used for property names; e.g. |
* <code>(o, "foo", ["bar", "baz"])</code>. This allows for testing |
* several properties of the same object with one call. |
* @return {boolean} |
* <code>true</code> if all arguments refer to methods, |
* <code>false</code> otherwise. |
*/ |
function _isNativeMethod (obj, prop) |
{ |
sProperty = obj; |
obj = jsx_object; |
/* NOTE: Thread-safe, argument-safe code reuse -- `this' is our ID */ |
return _isMethod.apply(_isNativeMethod, arguments); |
} |
|
var proto; |
/** |
* Determines if an object has a (non-inherited) property. |
* |
* @param {Object} obj (optional) |
* Object which property should be checked for existence. |
* @param {string} sProperty |
* Name of the property to check. |
* @return {boolean} |
* <code>true</code> if there is such a property; |
* <code>false</code> otherwise. |
*/ |
function _hasOwnProperty (obj, sProperty) |
{ |
if (arguments.length < 2 && obj) |
{ |
sProperty = obj; |
obj = jsx_object; |
} |
|
return (_isMethod(obj, "hasOwnProperty") |
? obj.hasOwnProperty(sProperty) |
: (typeof obj[sProperty] != "undefined" |
&& (null == obj.constructor |
|| ((proto = obj.constructor.prototype) |
&& typeof proto[sProperty] == "undefined")))); |
} |
var proto; |
|
/** |
* Determines if a value refers to an object. |
* |
* <p>Returns <code>true</code> if the value is a reference |
* to an object; <code>false</code> otherwise.</p> |
* |
* <p>A value "is an object" if it is a function, |
* <code>typeof "object"</code> or a host object |
* (not a primitive value), but not <code>null</code>. |
* |
* @return {boolean} |
*/ |
function _isObject (a) |
{ |
var t = typeof a; |
return (_isMethod(obj, "hasOwnProperty") |
? obj.hasOwnProperty(sProperty) |
: (typeof obj[sProperty] != "undefined" |
&& (null == obj.constructor |
|| ((proto = obj.constructor.prototype) |
&& typeof proto[sProperty] == "undefined")))); |
} |
|
return t == "function" |
|| (t == "object" |
|| (t != "undefined" && t != "boolean" |
&& t != "number" && t != "string") |
&& a !== null); |
} |
|
/** |
* Returns the own enumerable properties of an object |
* |
* @param {Object} obj |
* Object from which to get the keys |
* @return {Array} |
* Own enumerable properties of <var>obj</var> |
* @see Object#keys |
*/ |
function _getKeys (obj) |
{ |
if (typeof Object.keys == "function" && !Object.keys._emulated) |
/** |
* Determines if a value refers to an object. |
* |
* <p>Returns <code>true</code> if the value is a reference |
* to an object; <code>false</code> otherwise.</p> |
* |
* <p>A value "is an object" if it is a function, |
* <code>typeof "object"</code> or a host object |
* (not a primitive value), but not <code>null</code>. |
* |
* @return {boolean} |
*/ |
function _isObject (a) |
{ |
return Object.keys(obj); |
} |
var t = typeof a; |
|
if (!_isObject(obj)) |
{ |
return jsx.throwThis("TypeError", |
"jsx.object.getKeys() called on non-object"); |
return t == "function" |
|| (t == "object" |
|| (t != "undefined" && t != "boolean" |
&& t != "number" && t != "string") |
&& a !== null); |
} |
|
var names = []; |
|
for (var p in obj) |
/** |
* Returns the own enumerable properties of an object |
* |
* @param {Object} obj |
* Object from which to get the keys |
* @return {Array} |
* Own enumerable properties of <var>obj</var> |
* @see Object#keys |
*/ |
function _getKeys (obj) |
{ |
if (_hasOwnProperty(obj, p)) |
if (typeof Object.keys == "function" && !Object.keys._emulated) |
{ |
names.push(p); |
return Object.keys(obj); |
} |
} |
|
return names; |
} |
if (!_isObject(obj)) |
{ |
return jsx.throwThis("TypeError", |
"jsx.object.getKeys() called on non-object"); |
} |
|
function Dummy () {} |
var names = []; |
|
/** |
* Lets one object inherit from another |
* |
* @param {Object} obj = Object.prototype |
* Object from which to inherit. The default is |
* <code>Object.prototype</code>. |
* @return {Object} |
* Inheriting (child) object |
*/ |
function _inheritFrom (obj) |
{ |
var prototype = (typeof obj == "undefined" |
? Object.prototype |
: (obj || null)); |
for (var p in obj) |
{ |
if (_hasOwnProperty(obj, p)) |
{ |
names.push(p); |
} |
} |
|
if (typeof Object.create == "function" && !Object.create._emulated) |
{ |
return Object.create(prototype); |
return names; |
} |
|
if (typeof obj == "object" && obj == null) |
{ |
var result = {}; |
/*jshint -W103*/ |
result.__proto__ = null; |
/*jshint +W103*/ |
return result; |
} |
function Dummy () {} |
|
Dummy.prototype = prototype; |
return new Dummy(); |
} |
|
/** |
* Returns the value of an object's internal <code>[[Class]]</code> |
* property. |
* |
* Calls the <code>Object.prototype.toString()</code> method on |
* the object and returns the result of matching against |
* the specified return value, which includes the value of |
* the object's internal <code>[[Class]]</code> property. Although |
* implementations use prototype-based inheritance, the property |
* value is useful for determining the type of an object regardless |
* of the current value of its <code>constructor</code> property. |
* For example, that makes it possible to recognize <code>Array</code> |
* instances independent of the global context in which they were |
* constructed, even if {@link Array.isArray} is not provided by |
* the ECMAScript implementation. |
* |
* @see ECMAScript Language Specification, Edition 5.1, section 15.4.3.2 |
* @see jsx.object.isArray() |
* @function |
*/ |
var _getClass = (function () { |
var _toString = ({}).toString; |
|
/** |
* @param obj |
* @return {string|Undefined} |
* The value of an object's internal [[Class]] property, or |
* <code>undefined</code> if the property value cannot be determined. |
* Lets one object inherit from another |
* |
* @param {Object} obj = Object.prototype |
* Object from which to inherit. The default is |
* <code>Object.prototype</code>. |
* @return {Object} |
* Inheriting (child) object |
*/ |
function getClass (obj) |
function _inheritFrom (obj) |
{ |
return (_toString.call(obj) |
.match(/^\s*\[object\s+(\S+)\s*\]\s*$/) || [, ""])[1]; |
} |
var prototype = (typeof obj == "undefined" |
? Object.prototype |
: (obj || null)); |
|
return getClass; |
}()); |
if (typeof Object.create == "function" && !Object.create._emulated) |
{ |
return Object.create(prototype); |
} |
|
/** |
* Determines if a value refers to an {@link Array}. |
* <p> |
* Returns <code>true</code> if the value is a reference to an object |
* whose <code>[[Class]]</code> internal property is <code>"Array"</code>; |
* <code>false</code> otherwise. |
* </p> |
* |
* @param a |
* Potential <code>Array</code> |
* @return {boolean} |
*/ |
function _isArray (a) |
{ |
return (typeof Array.isArray == "function" && !Array.isArray._emulated |
? Array.isArray(a) |
: (a && a.constructor == Array) || _getClass(a) == "Array"); |
} |
if (typeof obj == "object" && obj == null) |
{ |
var result = {}; |
/*jshint -W103*/ |
result.__proto__ = null; |
/*jshint +W103*/ |
return result; |
} |
|
var _rxPrimitive = /^(boolean|function|number|object|string)$/; |
Dummy.prototype = prototype; |
return new Dummy(); |
} |
|
/** |
* Determines if a value is a primitive value convertible to |
* an object or a reference to a native object. |
* |
* @param value |
* @return {boolean} |
*/ |
function _isNativeObject (value) |
{ |
var t = (_isObject(value) |
&& typeof value.valueOf == "function" |
&& typeof value.valueOf()); |
/** |
* Returns the value of an object's internal <code>[[Class]]</code> |
* property. |
* |
* Calls the <code>Object.prototype.toString()</code> method on |
* the object and returns the result of matching against |
* the specified return value, which includes the value of |
* the object's internal <code>[[Class]]</code> property. Although |
* implementations use prototype-based inheritance, the property |
* value is useful for determining the type of an object regardless |
* of the current value of its <code>constructor</code> property. |
* For example, that makes it possible to recognize <code>Array</code> |
* instances independent of the global context in which they were |
* constructed, even if {@link Array.isArray} is not provided by |
* the ECMAScript implementation. |
* |
* @see ECMAScript Language Specification, Edition 5.1, section 15.4.3.2 |
* @see jsx.object.isArray() |
* @function |
*/ |
var _getClass = (function () { |
var _toString = ({}).toString; |
|
return (t |
&& (_rxPrimitive.test(t) |
|| _isArray(value) |
|| /^(Date|Error|RegExp)$/.test(_getClass(value)) |
|| (typeof Math != "undefined" && value == Math) |
|| (typeof JSON != "undefined" && value == JSON)) |
); |
} |
/** |
* @param obj |
* @return {string|Undefined} |
* The value of an object's internal [[Class]] property, or |
* <code>undefined</code> if the property value cannot be determined. |
*/ |
function getClass (obj) |
{ |
return (_toString.call(obj) |
.match(/^\s*\[object\s+(\S+)\s*\]\s*$/) || [, ""])[1]; |
} |
|
/** |
* Used by {@link #extend()} and {@link #setProperties()} |
* to overwrite existing properties. |
*/ |
var _ADD_OVERWRITE = 1; |
return getClass; |
}()); |
|
/** |
* Used by {@link #extend()} and {@link #clone()} |
* to make a shallow copy of all enumerable properties (default). |
*/ |
var _COPY_ENUM = 0; |
/** |
* Determines if a value refers to an {@link Array}. |
* <p> |
* Returns <code>true</code> if the value is a reference to an object |
* whose <code>[[Class]]</code> internal property is <code>"Array"</code>; |
* <code>false</code> otherwise. |
* </p> |
* |
* @param a |
* Potential <code>Array</code> |
* @return {boolean} |
*/ |
function _isArray (a) |
{ |
return (typeof Array.isArray == "function" && !Array.isArray._emulated |
? Array.isArray(a) |
: (a && a.constructor == Array) || _getClass(a) == "Array"); |
} |
|
/** |
* Used by {@link #extend()} and {@link #clone()} |
* to make a deep copy of all enumerable properties. |
*/ |
var _COPY_ENUM_DEEP = 2; |
var _rxPrimitive = /^(boolean|function|number|object|string)$/; |
|
/** |
* Used by {@link #extend()} and {@link #clone()} |
* to copy a property by inheritance. |
*/ |
var _COPY_INHERIT = 4; |
/** |
* Determines if a value is a primitive value convertible to |
* an object or a reference to a native object. |
* |
* @param value |
* @return {boolean} |
*/ |
function _isNativeObject (value) |
{ |
var t = (_isObject(value) |
&& typeof value.valueOf == "function" |
&& typeof value.valueOf()); |
|
function _getProto (o) |
{ |
if (typeof Object.getPrototypeOf == "function" |
&& !Object.getPrototypeOf._emulated) |
{ |
return Object.getPrototypeOf(o); |
return (t |
&& (_rxPrimitive.test(t) |
|| _isArray(value) |
|| /^(Date|Error|RegExp)$/.test(_getClass(value)) |
|| (typeof Math != "undefined" && value == Math) |
|| (typeof JSON != "undefined" && value == JSON)) |
); |
} |
|
/*jshint -W103*/ |
return o.__proto__ || (o.constructor && o.constructor.prototype); |
/*jshint +W103*/ |
} |
/** |
* Used by {@link #extend()} and {@link #setProperties()} |
* to overwrite existing properties. |
*/ |
var _ADD_OVERWRITE = 1; |
|
function _createTypedObject (oOriginal) |
{ |
var prototype = _getProto(oOriginal); |
return (prototype ? _inheritFrom(prototype) : _inheritFrom()); |
} |
/** |
* Used by {@link #extend()} and {@link #clone()} |
* to make a shallow copy of all enumerable properties (default). |
*/ |
var _COPY_ENUM = 0; |
|
/** |
* Creates a duplicate (clone) of an object |
* |
* @param {Object} oSource (optional) |
* Object to be cloned. If omitted or <code>null</code>, |
* the calling object is cloned. |
* @param {Number} iLevel (optional) |
* Use the {@link #COPY_ENUM jsx.object.COPY_*} |
* properties to specify the level of cloning. |
* The default is {@link #COPY_ENUM}. |
* @return {Object} |
* A reference to the clone. |
*/ |
function _clone (oSource, iLevel) |
{ |
if (typeof oSource == "number") |
/** |
* Used by {@link #extend()} and {@link #clone()} |
* to make a deep copy of all enumerable properties. |
*/ |
var _COPY_ENUM_DEEP = 2; |
|
/** |
* Used by {@link #extend()} and {@link #clone()} |
* to copy a property by inheritance. |
*/ |
var _COPY_INHERIT = 4; |
|
function _getProto (o) |
{ |
var tmp = oSource; |
oSource = iLevel; |
iLevel = tmp; |
} |
if (typeof Object.getPrototypeOf == "function" |
&& !Object.getPrototypeOf._emulated) |
{ |
return Object.getPrototypeOf(o); |
} |
|
if (!oSource) |
{ |
oSource = jsx_object; |
/*jshint -W103*/ |
return o.__proto__ || (o.constructor && o.constructor.prototype); |
/*jshint +W103*/ |
} |
|
if (typeof iLevel == "undefined") |
function _createTypedObject (oOriginal) |
{ |
iLevel = _COPY_ENUM; |
var prototype = _getProto(oOriginal); |
return (prototype ? _inheritFrom(prototype) : _inheritFrom()); |
} |
|
if (iLevel & _COPY_INHERIT) |
/** |
* Creates a duplicate (clone) of an object |
* |
* @param {Object} oSource (optional) |
* Object to be cloned. If omitted or <code>null</code>, |
* the calling object is cloned. |
* @param {Number} iLevel (optional) |
* Use the {@link #COPY_ENUM jsx.object.COPY_*} |
* properties to specify the level of cloning. |
* The default is {@link #COPY_ENUM}. |
* @return {Object} |
* A reference to the clone. |
*/ |
function _clone (oSource, iLevel) |
{ |
return _inheritFrom(oSource); |
} |
if (typeof oSource == "number") |
{ |
var tmp = oSource; |
oSource = iLevel; |
iLevel = tmp; |
} |
|
var me = _clone; |
if (!oSource) |
{ |
oSource = jsx_object; |
} |
|
/* |
* NOTE: For objects, valueOf() only copies the object reference, |
* so we are creating an instance that inherits from the |
* original's prototype, if possible. |
*/ |
var o2 = (typeof oSource == "object" && oSource |
? _createTypedObject(oSource) |
: oSource.valueOf()); |
if (typeof iLevel == "undefined") |
{ |
iLevel = _COPY_ENUM; |
} |
|
for (var p in oSource) |
{ |
if (_hasOwnProperty(oSource, p)) |
if (iLevel & _COPY_INHERIT) |
{ |
if (iLevel && _isObject(oSource[p])) |
{ |
jsx.tryThis(function () { |
o2[p] = me(oSource[p], iLevel); |
}); |
} |
else |
{ |
jsx.tryThis(function () { |
o2[p] = oSource[p]; |
}); |
} |
return _inheritFrom(oSource); |
} |
} |
|
/* |
* "var p in ..." might not have copied (all) the array elements |
* (NN < 4.8 or user-defined non-enumerable elements only) |
*/ |
if (_isArray(o2)) |
{ |
for (var i = oSource.length; i--;) |
var me = _clone; |
|
/* |
* NOTE: For objects, valueOf() only copies the object reference, |
* so we are creating an instance that inherits from the |
* original's prototype, if possible. |
*/ |
var o2 = (typeof oSource == "object" && oSource |
? _createTypedObject(oSource) |
: oSource.valueOf()); |
|
for (var p in oSource) |
{ |
if (_hasOwnProperty(oSource, i) && !_hasOwnProperty(o2, i)) |
if (_hasOwnProperty(oSource, p)) |
{ |
if (iLevel && _isObject(oSource[i])) |
if (iLevel && _isObject(oSource[p])) |
{ |
jsx.tryThis(function () { |
o2[i] = me(oSource[i], iLevel); |
o2[p] = me(oSource[p], iLevel); |
}); |
} |
else |
{ |
jsx.tryThis(function () { |
o2[i] = oSource[i]; |
o2[p] = oSource[p]; |
}); |
} |
} |
} |
} |
|
return o2; |
} |
|
/** |
* Defines a property of an object. |
* |
* Emulation of the Object.defineProperty() method from ES 5.1, |
* section 15.2.3.6. |
* |
* Uses {@link Object.prototype#__defineGetter__} and |
* {@link Object.prototype#__defineSetter__} (JavaScript only) as fallback. |
* |
* @function |
* @return {Object} Reference to the object |
*/ |
var _defineProperty = (function () { |
function _toPropertyDescriptor (obj) |
{ |
if (!_isObject(obj)) |
/* |
* "var p in ..." might not have copied (all) the array elements |
* (NN < 4.8 or user-defined non-enumerable elements only) |
*/ |
if (_isArray(o2)) |
{ |
jsx.throwThis("TypeError", "Object expected"); |
for (var i = oSource.length; i--;) |
{ |
if (_hasOwnProperty(oSource, i) && !_hasOwnProperty(o2, i)) |
{ |
if (iLevel && _isObject(oSource[i])) |
{ |
jsx.tryThis(function () { |
o2[i] = me(oSource[i], iLevel); |
}); |
} |
else |
{ |
jsx.tryThis(function () { |
o2[i] = oSource[i]; |
}); |
} |
} |
} |
} |
|
var desc = {}; |
return o2; |
} |
|
if (_hasOwnProperty(obj, "enumerable")) |
/** |
* Defines a property of an object. |
* |
* Emulation of the Object.defineProperty() method from ES 5.1, |
* section 15.2.3.6. |
* |
* Uses {@link Object.prototype#__defineGetter__} and |
* {@link Object.prototype#__defineSetter__} (JavaScript only) as fallback. |
* |
* @function |
* @return {Object} Reference to the object |
*/ |
var _defineProperty = (function () { |
function _toPropertyDescriptor (obj) |
{ |
desc.enumerable = !!obj.enumerable; |
} |
if (!_isObject(obj)) |
{ |
jsx.throwThis("TypeError", "Object expected"); |
} |
|
if (_hasOwnProperty(obj, "configurable")) |
{ |
desc.configurable = !!obj.configurable; |
} |
var desc = {}; |
|
var hasValue = obj.hasOwnProperty("value"); |
if (hasValue) |
{ |
desc.value = obj.value; |
} |
if (_hasOwnProperty(obj, "enumerable")) |
{ |
desc.enumerable = !!obj.enumerable; |
} |
|
var hasWritable = _hasOwnProperty(obj, "writable"); |
if (hasWritable) |
{ |
desc.writable = !!obj.writable; |
} |
if (_hasOwnProperty(obj, "configurable")) |
{ |
desc.configurable = !!obj.configurable; |
} |
|
var hasGetter = _hasOwnProperty(obj, "get"); |
if (hasGetter) |
{ |
if (typeof obj.get != "function") |
var hasValue = obj.hasOwnProperty("value"); |
if (hasValue) |
{ |
return jsx.throwThis("TypeError", "Function expected for getter"); |
desc.value = obj.value; |
} |
|
desc.get = obj.get; |
} |
var hasWritable = _hasOwnProperty(obj, "writable"); |
if (hasWritable) |
{ |
desc.writable = !!obj.writable; |
} |
|
var hasSetter = _hasOwnProperty(obj, "set"); |
if (hasSetter) |
{ |
if (typeof obj.set != "function") |
var hasGetter = _hasOwnProperty(obj, "get"); |
if (hasGetter) |
{ |
return jsx.throwThis("TypeError", "Function expected for setter"); |
if (typeof obj.get != "function") |
{ |
return jsx.throwThis("TypeError", "Function expected for getter"); |
} |
|
desc.get = obj.get; |
} |
|
desc.set = obj.set; |
} |
var hasSetter = _hasOwnProperty(obj, "set"); |
if (hasSetter) |
{ |
if (typeof obj.set != "function") |
{ |
return jsx.throwThis("TypeError", "Function expected for setter"); |
} |
|
if ((hasGetter || hasSetter) && (hasValue || hasWritable)) |
{ |
return jsx.throwThis("TypeError", "Cannot define getter/setter and value/writable"); |
} |
desc.set = obj.set; |
} |
|
return desc; |
} |
|
function _defineOwnProperty (obj, propertyName, descriptor, _throw, context) |
{ |
function _isAccessorDescriptor (desc) |
{ |
if (typeof desc == "undefined") |
if ((hasGetter || hasSetter) && (hasValue || hasWritable)) |
{ |
return false; |
return jsx.throwThis("TypeError", "Cannot define getter/setter and value/writable"); |
} |
|
return _hasOwnProperty(desc, "get") || _hasOwnProperty(desc, "set"); |
return desc; |
} |
|
function _isDataDescriptor (desc) |
function _defineOwnProperty (obj, propertyName, descriptor, _throw, context) |
{ |
if (typeof desc == "undefined") |
function _isAccessorDescriptor (desc) |
{ |
return false; |
if (typeof desc == "undefined") |
{ |
return false; |
} |
|
return _hasOwnProperty(desc, "get") || _hasOwnProperty(desc, "set"); |
} |
|
return desc.hasOwnProperty("value") || _hasOwnProperty(desc, "writable"); |
} |
function _isDataDescriptor (desc) |
{ |
if (typeof desc == "undefined") |
{ |
return false; |
} |
|
function _isGenericDescriptor (desc) |
{ |
if (typeof desc == "undefined") |
return desc.hasOwnProperty("value") || _hasOwnProperty(desc, "writable"); |
} |
|
function _isGenericDescriptor (desc) |
{ |
return false; |
if (typeof desc == "undefined") |
{ |
return false; |
} |
|
return !_isAccessorDescriptor(desc) && !_isDataDescriptor(desc); |
} |
|
return !_isAccessorDescriptor(desc) && !_isDataDescriptor(desc); |
} |
// var current = obj.hasOwnProperty(propertyName); |
// var extensible = obj[propertyName].[[Extensible]] |
|
// var current = obj.hasOwnProperty(propertyName); |
// var extensible = obj[propertyName].[[Extensible]] |
if (_isGenericDescriptor(descriptor) || _isDataDescriptor(descriptor)) |
{ |
var value = descriptor.value; |
obj[propertyName] = value; |
|
if (_isGenericDescriptor(descriptor) || _isDataDescriptor(descriptor)) |
{ |
var value = descriptor.value; |
obj[propertyName] = value; |
if (!descriptor.writable) |
{ |
jsx.tryThis( |
function () { |
/* NOTE: Need getter because __defineSetter__() undefines value */ |
obj.__defineGetter__(propertyName, function () { |
return value; |
}); |
|
if (!descriptor.writable) |
obj.__defineSetter__(propertyName, function () {}); |
}, |
function () { |
obj[propertyName] = value; |
|
jsx.warn((context ? context + ": " : "") |
+ "Could not define property `" + propertyName |
+ "' as read-only"); |
}); |
} |
} |
else |
{ |
/* accessor property descriptor */ |
jsx.tryThis( |
function () { |
/* NOTE: Need getter because __defineSetter__() undefines value */ |
obj.__defineGetter__(propertyName, function () { |
return value; |
}); |
if (descriptor["get"]) |
{ |
obj.__defineGetter__(propertyName, descriptor["get"]); |
} |
|
obj.__defineSetter__(propertyName, function () {}); |
if (descriptor["set"]) |
{ |
obj.__defineSetter__(propertyName, descriptor["set"]); |
} |
}, |
function () { |
obj[propertyName] = value; |
|
jsx.warn((context ? context + ": " : "") |
+ "Could not define property `" + propertyName |
+ "' as read-only"); |
+ "Could not define special property `" + propertyName + "'." |
+ " Please use explicit getters and setters instead."); |
}); |
} |
} |
else |
{ |
/* accessor property descriptor */ |
jsx.tryThis( |
function () { |
if (descriptor["get"]) |
{ |
obj.__defineGetter__(propertyName, descriptor["get"]); |
} |
|
if (descriptor["set"]) |
{ |
obj.__defineSetter__(propertyName, descriptor["set"]); |
} |
}, |
function () { |
jsx.warn((context ? context + ": " : "") |
+ "Could not define special property `" + propertyName + "'." |
+ " Please use explicit getters and setters instead."); |
}); |
return false; |
} |
|
return false; |
} |
|
/** |
* @function |
*/ |
var _defineProperty = _extend( |
/** |
* @param {Object} o |
* @param {Object} descriptor (optional) |
* Property descriptor, a reference to an object that defines |
* the attributes of the property. Must be of the form |
* <code><pre>{ |
* propertyName: { |
* configurable: …, |
* enumerable: …, |
* value: …, |
* writable: …, |
* get: function () {…}, |
* set: function (newValue) {…} |
* }, |
* … |
* } |
* </pre></code> as specified in the ECMAScript Language Specification, |
* Edition 5 Final, section 15.2.3.7. Note that the |
* <code>[[Configurable]]</code> and <code>[[Enumerable]]</code> |
* attributes cannot be emulated. The [[Writable]] attribute, |
* and getter and setter can only be emulated if the |
* <code>__defineGetter__()</code> and <code>__defineSetter__()</code> |
* methods are available, respectively. |
* @param {string} sContext (optional) |
* The context in which the property definition was attempted. |
* Included in the info message in case getters and setters |
* could not be defined. |
* @function |
*/ |
function (o, propertyName, descriptor, sContext) { |
var done = false; |
var _defineProperty = _extend( |
/** |
* @param {Object} o |
* @param {Object} descriptor (optional) |
* Property descriptor, a reference to an object that defines |
* the attributes of the property. Must be of the form |
* <code><pre>{ |
* propertyName: { |
* configurable: …, |
* enumerable: …, |
* value: …, |
* writable: …, |
* get: function () {…}, |
* set: function (newValue) {…} |
* }, |
* … |
* } |
* </pre></code> as specified in the ECMAScript Language Specification, |
* Edition 5 Final, section 15.2.3.7. Note that the |
* <code>[[Configurable]]</code> and <code>[[Enumerable]]</code> |
* attributes cannot be emulated. The [[Writable]] attribute, |
* and getter and setter can only be emulated if the |
* <code>__defineGetter__()</code> and <code>__defineSetter__()</code> |
* methods are available, respectively. |
* @param {string} sContext (optional) |
* The context in which the property definition was attempted. |
* Included in the info message in case getters and setters |
* could not be defined. |
*/ |
function (o, propertyName, descriptor, sContext) { |
var done = false; |
|
if (typeof Object.defineProperty == "function" |
&& !Object.defineProperty._emulated) |
{ |
jsx.tryThis(function () { |
Object.defineProperty(o, propertyName, descriptor); |
done = true; |
}); |
} |
|
if (!done) |
{ |
if (!/^(object|function)$/.test(typeof o) || !o) |
if (typeof Object.defineProperty == "function" |
&& !Object.defineProperty._emulated) |
{ |
return jsx.throwThis("TypeError", "Object expected"); |
jsx.tryThis(function () { |
Object.defineProperty(o, propertyName, descriptor); |
done = true; |
}); |
} |
|
var name = String(propertyName); |
var desc = _toPropertyDescriptor(descriptor); |
_defineOwnProperty(o, name, desc, true, sContext); |
} |
if (!done) |
{ |
if (!/^(object|function)$/.test(typeof o) || !o) |
{ |
return jsx.throwThis("TypeError", "Object expected"); |
} |
|
return o; |
}, |
{ |
_emulated: true |
}); |
var name = String(propertyName); |
var desc = _toPropertyDescriptor(descriptor); |
_defineOwnProperty(o, name, desc, true, sContext); |
} |
|
return _defineProperty; |
}()); |
return o; |
}, |
{ |
_emulated: true |
}); |
|
/** |
* Adds/replaces properties of an object. |
* |
* <p> |
* <em>Not to be confused with {@link Function.prototype.extend}.</em> |
* </p> |
* |
* @param {Object} oTarget |
* Target object whose properties should be set. |
* @param {Object} oSource |
* Object specifying the properties to be set. |
* The name of each property serves as the name for the |
* property of the target object, its value as the value |
* of that property. |
* @param {Number} iFlags = 0 |
* Flags for the modification, see {@link #ADD_OVERWRITE} |
* and {@link #COPY_ENUM jsx.object.COPY_*}. |
* @return {Object} |
* The extended object |
*/ |
function _extend (oTarget, oSource, iFlags) |
{ |
if (typeof iFlags == "undefined") |
{ |
iFlags = 0; |
} |
return _defineProperty; |
}()); |
|
var cloneLevel = (iFlags & (_COPY_ENUM_DEEP | _COPY_INHERIT)); |
|
for (var i = 0, keys = _getKeys(oSource), len = keys.length; |
i < len; ++i) |
/** |
* Adds/replaces properties of an object. |
* |
* <p> |
* <em>Not to be confused with {@link Function.prototype.extend}.</em> |
* </p> |
* |
* @param {Object} oTarget |
* Target object whose properties should be set. |
* @param {Object} oSource |
* Object specifying the properties to be set. |
* The name of each property serves as the name for the |
* property of the target object, its value as the value |
* of that property. |
* @param {Number} iFlags = 0 |
* Flags for the modification, see {@link #ADD_OVERWRITE} |
* and {@link #COPY_ENUM jsx.object.COPY_*}. |
* @return {Object} |
* The extended object |
*/ |
function _extend (oTarget, oSource, iFlags) |
{ |
var p = keys[i]; |
|
if (typeof oTarget[p] == "undefined" || (iFlags & _ADD_OVERWRITE)) |
if (typeof iFlags == "undefined") |
{ |
jsx.tryThis(function () { |
/* TODO: Support cloning of property attributes */ |
oTarget[p] = (cloneLevel |
? _clone(oSource[p], cloneLevel) |
: oSource[p]); |
oTarget[p]._userDefined = true; |
}); |
iFlags = 0; |
} |
} |
|
return oTarget; |
} |
var cloneLevel = (iFlags & (_COPY_ENUM_DEEP | _COPY_INHERIT)); |
|
/** |
* Returns a feature of an object |
* |
* @param {Object} obj |
* Object which provides the feature |
* @param {string|Array} path |
* Property names on the feature path, including the property |
* for the feature itself. For example, use |
* <code>jsx.object.getFeature(foo, "bar", "baz")</code> for |
* safe access to <code>foo.bar.baz</code>. |
* If this argument is an <code>Array</code>, it is used |
* instead of the remaining argument list; this is the |
* recommended way to call this method to ensure upwards |
* compatibility. |
* @return {any} |
* <code>undefined</code> if <var>obj</var> does not have such |
* a feature. Note that features whose value can be |
* <code>undefined</code> cannot be detected with this method. |
*/ |
function _getFeature (obj, path) |
{ |
var realPath = path; |
var start = 0; |
for (var i = 0, keys = _getKeys(oSource), len = keys.length; |
i < len; ++i) |
{ |
var p = keys[i]; |
|
if (!_isArray(realPath)) |
{ |
realPath = arguments; |
start = 1; |
if (typeof oTarget[p] == "undefined" || (iFlags & _ADD_OVERWRITE)) |
{ |
jsx.tryThis(function () { |
/* TODO: Support cloning of property attributes */ |
oTarget[p] = (cloneLevel |
? _clone(oSource[p], cloneLevel) |
: oSource[p]); |
oTarget[p]._userDefined = true; |
}); |
} |
} |
|
return oTarget; |
} |
|
for (var i = start, len = realPath.length; i < len; i++) |
/** |
* Returns a feature of an object |
* |
* @param {Object} obj |
* Object which provides the feature |
* @param {string|Array} path |
* Property names on the feature path, including the property |
* for the feature itself. For example, use |
* <code>jsx.object.getFeature(foo, "bar", "baz")</code> for |
* safe access to <code>foo.bar.baz</code>. |
* If this argument is an <code>Array</code>, it is used |
* instead of the remaining argument list; this is the |
* recommended way to call this method to ensure upwards |
* compatibility. |
* @return {any} |
* <code>undefined</code> if <var>obj</var> does not have such |
* a feature. Note that features whose value can be |
* <code>undefined</code> cannot be detected with this method. |
*/ |
function _getFeature (obj, path) |
{ |
var component = realPath[i]; |
if (_isObject(obj) |
&& typeof obj[component] != "undefined" && obj[component]) |
var realPath = path; |
var start = 0; |
|
if (!_isArray(realPath)) |
{ |
obj = obj[component]; |
realPath = arguments; |
start = 1; |
} |
else |
|
for (var i = start, len = realPath.length; i < len; i++) |
{ |
return void 0; |
var component = realPath[i]; |
if (_isObject(obj) |
&& typeof obj[component] != "undefined" && obj[component]) |
{ |
obj = obj[component]; |
} |
else |
{ |
return void 0; |
} |
} |
|
return obj; |
} |
|
return obj; |
} |
/* For getFunctionName from JSdoc; TODO: Use ES parser library */ |
var _srxUnicodeLetter = "\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}"; |
var _srxUnicodeEscapeSequence = "\\\\u[\\da-fA-F]{4}"; |
var _srxIdentifierStart = _srxUnicodeLetter + "$_" + _srxUnicodeEscapeSequence; |
var _srxUnicodeCombiningMark = "\p{Mn}\p{Mc}"; |
var _srxUnicodeDigit = "\\{Nd}"; |
var _srxUnicodeConnectorPunctuation = "\\p{Pc}"; |
var _srxIdentifierPart = |
+ _srxIdentifierStart |
+ _srxUnicodeCombiningMark |
+ _srxUnicodeDigit |
+ _srxUnicodeConnectorPunctuation; |
var _srxIdentifierName = "[" + _srxIdentifierStart + "][" + _srxIdentifierPart + "]*"; |
|
/* For getFunctionName from JSdoc; TODO: Use ES parser library */ |
var _srxUnicodeLetter = "\\p{Lu}\\p{Ll}\\p{Lt}\\p{Lm}\\p{Lo}\\p{Nl}"; |
var _srxUnicodeEscapeSequence = "\\\\u[\\da-fA-F]{4}"; |
var _srxIdentifierStart = _srxUnicodeLetter + "$_" + _srxUnicodeEscapeSequence; |
var _srxUnicodeCombiningMark = "\p{Mn}\p{Mc}"; |
var _srxUnicodeDigit = "\\{Nd}"; |
var _srxUnicodeConnectorPunctuation = "\\p{Pc}"; |
var _srxIdentifierPart = |
+ _srxIdentifierStart |
+ _srxUnicodeCombiningMark |
+ _srxUnicodeDigit |
+ _srxUnicodeConnectorPunctuation; |
var _srxIdentifierName = "[" + _srxIdentifierStart + "][" + _srxIdentifierPart + "]*"; |
var jsx_object = { |
/** |
* @memberOf jsx.object |
* @version |
*/ |
version: "$Revision$ ($Date$)", |
|
var jsx_object = { |
/** |
* @memberOf jsx.object |
* @version |
*/ |
version: "$Revision$ ($Date$)", |
copyright: "Copyright \xA9 2004-2013", |
author: "Thomas Lahn", |
email: "js@PointedEars.de", |
path: "http://PointedEars.de/scripts/", |
// docURL: jsx.object.path + "object.htm", |
|
copyright: "Copyright \xA9 2004-2013", |
author: "Thomas Lahn", |
email: "js@PointedEars.de", |
path: "http://PointedEars.de/scripts/", |
// docURL: jsx.object.path + "object.htm", |
ADD_OVERWRITE: _ADD_OVERWRITE, |
COPY_ENUM: _COPY_ENUM, |
COPY_ENUM_DEEP: _COPY_ENUM_DEEP, |
COPY_INHERIT: _COPY_INHERIT, |
|
ADD_OVERWRITE: _ADD_OVERWRITE, |
COPY_ENUM: _COPY_ENUM, |
COPY_ENUM_DEEP: _COPY_ENUM_DEEP, |
COPY_INHERIT: _COPY_INHERIT, |
isMethod: _isMethod, |
areMethods: _isMethod, |
isHostMethod: _isMethod, |
areHostMethods: _isMethod, |
|
isMethod: _isMethod, |
areMethods: _isMethod, |
isHostMethod: _isMethod, |
areHostMethods: _isMethod, |
isNativeMethod: _isNativeMethod, |
areNativeMethods: _isNativeMethod, |
|
isNativeMethod: _isNativeMethod, |
areNativeMethods: _isNativeMethod, |
/** |
* Calls a property if it is likely to be callable, and |
* returns its result. |
* |
* @param {Array} aPath |
* Argument list for <code><var>fTester</var></code> |
* @param {Array} aArguments |
* Argument list for the method call |
* @param {Function} fTester |
* Testing method. Recommended values include |
* {@link #isNativeMethod()} and {@link #isHostMethod()}. |
* The default is {@link #isMethod()}. |
* @return {Object} |
* <code>{returnValue: <var>value</var>}</code> if the method |
* could be called, where <code><var>value</var></code> is |
* the return value of the method; |
* <code>null</code> otherwise. |
*/ |
callIfMethod: function (aPath, aArguments, fTester) { |
if (!fTester) |
{ |
fTester = _isMethod; |
} |
|
/** |
* Calls a property if it is likely to be callable, and |
* returns its result. |
* |
* @param {Array} aPath |
* Argument list for <code><var>fTester</var></code> |
* @param {Array} aArguments |
* Argument list for the method call |
* @param {Function} fTester |
* Testing method. Recommended values include |
* {@link #isNativeMethod()} and {@link #isHostMethod()}. |
* The default is {@link #isMethod()}. |
* @return {Object} |
* <code>{returnValue: <var>value</var>}</code> if the method |
* could be called, where <code><var>value</var></code> is |
* the return value of the method; |
* <code>null</code> otherwise. |
*/ |
callIfMethod: function (aPath, aArguments, fTester) { |
if (!fTester) |
{ |
fTester = _isMethod; |
} |
if (fTester.apply(this, aPath)) |
{ |
var method = _getFeature.apply(this, aPath); |
var returnValue = method.apply(aPath[0], aArguments); |
return {returnValue: returnValue}; |
} |
|
if (fTester.apply(this, aPath)) |
{ |
var method = _getFeature.apply(this, aPath); |
var returnValue = method.apply(aPath[0], aArguments); |
return {returnValue: returnValue}; |
} |
return null; |
}, |
|
return null; |
}, |
/** |
* Determines if the passed value could be the result of |
* <code>typeof <var>callable</var></code>. |
* <p> |
* NOTE: This method has previously been provided by {@link types.js}; |
* optimizations in code reuse moved it here. |
* </p> |
* @param {string} s |
* String to be determined a method type, i.e. |
* <code>"object"</code> or <code>"unknown"</code> in MSHTML, |
* <code>"function"</code> otherwise. The type must have been |
* retrieved with the <code>typeof<code> operator. Note that |
* this method may also return <code>true</code> if the value |
* of the <code>typeof</code> operand is <code>null</code>; |
* to be sure that the operand is a method reference, you |
* have to <code>&&</code> (AND)-combine the |
* <code>isMethodType(...)</code> expression with the method |
* reference identifier unless <code>typeof</code> yielded |
* <code>"unknown"</code> for <var>s</var>. |
* @return {boolean} |
* <code>true</code> if <var>s</var> is a method type, |
* <code>false</code> otherwise. |
* @author |
* (C) 2003-2008 Thomas Lahn <types.js@PointedEars.de>. |
* Distributed under the GNU GPL v3 and later. |
* @partof http://pointedears.de/scripts/types.js |
* @deprecated since version 0.1.5a.2009070204 |
* in favor of {@link #isMethod(Object)} |
*/ |
isMethodType: function (s) { |
return /^\s*(function|object|unknown)\s*$/i.test(s); |
}, |
|
/** |
* Determines if the passed value could be the result of |
* <code>typeof <var>callable</var></code>. |
* <p> |
* NOTE: This method has previously been provided by {@link types.js}; |
* optimizations in code reuse moved it here. |
* </p> |
* @param {string} s |
* String to be determined a method type, i.e. |
* <code>"object"</code> or <code>"unknown"</code> in MSHTML, |
* <code>"function"</code> otherwise. The type must have been |
* retrieved with the <code>typeof<code> operator. Note that |
* this method may also return <code>true</code> if the value |
* of the <code>typeof</code> operand is <code>null</code>; |
* to be sure that the operand is a method reference, you |
* have to <code>&&</code> (AND)-combine the |
* <code>isMethodType(...)</code> expression with the method |
* reference identifier unless <code>typeof</code> yielded |
* <code>"unknown"</code> for <var>s</var>. |
* @return {boolean} |
* <code>true</code> if <var>s</var> is a method type, |
* <code>false</code> otherwise. |
* @author |
* (C) 2003-2008 Thomas Lahn <types.js@PointedEars.de>. |
* Distributed under the GNU GPL v3 and later. |
* @partof http://pointedears.de/scripts/types.js |
* @deprecated since version 0.1.5a.2009070204 |
* in favor of {@link #isMethod(Object)} |
*/ |
isMethodType: function (s) { |
return /^\s*(function|object|unknown)\s*$/i.test(s); |
}, |
_hasOwnProperty: _hasOwnProperty, |
isObject: _isObject, |
|
_hasOwnProperty: _hasOwnProperty, |
isObject: _isObject, |
isString: function (s) { |
return ((typeof s == "string") || jsx.object.isInstanceOf(s, String)); |
}, |
|
isString: function (s) { |
return ((typeof s == "string") || jsx.object.isInstanceOf(s, String)); |
}, |
getKeys: _getKeys, |
inheritFrom: _inheritFrom, |
getClass: _getClass, |
isArray: _isArray, |
isNativeObject: _isNativeObject, |
|
getKeys: _getKeys, |
inheritFrom: _inheritFrom, |
getClass: _getClass, |
isArray: _isArray, |
isNativeObject: _isNativeObject, |
isHostObject: function (value) { |
return !_isNativeObject(value); |
}, |
|
isHostObject: function (value) { |
return !_isNativeObject(value); |
}, |
clone: _clone, |
|
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)) |
/** |
* 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") |
{ |
continue; |
return jsx.throwThis(jsx.InvalidArgumentError, |
["", typeof flipper, "Function"]); |
} |
|
var value = obj[key]; |
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; |
|
var value_is_object = _isObject(value); |
if (value_is_object && !_Map) |
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
jsx.warn("Information loss because value is an object." |
+ " Load jsx.map.Map to avoid."); |
} |
var key = keys[i]; |
|
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)) |
if (flipper && !flipper.call(obj, key)) |
{ |
var a = new _Array(); |
a.push(key_value); |
|
if (_Map) |
{ |
flipped.put(value, a); |
} |
else |
{ |
flipped[value] = a; |
} |
continue; |
} |
|
if (flipped.length == _MAX_ARRAY_LENGTH && !_BigArray) |
var value = obj[key]; |
|
var value_is_object = _isObject(value); |
if (value_is_object && !_Map) |
{ |
jsx.warn("Possible information loss due to Array limits." |
+ " Provide jsx.array.BigArray to avoid."); |
jsx.warn("Information loss because value is an object." |
+ " Load jsx.map.Map to avoid."); |
} |
|
key_value = _Map |
var has_value_key = _Map |
? flipped.hasKey(value) |
: _hasOwnProperty(flipped, value); |
|
var key_value = _Map |
? flipped.get(value) |
: flipped[value]; |
|
key_value.push(key); |
} |
else |
{ |
if (has_value_key) |
if (has_value_key && bAccumulate) |
{ |
jsx.warn("Information loss due to same value." |
+ " Pass bAccumulate === true to avoid."); |
} |
if (!_isArray(key_value)) |
{ |
var a = new _Array(); |
a.push(key_value); |
|
if (_Map) |
{ |
flipped.put(value, key); |
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 |
{ |
flipped[value] = key; |
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; |
}, |
return flipped; |
}, |
|
/** |
* @deprecated in favor of {@link #extend} |
*/ |
setProperties: _extend, |
/** |
* @deprecated in favor of {@link #extend} |
*/ |
setProperties: _extend, |
|
extend: _extend, |
defineProperty: _defineProperty, |
extend: _extend, |
defineProperty: _defineProperty, |
|
/** |
* Defines properties of an object, if possible. |
* |
* Emulation of the Object.defineProperties() method from ES 5.1, |
* section 15.2.3.7. |
* |
* @function |
* @param {Object} o |
* The object for which properties getters and setters should be defined. |
* @param {Object} descriptor (optional) |
* Properties descriptor, where each own property name |
* is a property name of the new object, and each corresponding |
* property value is a reference to an object that defines the |
* attributes of that property. |
* @return {Object} Reference to the object |
* @see #defineProperty |
*/ |
defineProperties: _extend( |
function (o, descriptor, sContext) { |
var done = false; |
/** |
* Defines properties of an object, if possible. |
* |
* Emulation of the Object.defineProperties() method from ES 5.1, |
* section 15.2.3.7. |
* |
* @function |
* @param {Object} o |
* The object for which properties getters and setters should be defined. |
* @param {Object} descriptor (optional) |
* Properties descriptor, where each own property name |
* is a property name of the new object, and each corresponding |
* property value is a reference to an object that defines the |
* attributes of that property. |
* @return {Object} Reference to the object |
* @see #defineProperty |
*/ |
defineProperties: _extend( |
function (o, descriptor, sContext) { |
var done = false; |
|
if (typeof Object.defineProperties == "function" |
&& !Object.defineProperties._emulated) |
{ |
jsx.tryThis(function () { |
Object.defineProperties(o, descriptor); |
done = true; |
}); |
} |
if (typeof Object.defineProperties == "function" |
&& !Object.defineProperties._emulated) |
{ |
jsx.tryThis(function () { |
Object.defineProperties(o, descriptor); |
done = true; |
}); |
} |
|
if (!done) |
{ |
for (var i = 0, keys = _getKeys(descriptor), len = keys.length; |
i < len; ++i) |
if (!done) |
{ |
var propertyName = keys[i]; |
_defineProperty(o, propertyName, descriptor[propertyName], |
sContext); |
for (var i = 0, keys = _getKeys(descriptor), len = keys.length; |
i < len; ++i) |
{ |
var propertyName = keys[i]; |
_defineProperty(o, propertyName, descriptor[propertyName], |
sContext); |
} |
} |
} |
|
return o; |
}, |
{ |
_emulated: true |
}), |
return o; |
}, |
{ |
_emulated: true |
}), |
|
/** |
* Determines if a (non-inherited) property of an object is enumerable |
* |
* @param {Object} obj (optional) |
* Object which property should be checked for enumerability. |
* @param {string} sProperty |
* Name of the property to check. |
* @return {boolean} |
* <code>true</code> if there is such a property; |
* <code>false</code> otherwise. |
*/ |
_propertyIsEnumerable: function (obj, sProperty) { |
if (arguments.length < 2 && obj) |
{ |
sProperty = obj; |
obj = jsx_object; |
} |
/** |
* Determines if a (non-inherited) property of an object is enumerable |
* |
* @param {Object} obj (optional) |
* Object which property should be checked for enumerability. |
* @param {string} sProperty |
* Name of the property to check. |
* @return {boolean} |
* <code>true</code> if there is such a property; |
* <code>false</code> otherwise. |
*/ |
_propertyIsEnumerable: function (obj, sProperty) { |
if (arguments.length < 2 && obj) |
{ |
sProperty = obj; |
obj = jsx_object; |
} |
|
if (_isMethod(obj, "propertyIsEnumerable")) |
{ |
return obj.propertyIsEnumerable(sProperty); |
} |
|
for (var propertyName in obj) |
{ |
if (propertyName == name && _hasOwnProperty(obj, propertyName)) |
if (_isMethod(obj, "propertyIsEnumerable")) |
{ |
return true; |
return obj.propertyIsEnumerable(sProperty); |
} |
} |
|
return false; |
}, |
|
/** |
* Determines if an object, or the objects it refers to, |
* has an enumerable property with a certain value |
* |
* @param {Object} obj |
* @param needle |
* The value to be searched for |
* @param {Object} params |
* Search parameters. The following properties are supported: |
* <table> |
* <thead> |
* <tr> |
* <th>Property</th> |
* <th>Type</th> |
* <th>Meaning</th> |
* </tr> |
* </thead> |
* <tbody> |
* <tr> |
* <th><code><var>exclude</var></code></th> |
* <td><code>Array</code></td> |
* <td>Names of the properties that should not be searched</td> |
* </tr> |
* <tr> |
* <th><code><var>recursive</var></code></th> |
* <td><code>boolean</code></td> |
* <td>If a true-value, search recursively.</td> |
* </tr> |
* <tr> |
* <th><code><var>strict</var></code></th> |
* <td><code>boolean</code></td> |
* <td>If a true-value, perform a strict comparison |
* without type conversion.</td> |
* </tr> |
* </tbody> |
* </table> |
*/ |
hasPropertyValue: |
function jsx_object_hasPropertyValue (obj, needle, params) { |
for (var property in obj) |
for (var propertyName in obj) |
{ |
if (params && params.exclude && params.exclude.indexOf(property) > -1) |
if (propertyName == name && _hasOwnProperty(obj, propertyName)) |
{ |
continue; |
return true; |
} |
} |
|
var propertyValue = obj[property]; |
if (params && params.recursive) |
return false; |
}, |
|
/** |
* Determines if an object, or the objects it refers to, |
* has an enumerable property with a certain value |
* |
* @param {Object} obj |
* @param needle |
* The value to be searched for |
* @param {Object} params |
* Search parameters. The following properties are supported: |
* <table> |
* <thead> |
* <tr> |
* <th>Property</th> |
* <th>Type</th> |
* <th>Meaning</th> |
* </tr> |
* </thead> |
* <tbody> |
* <tr> |
* <th><code><var>exclude</var></code></th> |
* <td><code>Array</code></td> |
* <td>Names of the properties that should not be searched</td> |
* </tr> |
* <tr> |
* <th><code><var>recursive</var></code></th> |
* <td><code>boolean</code></td> |
* <td>If a true-value, search recursively.</td> |
* </tr> |
* <tr> |
* <th><code><var>strict</var></code></th> |
* <td><code>boolean</code></td> |
* <td>If a true-value, perform a strict comparison |
* without type conversion.</td> |
* </tr> |
* </tbody> |
* </table> |
*/ |
hasPropertyValue: |
function jsx_object_hasPropertyValue (obj, needle, params) { |
for (var property in obj) |
{ |
if (typeof propertyValue == "object" && propertyValue !== null) |
if (params && params.exclude && params.exclude.indexOf(property) > -1) |
{ |
if (jsx_object_hasPropertyValue(propertyValue, needle, params)) |
continue; |
} |
|
var propertyValue = obj[property]; |
if (params && params.recursive) |
{ |
if (typeof propertyValue == "object" && propertyValue !== null) |
{ |
return true; |
if (jsx_object_hasPropertyValue(propertyValue, needle, params)) |
{ |
return true; |
} |
} |
} |
} |
|
if (params && params.strict) |
{ |
if (propertyValue === needle) |
if (params && params.strict) |
{ |
return true; |
if (propertyValue === needle) |
{ |
return true; |
} |
} |
} |
else |
{ |
/* Switch operands because of JScript quirk */ |
if (needle == propertyValue) |
else |
{ |
return true; |
/* Switch operands because of JScript quirk */ |
if (needle == propertyValue) |
{ |
return true; |
} |
} |
} |
} |
|
return false; |
}, |
return false; |
}, |
|
/** |
* Returns the name of an unused property for an object. |
* |
* @param {Object} obj |
* @param {Number} iLength |
* Maximum property name length up to which an unused name |
* is searched. The default is 256. |
* @return {string} |
* The name of a non-existing property of <code>o</code> if |
* {@link Object#prototype.hasOwnProperty()} is supported, or |
* the name of a property with value <code>undefined</code> |
* if it is not supported; the empty string |
* if there is no such property. |
*/ |
findNewProperty: function (obj, iLength) { |
if (!obj) |
{ |
obj = jsx_object; |
} |
/** |
* Returns the name of an unused property for an object. |
* |
* @param {Object} obj |
* @param {Number} iLength |
* Maximum property name length up to which an unused name |
* is searched. The default is 256. |
* @return {string} |
* The name of a non-existing property of <code>o</code> if |
* {@link Object#prototype.hasOwnProperty()} is supported, or |
* the name of a property with value <code>undefined</code> |
* if it is not supported; the empty string |
* if there is no such property. |
*/ |
findNewProperty: function (obj, iLength) { |
if (!obj) |
{ |
obj = jsx_object; |
} |
|
if (arguments.length < 2) |
{ |
iLength = 256; |
} |
else |
{ |
iLength = parseInt(iLength, 10); |
} |
if (arguments.length < 2) |
{ |
iLength = 256; |
} |
else |
{ |
iLength = parseInt(iLength, 10); |
} |
|
var prefix = ""; |
var prefix = ""; |
|
while (prefix.length < iLength) |
{ |
for (var i = "a".charCodeAt(0), max = "z".charCodeAt(0); i <= max; ++i) |
while (prefix.length < iLength) |
{ |
var ch = String.fromCharCode(i); |
var newName = prefix + ch + "_"; |
if (!_hasOwnProperty(obj, newName)) |
for (var i = "a".charCodeAt(0), max = "z".charCodeAt(0); i <= max; ++i) |
{ |
return newName; |
var ch = String.fromCharCode(i); |
var newName = prefix + ch + "_"; |
if (!_hasOwnProperty(obj, newName)) |
{ |
return newName; |
} |
} |
|
prefix += "a"; |
} |
|
prefix += "a"; |
} |
return ""; |
}, |
|
return ""; |
}, |
/** |
* Returns a new object that can serve as data container. |
* |
* 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>oSource</var>. This is |
* accomplished by either cutting off its existing prototype |
* chain or not creating one for it in the first place. |
* |
* Different to {@link Object.create()}, properties from |
* <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 <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>. |
* |
* @param {Object} oSource (optional) |
* @param {Number} iFlags (optional) |
* See {@link #clone()}. |
* @return {Object} |
* @see Object.create() |
* @see jsx.object.clone() |
*/ |
getDataObject: function (oSource, iFlags) { |
var obj = _inheritFrom(null); |
|
/** |
* Returns a new object that can serve as data container. |
* |
* 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>oSource</var>. This is |
* accomplished by either cutting off its existing prototype |
* chain or not creating one for it in the first place. |
* |
* Different to {@link Object.create()}, properties from |
* <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 <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>. |
* |
* @param {Object} oSource (optional) |
* @param {Number} iFlags (optional) |
* See {@link #clone()}. |
* @return {Object} |
* @see Object.create() |
* @see jsx.object.clone() |
*/ |
getDataObject: function (oSource, iFlags) { |
var obj = _inheritFrom(null); |
|
if (_isObject(oSource)) |
{ |
for (var i = 0, keys = _getKeys(oSource), len = keys.length; |
i < len; ++i) |
if (_isObject(oSource)) |
{ |
var name = keys[i]; |
var value = oSource[name]; |
for (var i = 0, keys = _getKeys(oSource), len = keys.length; |
i < len; ++i) |
{ |
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); |
/* NOTE: formerly, numeric flags was first argument of _clone() */ |
obj[name] = (typeof value != "number" |
? _clone(value, iFlags) |
: value); |
} |
} |
} |
|
return obj; |
}, |
return obj; |
}, |
|
getFeature: _getFeature, |
getFeature: _getFeature, |
|
/** |
* Emulates the <code>instanceof</code> operator |
* of ECMAScript Edition 3 and later. |
* |
* Uses <code>Object.getPrototypeOf</code> (ECMAScript Ed. 3 and later) |
* or the proprietary <code>__proto__</code> property (JavaScript 1.3 |
* and later, and compatible implementations). |
* |
* Example: |
* <pre><code> |
* var o = new Object(); |
* o instanceof Object; // yields `true' |
* |
* function Foo() {} |
* var o = new Foo(); |
* o instanceof Object; // yields `true' |
* o instanceof Foo; // yields `true' also |
* |
* var _isInstanceOf = jsx.object.isInstanceOf; |
* _isInstanceOf(o, Object); // returns `true' |
* _isInstanceOf(o, Foo); // returns `true' also |
* _isInstanceOf(o, function () {}); // returns `false' |
* </code></pre> |
* |
* NOTE: This method has previously been provided by {@link types.js}; |
* optimizations in code reuse moved it here. |
* |
* @author (C) 2003, 2011, 2013, 2014 Thomas Lahn <js@PointedEars.de> |
* @param {Object} obj |
* Value to be determined an instance of <code>Constructor</code> |
* or inheriting from the constructor of <code>Constructor.prototype</code> |
* or an object in its prototype chain. |
* @param {Function} Constructor |
* Object to be determined the constructor associated with an |
* object in the prototype chain of <var>obj</var>. |
* @return {boolean} |
* <code>true</code> if <code>obj</code> is an object constructed |
* with <var>Constructor</var>, <code>false</code> otherwise. |
*/ |
isInstanceOf: function jsx_object_isInstanceOf (obj, Constructor) { |
if (!_isObject(obj)) |
{ |
return false; |
} |
/** |
* Emulates the <code>instanceof</code> operator |
* of ECMAScript Edition 3 and later. |
* |
* Uses <code>Object.getPrototypeOf</code> (ECMAScript Ed. 3 and later) |
* or the proprietary <code>__proto__</code> property (JavaScript 1.3 |
* and later, and compatible implementations). |
* |
* Example: |
* <pre><code> |
* var o = new Object(); |
* o instanceof Object; // yields `true' |
* |
* function Foo() {} |
* var o = new Foo(); |
* o instanceof Object; // yields `true' |
* o instanceof Foo; // yields `true' also |
* |
* var _isInstanceOf = jsx.object.isInstanceOf; |
* _isInstanceOf(o, Object); // returns `true' |
* _isInstanceOf(o, Foo); // returns `true' also |
* _isInstanceOf(o, function () {}); // returns `false' |
* </code></pre> |
* |
* NOTE: This method has previously been provided by {@link types.js}; |
* optimizations in code reuse moved it here. |
* |
* @author (C) 2003, 2011, 2013, 2014 Thomas Lahn <js@PointedEars.de> |
* @param {Object} obj |
* Value to be determined an instance of <code>Constructor</code> |
* or inheriting from the constructor of <code>Constructor.prototype</code> |
* or an object in its prototype chain. |
* @param {Function} Constructor |
* Object to be determined the constructor associated with an |
* object in the prototype chain of <var>obj</var>. |
* @return {boolean} |
* <code>true</code> if <code>obj</code> is an object constructed |
* with <var>Constructor</var>, <code>false</code> otherwise. |
*/ |
isInstanceOf: function jsx_object_isInstanceOf (obj, Constructor) { |
if (!_isObject(obj)) |
{ |
return false; |
} |
|
var proto = Constructor.prototype; |
var proto = Constructor.prototype; |
|
if (!_isObject(proto)) |
{ |
return jsx.throwThis("TypeError", |
["Expecting a function in instanceof check, but got " + Constructor], |
jsx_object_isInstanceOf); |
} |
|
while ((obj = _getProto(obj))) |
{ |
if (proto == obj) |
if (!_isObject(proto)) |
{ |
return true; |
return jsx.throwThis("TypeError", |
["Expecting a function in instanceof check, but got " + Constructor], |
jsx_object_isInstanceOf); |
} |
} |
|
return false; |
}, |
|
/** |
* Returns the name of a function |
* |
* @param {Function|String} aFunction |
* @return {string} |
* The name of a function if it has one; the empty string otherwise. |
*/ |
getFunctionName: function (aFunction) { |
/* TODO: Cache expression */ |
var rx, _RegExp; |
|
if ((_RegExp = _getFeature(jsx, "regexp", "RegExp"))) |
{ |
jsx.tryThis( |
function () { |
rx = new _RegExp("^\\s*function\\s+(" + _srxIdentifierName + ")"); |
}, |
function (e) { |
jsx.warn("Could not use Unicode character properties: " + e.message); |
while ((obj = _getProto(obj))) |
{ |
if (proto == obj) |
{ |
return true; |
} |
); |
} |
else |
{ |
jsx.warn("jsx.regexp.RegExp not loaded."); |
} |
} |
|
if (!rx) |
{ |
jsx.warn("Non-ASCII identifiers cannot be parsed."); |
rx = /^\s*function\s+([A-Za-z_]\w*)/; |
} |
return false; |
}, |
|
/* Return the empty string for null or undefined */ |
return (aFunction != null |
&& typeof aFunction.name != "undefined" && aFunction.name) |
|| (String(aFunction).match(rx) || [, ""])[1]; |
}, |
/** |
* Returns the name of a function |
* |
* @param {Function|String} aFunction |
* @return {string} |
* The name of a function if it has one; the empty string otherwise. |
*/ |
getFunctionName: function (aFunction) { |
/* TODO: Cache expression */ |
var rx, _RegExp; |
|
/** |
* Returns minimum documentation for a function |
* |
* @param {Function|String} aFunction |
* @return {string} |
*/ |
getDoc: function (aFunction) { |
return (String(aFunction).match( |
/^\s*(function(\s+[A-Za-z_]\w*)?\s*\([^\)]*\))/) || [, ""])[1]; |
}, |
if ((_RegExp = _getFeature(jsx, "regexp", "RegExp"))) |
{ |
jsx.tryThis( |
function () { |
rx = new _RegExp("^\\s*function\\s+(" + _srxIdentifierName + ")"); |
}, |
function (e) { |
jsx.warn("Could not use Unicode character properties: " + e.message); |
} |
); |
} |
else |
{ |
jsx.warn("jsx.regexp.RegExp not loaded."); |
} |
|
/** |
* Retrieves the value of a property of an object |
* |
* @param {Object} obj |
* @param {string} sProperty |
* @param aDefault |
* @return {any} |
* @throws {@link #PropertyError} if the property |
* does not exist or has the <code>undefined</code> value, and |
* <var>aDefault</var> was not provided |
*/ |
getProperty: function (obj, sProperty, aDefault) { |
if (typeof obj[sProperty] != "undefined") |
{ |
return obj[sProperty]; |
} |
if (!rx) |
{ |
jsx.warn("Non-ASCII identifiers cannot be parsed."); |
rx = /^\s*function\s+([A-Za-z_]\w*)/; |
} |
|
/* default value not passed */ |
if (arguments.length < 3) |
{ |
return jsx.throwThis("jsx.object.PropertyError", sProperty); |
} |
/* Return the empty string for null or undefined */ |
return (aFunction != null |
&& typeof aFunction.name != "undefined" && aFunction.name) |
|| (String(aFunction).match(rx) || [, ""])[1]; |
}, |
|
return aDefault; |
} |
}; |
|
return jsx_object; |
}()); |
|
/** |
* Prints debug messages to the script console. |
* |
* NOTE: This method has previously been provided by |
* {@link debug.js}; optimizations in code reuse |
* moved it here. |
* |
* @function |
*/ |
jsx.dmsg = (function () { |
var |
_isMethod = jsx.object.isMethod, |
msgMap = { |
data: { |
info: "INFO", |
warn: "WARNING", |
debug: "DEBUG" |
/** |
* Returns minimum documentation for a function |
* |
* @param {Function|String} aFunction |
* @return {string} |
*/ |
getDoc: function (aFunction) { |
return (String(aFunction).match( |
/^\s*(function(\s+[A-Za-z_]\w*)?\s*\([^\)]*\))/) || [, ""])[1]; |
}, |
|
getString: function (s) { |
var data = this.data; |
/** |
* Retrieves the value of a property of an object |
* |
* @param {Object} obj |
* @param {string} sProperty |
* @param aDefault |
* @return {any} |
* @throws {@link #PropertyError} if the property |
* does not exist or has the <code>undefined</code> value, and |
* <var>aDefault</var> was not provided |
*/ |
getProperty: function (obj, sProperty, aDefault) { |
if (typeof obj[sProperty] != "undefined") |
{ |
return obj[sProperty]; |
} |
|
if (typeof data[s] != "undefined") |
/* default value not passed */ |
if (arguments.length < 3) |
{ |
return data[s] + ": "; |
return jsx.throwThis("jsx.object.PropertyError", sProperty); |
} |
|
return ""; |
return aDefault; |
} |
}; |
|
return jsx_object; |
}()); |
|
/** |
* @param {string} sMsg |
* Message to be printed |
* @param {string} sType = "log" |
* Type of the message. Supported values include |
* <code>"log"</code> (default), <code>"info"</code>, <code>"warn"</code>, |
* and <code>"debug"</code>. If a script console does not support |
* a message type, the default value is used. |
* @return {boolean} |
* <code>true</code> if it was possible to cause the message to be printed; |
* <code>false</code> otherwise. |
* Prints debug messages to the script console. |
* |
* NOTE: This method has previously been provided by |
* {@link debug.js}; optimizations in code reuse |
* moved it here. |
* |
* @function |
*/ |
return function (sMsg, sType) { |
/* Firebug 0.4+ and others */ |
if (typeof console != "undefined") |
{ |
if (!sType || !_isMethod(console, sType) && sType != "log") |
jsx.dmsg = (function () { |
var |
_isMethod = jsx.object.isMethod, |
msgMap = { |
data: { |
info: "INFO", |
warn: "WARNING", |
debug: "DEBUG" |
}, |
|
getString: function (s) { |
var data = this.data; |
|
if (typeof data[s] != "undefined") |
{ |
return data[s] + ": "; |
} |
|
return ""; |
} |
}; |
|
/** |
* @param {string} sMsg |
* Message to be printed |
* @param {string} sType = "log" |
* Type of the message. Supported values include |
* <code>"log"</code> (default), <code>"info"</code>, <code>"warn"</code>, |
* and <code>"debug"</code>. If a script console does not support |
* a message type, the default value is used. |
* @return {boolean} |
* <code>true</code> if it was possible to cause the message to be printed; |
* <code>false</code> otherwise. |
*/ |
return function (sMsg, sType) { |
/* Firebug 0.4+ and others */ |
if (typeof console != "undefined") |
{ |
sMsg = msgMap.getString(sType) + sMsg; |
sType = "log"; |
} |
if (!sType || !_isMethod(console, sType) && sType != "log") |
{ |
sMsg = msgMap.getString(sType) + sMsg; |
sType = "log"; |
} |
|
if (sType != "info") |
{ |
sMsg += "\n" + jsx.getStackTrace(); |
if (sType != "info") |
{ |
sMsg += "\n" + jsx.getStackTrace(); |
} |
|
if (_isMethod(console, sType)) |
{ |
/* MSHTML's console methods do not implement call() */ |
Function.prototype.call.call(console[sType], console, sMsg); |
return true; |
} |
} |
|
if (_isMethod(console, sType)) |
else if (typeof opera != "undefined" |
&& _isMethod(opera, "postError")) |
{ |
/* MSHTML's console methods do not implement call() */ |
Function.prototype.call.call(console[sType], console, sMsg); |
opera.postError(msgMap.getString(sType) + sMsg); |
return true; |
} |
} |
else if (typeof opera != "undefined" |
&& _isMethod(opera, "postError")) |
{ |
opera.postError(msgMap.getString(sType) + sMsg); |
return true; |
} |
|
return false; |
return false; |
}; |
}()); |
|
/** |
* Issues an info message, if possible. |
* |
* @param {String} sMsg |
* Message |
* @see jsx#dmsg |
*/ |
jsx.info = function (sMsg) { |
return jsx.dmsg(sMsg, jsx.MSG_INFO); |
}; |
}()); |
|
/** |
* Issues an info message, if possible. |
* |
* @param {String} sMsg |
* Message |
* @see jsx#dmsg |
*/ |
jsx.info = function (sMsg) { |
return jsx.dmsg(sMsg, jsx.MSG_INFO); |
}; |
/** |
* Issues a warning, if possible. |
* |
* @param {String} sMsg |
* Message |
* @see jsx#dmsg |
*/ |
jsx.warn = function (sMsg) { |
return jsx.dmsg(sMsg, jsx.MSG_WARN); |
}; |
|
/** |
* Issues a warning, if possible. |
* |
* @param {String} sMsg |
* Message |
* @see jsx#dmsg |
*/ |
jsx.warn = function (sMsg) { |
return jsx.dmsg(sMsg, jsx.MSG_WARN); |
}; |
/** |
* Issues an error message, if possible. |
* |
* @param {string} sMsg Message |
* @see jsx#dmsg |
*/ |
jsx.error = function (sMsg) { |
return jsx.dmsg(sMsg, jsx.MSG_ERROR); |
}; |
|
/** |
* Issues an error message, if possible. |
* |
* @param {string} sMsg Message |
* @see jsx#dmsg |
*/ |
jsx.error = function (sMsg) { |
return jsx.dmsg(sMsg, jsx.MSG_ERROR); |
}; |
|
/** |
* Clears the handler for the proprietary <code>error</code> event. |
* |
* NOTE: This method has previously been provided by {@link debug.js}; |
* optimizations in code reuse moved it here. |
* |
* @return {boolean} <code>true</code> |
*/ |
/* |
* NOTE: Initialization must come before the initialization of |
* setErrorHandler() as it is used in a closure there, |
* see Message-ID <2152411.FhMhkbZ0Pk@PointedEars.de> |
*/ |
jsx.clearErrorHandler = function () { |
if (typeof window != "undefined" && window !== null) |
{ |
/* |
* debug.js 0.99.5.2006041101 BUGFIX: |
* onerror is defined as a property of window, not of the Global Object |
*/ |
window.onerror = null; |
} |
|
return true; |
}; |
|
/** |
* Sets the handler for the proprietary <code>error</code> event. |
* |
* NOTE: This method has previously been provided by {@link debug.js}; |
* and {@link types.js}; optimizations in code reuse moved it here. |
* |
* @function |
*/ |
jsx.setErrorHandler = (function () { |
var |
jsx_object = jsx.object, |
jsx_clearErrorHandler = jsx.clearErrorHandler; |
|
/** |
* @param {Callable} fHandler |
* @return {boolean} |
* <code>true</code> if the error handler could be assigned to |
* successfully, <code>false</code> otherwise. Note that one reason |
* for failure can be that an event handler is no longer supported |
* by the UA's DOM due to efforts towards adherence to Web standards. |
* Clears the handler for the proprietary <code>error</code> event. |
* |
* NOTE: This method has previously been provided by {@link debug.js}; |
* optimizations in code reuse moved it here. |
* |
* @return {boolean} <code>true</code> |
*/ |
return function (fHandler) { |
/* |
* NOTE: There is no deadlock here because even if `fHandler' is a string, |
* `isMethod(fHandler)' will call `setErrorHandler()' without arguments; |
* so fHandler in that call will be `undefined' and `setErrorHandler()' |
* is not called again. |
*/ |
if (!jsx_object.isMethod(fHandler)) |
/* |
* NOTE: Initialization must come before the initialization of |
* setErrorHandler() as it is used in a closure there, |
* see Message-ID <2152411.FhMhkbZ0Pk@PointedEars.de> |
*/ |
jsx.clearErrorHandler = function () { |
if (typeof window != "undefined" && window !== null) |
{ |
fHandler = jsx_clearErrorHandler; |
} |
|
if (typeof assertFalse == "function") |
{ |
assertFalse(typeof fHandler == "undefined", false, |
"jsx.setErrorHandler(fHandler)"); |
} |
|
if (typeof window != "undefined" && window !== null |
&& typeof fHandler != "undefined") |
{ |
/* |
* debug.js 0.99.5.2006041101 BUGFIX: |
* onerror is defined as a property of window, not of the Global Object |
*/ |
window.onerror = fHandler; |
window.onerror = null; |
} |
|
return (typeof window.onerror != "undefined" |
&& window.onerror == fHandler); |
return true; |
}; |
}()); |
|
/** |
* Sets the handler for the proprietary <code>error</code> event. |
* |
* NOTE: This method has previously been provided by {@link debug.js}; |
* and {@link types.js}; optimizations in code reuse moved it here. |
* |
* @function |
*/ |
jsx.setErrorHandler = (function () { |
var |
jsx_object = jsx.object, |
jsx_clearErrorHandler = jsx.clearErrorHandler; |
|
/** |
* @param {Callable} fHandler |
* @return {boolean} |
* <code>true</code> if the error handler could be assigned to |
* successfully, <code>false</code> otherwise. Note that one reason |
* for failure can be that an event handler is no longer supported |
* by the UA's DOM due to efforts towards adherence to Web standards. |
*/ |
return function (fHandler) { |
/* |
* NOTE: There is no deadlock here because even if `fHandler' is a string, |
* `isMethod(fHandler)' will call `setErrorHandler()' without arguments; |
* so fHandler in that call will be `undefined' and `setErrorHandler()' |
* is not called again. |
*/ |
if (!jsx_object.isMethod(fHandler)) |
{ |
fHandler = jsx_clearErrorHandler; |
} |
|
if (typeof assertFalse == "function") |
{ |
assertFalse(typeof fHandler == "undefined", false, |
"jsx.setErrorHandler(fHandler)"); |
} |
|
if (typeof window != "undefined" && window !== null |
&& typeof fHandler != "undefined") |
{ |
/* |
* debug.js 0.99.5.2006041101 BUGFIX: |
* onerror is defined as a property of window, not of the Global Object |
*/ |
window.onerror = fHandler; |
} |
|
return (typeof window.onerror != "undefined" |
&& window.onerror == fHandler); |
}; |
}()); |
}(this)); |
|
/** |
* Throws an exception, including an execution context hint if provided, |
* followed by an error message. |
1965,1521 → 1968,1553 |
eval("throw exception"); |
}; |
|
jsx.object.extend(jsx, { |
/** |
* Holds the runtime options for JSX. |
* |
* Due to the dynamic nature of ECMAScript, it is very flexible. |
* Built-in objects can be augmented and built-in methods can be |
* overwritten to allow for "syntactic sugar" that make programs |
* easier to write and to read, should the implementation not |
* already provide suitable features. However, augmentation |
* and replacement do have disadvantages if you are not aware |
* of the fact. Allowing for a maximum of flexibility, JSX |
* uses options that govern to which degree JSX components may |
* modify built-in objects. Options include, with increasing |
* degree of flexibility and side-effects: |
* |
* <table> |
* <thead> |
* <tr> |
* <td></td> |
* <th>Modify built-ins</th> |
* <th>Augment built-ins</th> |
* <th>Augment built-in prototypes</th> |
* <th>Augment <code>Object</code> prototype</th> |
* </tr> |
* </thead> |
* <tbody> |
* <tr> |
* <th><code>augmentBuiltins</code></th> |
* <td>yes</td> |
* <td>yes</td> |
* <td>no</td> |
* <td>no</td> |
* </tr> |
* <tr> |
* <th><code>augmentPrototypes</code></th> |
* <td>yes</td> |
* <td>yes</td> |
* <td>yes</td> |
* <td>no</td> |
* </tr> |
* <tr> |
* <th><code>augmentObjectPrototype</code></th> |
* <td>yes</td> |
* <td>yes</td> |
* <td>yes</td> |
* <td>yes</td> |
* </tr> |
* <tr> |
* <th><code>replaceBuiltins</code></th> |
* <td>yes</td> |
* <td>depends</td> |
* <td>depends</td> |
* <td>depends</td> |
* </tr> |
* </tbody> |
* </table> |
* |
* <dl> |
* <dt><code>augmentBuiltins</code></dt> |
* <dd>Allow built-ins to be augmented with new |
* properties. This allows new properties on |
* the built-in constructors, but not on |
* prototype objects of built-in objects. |
* (See <code>augmentPrototypes</code>.) |
* Since there usually is no harm in that, |
* the default is <code>true</code>. |
* Set to <code>false</code> if you are testing features |
* of ECMAScript implementations with JSX, |
* like with the |
* {@link http://PointedEars.de/es-matrix ECMAScript Support Matrix}. |
* <dl> |
* <dt><code>augmentPrototypes</code></dt> |
* <dd>Allow prototype objects to be augmented, |
* except <code>Object.prototype</code>. |
* This allows for new, inherited methods for |
* <code>String</code>s, for example. |
* Since there usually is no harm in that, the |
* default is <code>true</code>. |
* <dl> |
* <dt><code>augmentObjectPrototype</code></dt> |
* <dd>Allow <code>Object.prototype</code> |
* to be augmented. <em>CAUTION: |
* The new properties are inherited |
* to all native objects, and |
* host objects that have |
* <code>Object.prototype</code> |
* in their prototype chain. The new |
* properties will show up everywhere, |
* including <code>for-in</code> |
* iteration. If you do not know |
* what this is all about, leave it |
* at the default <code>false</code>.</em></dd> |
* </dl> |
* </dd> |
* <dt><code>replaceBuiltins</code></dt> |
* <dd>Allow built-ins to be replaced with native user-defined |
* implementations.</dd> |
* </dl> |
* @namespace |
* @memberOf jsx |
*/ |
options: {} |
}); |
(function (global) { |
jsx.object.extend(jsx, { |
/** |
* Holds the runtime options for JSX. |
* |
* Due to the dynamic nature of ECMAScript, it is very flexible. |
* Built-in objects can be augmented and built-in methods can be |
* overwritten to allow for "syntactic sugar" that make programs |
* easier to write and to read, should the implementation not |
* already provide suitable features. However, augmentation |
* and replacement do have disadvantages if you are not aware |
* of the fact. Allowing for a maximum of flexibility, JSX |
* uses options that govern to which degree JSX components may |
* modify built-in objects. Options include, with increasing |
* degree of flexibility and side-effects: |
* |
* <table> |
* <thead> |
* <tr> |
* <td></td> |
* <th>Modify built-ins</th> |
* <th>Augment built-ins</th> |
* <th>Augment built-in prototypes</th> |
* <th>Augment <code>Object</code> prototype</th> |
* </tr> |
* </thead> |
* <tbody> |
* <tr> |
* <th><code>augmentBuiltins</code></th> |
* <td>yes</td> |
* <td>yes</td> |
* <td>no</td> |
* <td>no</td> |
* </tr> |
* <tr> |
* <th><code>augmentPrototypes</code></th> |
* <td>yes</td> |
* <td>yes</td> |
* <td>yes</td> |
* <td>no</td> |
* </tr> |
* <tr> |
* <th><code>augmentObjectPrototype</code></th> |
* <td>yes</td> |
* <td>yes</td> |
* <td>yes</td> |
* <td>yes</td> |
* </tr> |
* <tr> |
* <th><code>replaceBuiltins</code></th> |
* <td>yes</td> |
* <td>depends</td> |
* <td>depends</td> |
* <td>depends</td> |
* </tr> |
* </tbody> |
* </table> |
* |
* <dl> |
* <dt><code>augmentBuiltins</code></dt> |
* <dd>Allow built-ins to be augmented with new |
* properties. This allows new properties on |
* the built-in constructors, but not on |
* prototype objects of built-in objects. |
* (See <code>augmentPrototypes</code>.) |
* Since there usually is no harm in that, |
* the default is <code>true</code>. |
* Set to <code>false</code> if you are testing features |
* of ECMAScript implementations with JSX, |
* like with the |
* {@link http://PointedEars.de/es-matrix ECMAScript Support Matrix}. |
* <dl> |
* <dt><code>augmentPrototypes</code></dt> |
* <dd>Allow prototype objects to be augmented, |
* except <code>Object.prototype</code>. |
* This allows for new, inherited methods for |
* <code>String</code>s, for example. |
* Since there usually is no harm in that, the |
* default is <code>true</code>. |
* <dl> |
* <dt><code>augmentObjectPrototype</code></dt> |
* <dd>Allow <code>Object.prototype</code> |
* to be augmented. <em>CAUTION: |
* The new properties are inherited |
* to all native objects, and |
* host objects that have |
* <code>Object.prototype</code> |
* in their prototype chain. The new |
* properties will show up everywhere, |
* including <code>for-in</code> |
* iteration. If you do not know |
* what this is all about, leave it |
* at the default <code>false</code>.</em></dd> |
* </dl> |
* </dd> |
* <dt><code>replaceBuiltins</code></dt> |
* <dd>Allow built-ins to be replaced with native user-defined |
* implementations.</dd> |
* </dl> |
* @namespace |
* @memberOf jsx |
*/ |
options: {} |
}); |
|
jsx.object.extend(jsx.options, { |
/** |
* If <code>false</code>, built-ins are not modified. |
* The default is <code>true</code>. |
* |
* @memberOf jsx.options |
* @type boolean |
*/ |
augmentBuiltins: true, |
jsx.object.extend(jsx.options, { |
/** |
* If <code>false</code>, built-ins are not modified. |
* The default is <code>true</code>. |
* |
* @memberOf jsx.options |
* @type boolean |
*/ |
augmentBuiltins: true, |
|
/** |
* If <code>false</code>, built-in prototypes are not modified. |
* The default is <code>true</code>. |
* |
* @type boolean |
*/ |
augmentPrototypes: true, |
|
/** |
* If <code>false</code> (default), the Object prototype object is |
* not modified. The default is <code>false</code>. |
* |
* @type boolean |
*/ |
augmentObjectPrototype: false, |
|
/** |
* If <code>false</code>, built-ins are not replaced. |
* The default is <code>true</code>. |
* |
* @type boolean |
*/ |
replaceBuiltins: true, |
|
/** |
* If <code>false</code>, missing language features are not emulated. |
* The default is <code>true</code>. |
* <p> |
* WARNING: JSX features may depend on emulation; intended for |
* testing only. |
* </p> |
* @type boolean |
*/ |
emulate: true |
}); |
|
if (jsx.options.emulate) |
{ |
jsx.object.extend(jsx.options, { |
augmentBuiltins: true, |
/** |
* If <code>false</code>, built-in prototypes are not modified. |
* The default is <code>true</code>. |
* |
* @type boolean |
*/ |
augmentPrototypes: true, |
replaceBuiltins: true |
}, jsx.object.ADD_OVERWRITE); |
} |
|
if (jsx.options.augmentBuiltins) |
{ |
jsx.object.extend(Object, { |
/** |
* @see jsx.object.defineProperty |
* If <code>false</code> (default), the Object prototype object is |
* not modified. The default is <code>false</code>. |
* |
* @type boolean |
*/ |
defineProperty: jsx.object.defineProperty, |
augmentObjectPrototype: false, |
|
/** |
* @see jsx.object.defineProperties |
* If <code>false</code>, built-ins are not replaced. |
* The default is <code>true</code>. |
* |
* @type boolean |
*/ |
defineProperties: jsx.object.defineProperties |
replaceBuiltins: true, |
|
/** |
* If <code>false</code>, missing language features are not emulated. |
* The default is <code>true</code>. |
* <p> |
* WARNING: JSX features may depend on emulation; intended for |
* testing only. |
* </p> |
* @type boolean |
*/ |
emulate: true |
}); |
|
if (typeof Object.create != "function") |
if (jsx.options.emulate) |
{ |
/** |
* Creates a new object and initializes its properties. |
* |
* Emulation of the Object.create() method from ES 5.1, |
* section 15.2.3.5. |
* |
* @function |
*/ |
Object.create = jsx.object.extend( |
jsx.object.extend(jsx.options, { |
augmentBuiltins: true, |
augmentPrototypes: true, |
replaceBuiltins: true |
}, jsx.object.ADD_OVERWRITE); |
} |
|
if (jsx.options.augmentBuiltins) |
{ |
jsx.object.extend(Object, { |
/** |
* @param {Object|Null} prototype |
* @param {Object} descriptor (optional) |
* Properties descriptor, where each own property name |
* is a property name of the new object, and each corresponding |
* property value is a reference to an object that defines the |
* attributes of that property. Supported properties of |
* that defining object include <code>value</code> only |
* at this time. |
* @return {Object} Reference to the new object |
* @see jsx.object.defineProperty |
*/ |
function (prototype, descriptor) { |
var o = jsx.object.inheritFrom(prototype); |
defineProperty: jsx.object.defineProperty, |
|
if (typeof descriptor != "undefined") |
{ |
Object.defineProperties(o, descriptor); |
} |
/** |
* @see jsx.object.defineProperties |
*/ |
defineProperties: jsx.object.defineProperties |
}); |
|
return o; |
}, |
{ |
if (typeof Object.create != "function") |
{ |
/** |
* Creates a new object and initializes its properties. |
* |
* Emulation of the Object.create() method from ES 5.1, |
* section 15.2.3.5. |
* |
* @function |
*/ |
Object.create = jsx.object.extend( |
/** |
* @memberOf Object.create |
* @param {Object|Null} prototype |
* @param {Object} descriptor (optional) |
* Properties descriptor, where each own property name |
* is a property name of the new object, and each corresponding |
* property value is a reference to an object that defines the |
* attributes of that property. Supported properties of |
* that defining object include <code>value</code> only |
* at this time. |
* @return {Object} Reference to the new object |
*/ |
_emulated: true |
} |
); |
} |
function (prototype, descriptor) { |
var o = jsx.object.inheritFrom(prototype); |
|
if (typeof Object.keys != "function") |
{ |
/** |
* @param {Object} obj |
*/ |
Object.keys = function (obj) { |
return jsx.object.getKeys(obj); |
}; |
if (typeof descriptor != "undefined") |
{ |
Object.defineProperties(o, descriptor); |
} |
|
Object.keys._emulated = true; |
} |
return o; |
}, |
{ |
/** |
* @memberOf Object.create |
*/ |
_emulated: true |
} |
); |
} |
|
if (typeof Object.values != "function") |
{ |
/** |
* @param {Object} obj |
*/ |
Object.values = function (obj) { |
return Object.keys(obj).map(function (key) { |
return this[key]; |
}, obj); |
}; |
if (typeof Object.keys != "function") |
{ |
/** |
* @param {Object} obj |
*/ |
Object.keys = function (obj) { |
return jsx.object.getKeys(obj); |
}; |
|
Object.values._emulated = true; |
} |
Object.keys._emulated = true; |
} |
|
if (typeof Object.forKeys != "function") |
{ |
/** |
* Executes a callback for all keys of an object |
* |
* @param {Object} obj |
* @param {Object} callback |
* @param {Object} thisValue |
*/ |
Object.forKeys = function (obj, callback, thisValue) { |
return Object.keys(obj).forEach(function (key) { |
return callback.call(thisValue || this, this[key], key, thisValue || this); |
}, obj); |
}; |
if (typeof Object.values != "function") |
{ |
/** |
* @param {Object} obj |
*/ |
Object.values = function (obj) { |
return Object.keys(obj).map(function (key) { |
return this[key]; |
}, obj); |
}; |
|
Object.forKeys._emulated = true; |
} |
Object.values._emulated = true; |
} |
|
if (typeof Object.assign != "function") |
{ |
/** |
* Copy the values of all of the enumerable own properties |
* from one or more source objects to a target object. |
* |
* @param {Object} target |
* @params {Object} sources |
* @return {Object} |
* @see http://ecma-international.org/ecma-262/6.0/index.html#sec-object.assign |
*/ |
Object.assign = function (target) { |
function toObject (o) |
{ |
if (o == null) |
if (typeof Object.forKeys != "function") |
{ |
/** |
* Executes a callback for all keys of an object |
* |
* @param {Object} obj |
* @param {Object} callback |
* @param {Object} thisValue |
*/ |
Object.forKeys = function (obj, callback, thisValue) { |
return Object.keys(obj).forEach(function (key) { |
return callback.call(thisValue || this, this[key], key, thisValue || this); |
}, obj); |
}; |
|
Object.forKeys._emulated = true; |
} |
|
if (typeof Object.assign != "function") |
{ |
/** |
* Copy the values of all of the enumerable own properties |
* from one or more source objects to a target object. |
* |
* @param {Object} target |
* @params {Object} sources |
* @return {Object} |
* @see http://ecma-international.org/ecma-262/6.0/index.html#sec-object.assign |
*/ |
Object.assign = function (target) { |
function toObject (o) |
{ |
throw new TypeError("Cannot convert to object: " + o + " : " + jsx.object.getClass(o) || typeof o); |
if (o == null) |
{ |
throw new TypeError("Cannot convert to object: " + o + " : " + jsx.object.getClass(o) || typeof o); |
} |
|
return new Object(o); |
} |
|
return new Object(o); |
} |
target = toObject(target); |
|
target = toObject(target); |
|
for (var i = 1, len = arguments.length; i < len; ++i) |
{ |
var source = arguments[i]; |
if (source) |
for (var i = 1, len = arguments.length; i < len; ++i) |
{ |
Object.forKeys(source, function (value, key) { |
var desc = Object.getOwnPropertyDescriptor(this.source, key); |
var source = arguments[i]; |
if (source) |
{ |
Object.forKeys(source, function (value, key) { |
var desc = Object.getOwnPropertyDescriptor(this.source, key); |
|
if (typeof desc != "undefined" && desc.enumerable) |
{ |
Object.defineProperty(this.target, key, desc); |
} |
}, {target: target, source: source}); |
if (typeof desc != "undefined" && desc.enumerable) |
{ |
Object.defineProperty(this.target, key, desc); |
} |
}, {target: target, source: source}); |
} |
} |
} |
|
return target; |
}; |
} |
return target; |
}; |
} |
|
if (typeof Object.extend != "function") |
{ |
/** |
* Extends an object with properties from other objects. |
* |
* Different to {@link Object.assign} and {@link Object.merge}, |
* existing property values are overwritten, unless the property |
* value is an {@link Array}, in which case the values of the |
* corresponding properties of the sources are appended. |
* |
* @param {Object} obj |
* @params {Object} sources |
*/ |
Object.extend = function (obj) { |
for (var i = 1, len = arguments.length; i < len; ++i) |
{ |
var source = arguments[i]; |
if (typeof Object.extend != "function") |
{ |
/** |
* Extends an object with properties from other objects. |
* |
* Different to {@link Object.assign} and {@link Object.merge}, |
* existing property values are overwritten, unless the property |
* value is an {@link Array}, in which case the values of the |
* corresponding properties of the sources are appended. |
* |
* @param {Object} obj |
* @params {Object} sources |
*/ |
Object.extend = function (obj) { |
for (var i = 1, len = arguments.length; i < len; ++i) |
{ |
var source = arguments[i]; |
|
Object.forKeys(source, function (value, key, source) { |
if (!(jsx.object._hasOwnProperty(obj, key))) |
{ |
var desc = (typeof Object.getOwnPropertyDescriptor == "function") |
&& Object.getOwnPropertyDescriptor(source, key); |
if (desc && "value" in desc) |
Object.forKeys(source, function (value, key, source) { |
if (!(jsx.object._hasOwnProperty(obj, key))) |
{ |
desc.value = value; |
Object.defineProperty(obj, key, desc); |
var desc = (typeof Object.getOwnPropertyDescriptor == "function") |
&& Object.getOwnPropertyDescriptor(source, key); |
if (desc && "value" in desc) |
{ |
desc.value = value; |
Object.defineProperty(obj, key, desc); |
} |
else |
{ |
obj[key] = value; |
} |
} |
else |
{ |
obj[key] = value; |
if (Array.isArray(obj)) |
{ |
if (!Array.isArray(source)) |
{ |
source = Object.values(source); |
} |
|
obj.splice.apply(obj, [obj.length, 0].concat(source)); |
} |
else |
{ |
Object.extend(obj[key], value); |
} |
} |
} |
else |
{ |
if (Array.isArray(obj)) |
}, source); |
|
return obj; |
} |
}; |
|
Object.extend._emulated = true; |
} |
|
if (typeof Object.merge != "function") |
{ |
/** |
* Merges the properties of one or more objects with |
* the <var>target</var> object. |
* |
* @param target |
* @return Object |
*/ |
Object.merge = function (target) { |
var clone = Object.clone(target, true); |
|
for (var i = 1, len = arguments.length; i < len; ++i) |
{ |
var arg = arguments[i]; |
|
Object.getOwnPropertyNames(target).forEach(function (name) { |
var sourceValue = this.source[name]; |
|
if (name in this.clone) |
{ |
if (!Array.isArray(source)) |
if (!Array.isArray(this.clone[name])) |
{ |
source = Object.values(source); |
this.target[name] = [this.target[name]]; |
} |
|
obj.splice.apply(obj, [obj.length, 0].concat(source)); |
this.target[name].push(sourceValue); |
} |
else |
{ |
Object.extend(obj[key], value); |
this.target[name] = sourceValue; |
} |
} |
}, source); |
|
return obj; |
} |
}; |
}, {target: clone, source: arg}); |
} |
|
Object.extend._emulated = true; |
return clone; |
}; |
} |
} |
|
if (typeof Object.merge != "function") |
{ |
/** |
* Gets the stack trace of the calling execution context. |
* |
* Based on getStackTrace() from jsUnit 2.2alpha of 2006-03-24. |
* |
* @return {string} |
* The stack trace of the calling execution context, if available. |
*/ |
jsx.getStackTrace = function () { |
/** |
* Merges the properties of one or more objects with |
* the <var>target</var> object. |
* |
* @param target |
* @return Object |
* @private |
* @param {Error} excp |
*/ |
Object.merge = function (target) { |
var clone = Object.clone(target, true); |
function parseErrorStack(excp) |
{ |
var stack = []; |
|
for (var i = 1, len = arguments.length; i < len; ++i) |
if (excp && excp.stack) |
{ |
var arg = arguments[i]; |
var stacklist = excp.stack.split('\n'); |
|
Object.getOwnPropertyNames(target).forEach(function (name) { |
var sourceValue = this.source[name]; |
// for (var i = 0; i < stacklist.length - 1; i++) |
// { |
// var framedata = stacklist[i]; |
// |
// var name = framedata.match(/^\s*(at\s+)?(\w*)/)[2]; |
// if (!name) |
// { |
// name = 'anonymous'; |
// } |
// |
// stack.push(name); |
// } |
stack = stacklist; |
|
if (name in this.clone) |
{ |
if (!Array.isArray(this.clone[name])) |
{ |
this.target[name] = [this.target[name]]; |
} |
|
this.target[name].push(sourceValue); |
} |
else |
{ |
this.target[name] = sourceValue; |
} |
|
}, {target: clone, source: arg}); |
/* remove top level anonymous functions to match JScript */ |
// while (stack.length && stack[stack.length - 1] == 'anonymous') |
// { |
// stack.length = stack.length - 1; |
// } |
} |
|
return clone; |
}; |
} |
} |
|
/** |
* Gets the stack trace of the calling execution context. |
* |
* Based on getStackTrace() from jsUnit 2.2alpha of 2006-03-24. |
* |
* @return {string} |
* The stack trace of the calling execution context, if available. |
*/ |
jsx.getStackTrace = function () { |
/** |
* @private |
* @param {Error} excp |
*/ |
function parseErrorStack(excp) |
{ |
var stack = []; |
|
if (excp && excp.stack) |
{ |
var stacklist = excp.stack.split('\n'); |
|
// for (var i = 0; i < stacklist.length - 1; i++) |
// { |
// var framedata = stacklist[i]; |
// |
// var name = framedata.match(/^\s*(at\s+)?(\w*)/)[2]; |
// if (!name) |
// { |
// name = 'anonymous'; |
// } |
// |
// stack.push(name); |
// } |
stack = stacklist; |
|
/* remove top level anonymous functions to match JScript */ |
// while (stack.length && stack[stack.length - 1] == 'anonymous') |
// { |
// stack.length = stack.length - 1; |
// } |
return stack; |
} |
|
return stack; |
} |
var result = ''; |
|
var result = ''; |
|
if (jsx.object.hasOwnProperty(arguments, "caller") && arguments.caller) |
{ |
/* JScript and older JavaScript */ |
for (var a = arguments.caller; a != null; a = a.caller) |
if (jsx.object.hasOwnProperty(arguments, "caller") && arguments.caller) |
{ |
result += '> ' + (jsx.object.getFunctionName(a.callee) || "anonymous") |
+ '\n'; |
if (a.caller == a) |
/* JScript and older JavaScript */ |
for (var a = arguments.caller; a != null; a = a.caller) |
{ |
result += '*'; |
break; |
result += '> ' + (jsx.object.getFunctionName(a.callee) || "anonymous") |
+ '\n'; |
if (a.caller == a) |
{ |
result += '*'; |
break; |
} |
} |
} |
} |
else |
{ |
/* other */ |
if (typeof Error != "function") |
else |
{ |
return result; |
/* other */ |
if (typeof Error != "function") |
{ |
return result; |
} |
|
var stack = parseErrorStack(new Error()); |
result = stack.slice(2).join("\n"); |
// for (var i = 1; i < stack.length; i++) |
// { |
// result += '> ' + stack[i] + '\n'; |
// } |
} |
|
var stack = parseErrorStack(new Error()); |
result = stack.slice(2).join("\n"); |
// for (var i = 1; i < stack.length; i++) |
// { |
// result += '> ' + stack[i] + '\n'; |
// } |
} |
return result; |
}; |
|
return result; |
}; |
|
jsx.object.extend(jsx, { |
/** |
* Reference to the ECMAScript Global Object |
* @memberOf jsx |
* @type Global |
*/ |
global: global, |
|
jsx.object.extend(jsx, { |
/** |
* Reference to the ECMAScript Global Object |
* @memberOf jsx |
* @type Global |
*/ |
global: this, |
MSG_INFO: "info", |
MSG_WARN: "warn", |
MSG_ERROR: "error", |
MSG_DEBUG: "debug" |
}, jsx.object.ADD_OVERWRITE); |
|
MSG_INFO: "info", |
MSG_WARN: "warn", |
MSG_ERROR: "error", |
MSG_DEBUG: "debug" |
}, jsx.object.ADD_OVERWRITE); |
|
/** |
* @namespace |
*/ |
jsx.array = (function (jsx_object) { |
var _isMethod = jsx_object.isMethod; |
|
/** |
* Returns <code>true</code> if a value can be used |
* as array index. |
* |
* @return {boolean} |
* <code>true</code> if a value can be used |
* as array index, i.e. can be converted to an integer |
* (may be out of ES 5.1 index range); |
* <code>false</code> otherwise. |
* @namespace |
*/ |
function jsx_array_isIndex (index) |
{ |
/* Exclude NaN and non-integers */ |
index = +index; |
return ((index == index) && (index % 1 == 0)); |
} |
jsx.array = (function (jsx_object) { |
var _isMethod = jsx_object.isMethod; |
|
return { |
/** |
* @memberOf jsx.array |
*/ |
version: jsx.object.version, |
|
/** |
* Maps elements of an <code>Array</code>-like object |
* to named properties of another object. |
* Returns <code>true</code> if a value can be used |
* as array index. |
* |
* <p>NOTE: Equivalent to Array destructuring (JavaScript 1.7+):</p> |
* <pre><code>var o = jsx.array.destructure(["bar", "foo"], ["foo", "bar"]);</code></pre> |
* is equivalent to |
* <pre><code>var o = {}; |
* [o.foo, o.bar] = ["bar", "foo"];</code></pre> |
* |
* @param {Object} a |
* <code>Array</code>-like object whose elements should be mapped. |
* @param {Array} properties |
* Names of the properties that array elements should be mapped to. |
* If an element of this <code>Array</code> is <code>undefined</code> |
* or <code>null</code> (the former can be facilitated with |
* omitting the element value in an <code>Array</code> initialiser |
* when not the last element of this <code>Array</code>, |
* for backwards compatibility), the corresponding element of |
* <var>a</var> is not mapped. |
* @param {Object} oTarget |
* Target object. If a false-value, a new <code>Object</code> |
* instance is being created. |
* @return {Object} |
* <var>oTarget</var> or a new <code>Object</code> instance |
* augmented with the specified properties and values. |
* @return {boolean} |
* <code>true</code> if a value can be used |
* as array index, i.e. can be converted to an integer |
* (may be out of ES 5.1 index range); |
* <code>false</code> otherwise. |
*/ |
destructure: function (a, properties, oTarget) { |
var o = oTarget || jsx_object.getDataObject(); |
function jsx_array_isIndex (index) |
{ |
/* Exclude NaN and non-integers */ |
index = +index; |
return ((index == index) && (index % 1 == 0)); |
} |
|
/* More efficient with sparse arrays */ |
var keys = jsx_object.getKeys(properties); |
return { |
/** |
* @memberOf jsx.array |
*/ |
version: jsx.object.version, |
|
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
var index = keys[i]; |
if (jsx_array_isIndex(index)) |
/** |
* Maps elements of an <code>Array</code>-like object |
* to named properties of another object. |
* |
* <p>NOTE: Equivalent to Array destructuring (JavaScript 1.7+):</p> |
* <pre><code>var o = jsx.array.destructure(["bar", "foo"], ["foo", "bar"]);</code></pre> |
* is equivalent to |
* <pre><code>var o = {}; |
* [o.foo, o.bar] = ["bar", "foo"];</code></pre> |
* |
* @param {Object} a |
* <code>Array</code>-like object whose elements should be mapped. |
* @param {Array} properties |
* Names of the properties that array elements should be mapped to. |
* If an element of this <code>Array</code> is <code>undefined</code> |
* or <code>null</code> (the former can be facilitated with |
* omitting the element value in an <code>Array</code> initialiser |
* when not the last element of this <code>Array</code>, |
* for backwards compatibility), the corresponding element of |
* <var>a</var> is not mapped. |
* @param {Object} oTarget |
* Target object. If a false-value, a new <code>Object</code> |
* instance is being created. |
* @return {Object} |
* <var>oTarget</var> or a new <code>Object</code> instance |
* augmented with the specified properties and values. |
*/ |
destructure: function (a, properties, oTarget) { |
var o = oTarget || jsx_object.getDataObject(); |
|
/* More efficient with sparse arrays */ |
var keys = jsx_object.getKeys(properties); |
|
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
var propertyName = properties[index]; |
if (propertyName != null) |
var index = keys[i]; |
if (jsx_array_isIndex(index)) |
{ |
o[propertyName] = a[i]; |
var propertyName = properties[index]; |
if (propertyName != null) |
{ |
o[propertyName] = a[i]; |
} |
} |
} |
} |
|
return o; |
}, |
return o; |
}, |
|
isIndex: jsx_array_isIndex, |
isIndex: jsx_array_isIndex, |
|
/** |
* Maps one array to another |
* |
* @return {Array} |
* <var>array</var> with <var>callback</var> applied to each element. |
* @see ECMAScript Language Specification, Edition 5.1, section 15.4.4.19 |
* @param {Array} array |
* Array to be mapped |
* @param {Callable} callback |
* @param {Object} oThis (optional) |
*/ |
map: function (array, callback, oThis) { |
if (!_isMethod(callback)) |
{ |
return jsx.throwThis("TypeError", |
(_isMethod(callback, "toSource") ? callback.toSource() : callback) |
+ " is not callable", |
this + ".map"); |
} |
/** |
* Maps one array to another |
* |
* @return {Array} |
* <var>array</var> with <var>callback</var> applied to each element. |
* @see ECMAScript Language Specification, Edition 5.1, section 15.4.4.19 |
* @param {Array} array |
* Array to be mapped |
* @param {Callable} callback |
* @param {Object} oThis (optional) |
*/ |
map: function (array, callback, oThis) { |
if (!_isMethod(callback)) |
{ |
return jsx.throwThis("TypeError", |
(_isMethod(callback, "toSource") ? callback.toSource() : callback) |
+ " is not callable", |
this + ".map"); |
} |
|
var |
array_length = +array.length, |
res = []; |
var |
array_length = +array.length, |
res = []; |
|
/* More efficient with sparse arrays */ |
var keys = jsx_object.getKeys(array); |
keys.sort(function (a, b) { return a - b; }); |
/* More efficient with sparse arrays */ |
var keys = jsx_object.getKeys(array); |
keys.sort(function (a, b) { return a - b; }); |
|
/* Start with highest index to reduce .length updates */ |
for (var i = keys.length; i--;) |
{ |
var index = keys[i]; |
if (jsx_array_isIndex(index) && index < array_length) |
/* Start with highest index to reduce .length updates */ |
for (var i = keys.length; i--;) |
{ |
res[index] = callback.call(oThis, array[index], index, array); |
var index = keys[i]; |
if (jsx_array_isIndex(index) && index < array_length) |
{ |
res[index] = callback.call(oThis, array[index], index, array); |
} |
} |
|
return res; |
} |
}; |
}(jsx.object)); |
|
return res; |
/** |
* Returns an <code>Array</code> created from mapping items |
* of an Array-like object. |
* |
* @param {Object} iterable |
* <code>Array</code>-like object |
* @param {Function} builder (optional) |
* Mapping function whose return value specifies the |
* mapped value in the new <code>Array</code>. |
* Pass <code>null</code> for no mapping. |
* @param {Object} oThis (optional) |
* <code>this</code> value in the mapping function |
* @return {Array} |
* @see Array.prototype#map |
*/ |
jsx.array.from = function (iterable, builder, oThis) { |
if (arguments.length < 2) |
{ |
builder = null; |
} |
}; |
}(jsx.object)); |
|
/** |
* Returns an <code>Array</code> created from mapping items |
* of an Array-like object. |
* |
* @param {Object} iterable |
* <code>Array</code>-like object |
* @param {Function} builder (optional) |
* Mapping function whose return value specifies the |
* mapped value in the new <code>Array</code>. |
* Pass <code>null</code> for no mapping. |
* @param {Object} oThis (optional) |
* <code>this</code> value in the mapping function |
* @return {Array} |
* @see Array.prototype#map |
*/ |
jsx.array.from = function (iterable, builder, oThis) { |
if (arguments.length < 2) |
{ |
builder = null; |
} |
if (arguments.length > 1 && builder && typeof builder != "function") |
{ |
return jsx.throwThis("TypeError", |
(jsx.object.isMethod(builder, "toSource") ? builder.toSource() : builder) |
+ " is not callable", |
this + ".map"); |
} |
|
if (arguments.length > 1 && builder && typeof builder != "function") |
{ |
return jsx.throwThis("TypeError", |
(jsx.object.isMethod(builder, "toSource") ? builder.toSource() : builder) |
+ " is not callable", |
this + ".map"); |
} |
if (arguments.length < 3) |
{ |
oThis = iterable; |
} |
|
if (arguments.length < 3) |
{ |
oThis = iterable; |
} |
var |
len = iterable.length >>> 0, |
res = []; |
|
var |
len = iterable.length >>> 0, |
res = []; |
for (var i = 0; i < len; ++i) |
{ |
res[i] = (builder |
? builder.call(oThis, iterable[i], i, iterable) |
: oThis[i]); |
} |
|
for (var i = 0; i < len; ++i) |
{ |
res[i] = (builder |
? builder.call(oThis, iterable[i], i, iterable) |
: oThis[i]); |
} |
return res; |
}; |
|
return res; |
}; |
/** |
* @param {Array} a |
* @param {Number} index |
* @param {Boolean} bThrow |
* if <code>true</code>, throws an exception on invalid index |
*/ |
jsx.array.getRealIndex = function (a, index, bThrow) { |
if (isNaN(index) && bThrow) |
{ |
return jsx.throwThis(jsx.InvalidArgumentError, ["", |
"(" + typeof a + ", " + typeof index + ")", |
"(object[Array], number)"]); |
} |
|
/** |
* @param {Array} a |
* @param {Number} index |
* @param {Boolean} bThrow |
* if <code>true</code>, throws an exception on invalid index |
*/ |
jsx.array.getRealIndex = function (a, index, bThrow) { |
if (isNaN(index) && bThrow) |
{ |
return jsx.throwThis(jsx.InvalidArgumentError, ["", |
"(" + typeof a + ", " + typeof index + ")", |
"(object[Array], number)"]); |
} |
index = +index; |
|
index = +index; |
if (index >= 0) |
{ |
return index; |
} |
|
if (index >= 0) |
{ |
return index; |
} |
return a.length + index; |
}; |
|
return a.length + index; |
}; |
/** |
* Retrieves an {@link Array} element as if by the expression |
* <code><var>a</var>.slice(<var>index</var>, |
* <var>index</var> + 1)[0]</code>. |
* |
* If <var>index</var> is negative, its absolute is counted |
* from the end of <var>a</var>. |
* |
* @param {Array} a |
* @param {Number} index |
* @return {any} |
*/ |
jsx.array.get = function (a, index) { |
index = jsx.array.getRealIndex(a, index, true); |
return a[index]; |
}; |
|
/** |
* Retrieves an {@link Array} element as if by the expression |
* <code><var>a</var>.slice(<var>index</var>, |
* <var>index</var> + 1)[0]</code>. |
* |
* If <var>index</var> is negative, its absolute is counted |
* from the end of <var>a</var>. |
* |
* @param {Array} a |
* @param {Number} index |
* @return {any} |
*/ |
jsx.array.get = function (a, index) { |
index = jsx.array.getRealIndex(a, index, true); |
return a[index]; |
}; |
/** |
* Sets an {@link Array} element as if by the expression |
* <code><var>a</var>[(<var>index</var> < 0) ? (index + a.length) |
* : <var>index</var>] = <var>value</var></code>. |
* |
* If <var>index</var> is negative, its absolute is counted |
* from the end of <var>a</var>. |
* |
* @param {Array} a |
* @param {Number} index |
* @return {any} |
*/ |
jsx.array.set = function (a, index, value) { |
index = jsx.array.getRealIndex(a, index, true); |
return (a[index] = value); |
}; |
|
/** |
* Sets an {@link Array} element as if by the expression |
* <code><var>a</var>[(<var>index</var> < 0) ? (index + a.length) |
* : <var>index</var>] = <var>value</var></code>. |
* |
* If <var>index</var> is negative, its absolute is counted |
* from the end of <var>a</var>. |
* |
* @param {Array} a |
* @param {Number} index |
* @return {any} |
*/ |
jsx.array.set = function (a, index, value) { |
index = jsx.array.getRealIndex(a, index, true); |
return (a[index] = value); |
}; |
if (jsx.options.augmentBuiltins) |
{ |
/* Defines Array.isArray() if not already defined */ |
jsx.object.extend(Array, { |
destructure: jsx.array.destructure, |
from: jsx.array.from, |
get: jsx.array.get, |
set: jsx.array.set, |
isArray: jsx.object.isArray |
}); |
|
if (jsx.options.augmentBuiltins) |
{ |
/* Defines Array.isArray() if not already defined */ |
jsx.object.extend(Array, { |
destructure: jsx.array.destructure, |
from: jsx.array.from, |
get: jsx.array.get, |
set: jsx.array.set, |
isArray: jsx.object.isArray |
}); |
Object.observe = (typeof Object.observe == "function") |
? (function () { |
var _observe = Object.observe; |
|
Object.observe = (typeof Object.observe == "function") |
? (function () { |
var _observe = Object.observe; |
return function (obj, callback) { |
_observe(obj, callback); |
return obj; |
}; |
}()) |
: function (obj, callback) { |
var proxy; |
|
return function (obj, callback) { |
_observe(obj, callback); |
return obj; |
}; |
}()) |
: function (obj, callback) { |
var proxy; |
var handler = { |
"set": function (obj, prop, value) { |
var type = "update"; |
|
var handler = { |
"set": function (obj, prop, value) { |
var type = "update"; |
if (jsx.object._hasOwnProperty(obj, prop)) |
{ |
var oldValue = obj[prop]; |
} |
else |
{ |
type = "add"; |
} |
|
if (jsx.object._hasOwnProperty(obj, prop)) |
{ |
var oldValue = obj[prop]; |
} |
else |
{ |
type = "add"; |
} |
obj[prop] = value; |
|
obj[prop] = value; |
if (type == "update") |
{ |
if (obj[prop] !== oldValue) |
{ |
callback(prop, obj, type, oldValue); |
} |
} |
else |
{ |
callback(prop, obj, type); |
} |
}, |
"deleteProperty": function (obj, prop) { |
var hadOwnProperty = jsx.object._hasOwnProperty(obj, prop); |
var deleted = delete obj[prop]; |
|
if (type == "update") |
{ |
if (obj[prop] !== oldValue) |
if (hadOwnProperty && deleted) |
{ |
callback(prop, obj, type, oldValue); |
callback(prop, obj, "delete"); |
} |
} |
else |
{ |
callback(prop, obj, type); |
} |
}, |
"deleteProperty": function (obj, prop) { |
var hadOwnProperty = jsx.object._hasOwnProperty(obj, prop); |
var deleted = delete obj[prop]; |
}; |
|
if (hadOwnProperty && deleted) |
{ |
callback(prop, obj, "delete"); |
} |
} |
jsx.tryThis( |
function () { |
proxy = new Proxy(obj, handler); |
}, |
function () { |
jsx.tryThis( |
function () { |
proxy = Proxy.create(obj, handler); |
}, |
function () { |
jsx.warn("Cannot observe object, Proxy is not implemented"); |
}); |
}); |
|
return proxy; |
}; |
} |
|
jsx.tryThis( |
function () { |
proxy = new Proxy(obj, handler); |
}, |
function () { |
jsx.tryThis( |
function () { |
proxy = Proxy.create(obj, handler); |
}, |
function () { |
jsx.warn("Cannot observe object, Proxy is not implemented"); |
}); |
}); |
/** |
* Returns the absolute path for a URI-reference |
* |
* @param {string} relativePath |
* @param {string} basePath |
* @return {string} |
*/ |
jsx.absPath = function (relativePath, basePath) { |
var uri = (basePath || document.URL).replace(/[?#].*$/, "").split("/"); |
relativePath = relativePath.split("/"); |
|
return proxy; |
}; |
} |
|
/** |
* Returns the absolute path for a URI-reference |
* |
* @param {string} relativePath |
* @param {string} basePath |
* @return {string} |
*/ |
jsx.absPath = function (relativePath, basePath) { |
var uri = (basePath || document.URL).replace(/[?#].*$/, "").split("/"); |
relativePath = relativePath.split("/"); |
|
if (uri[uri.length - 1] != "") |
{ |
uri.pop(); |
} |
|
for (var i = 0, len = relativePath.length; i < len; ++i) |
{ |
var component = relativePath[i]; |
if (component == "..") |
if (uri[uri.length - 1] != "") |
{ |
uri.pop(); |
} |
else if (component != ".") |
|
for (var i = 0, len = relativePath.length; i < len; ++i) |
{ |
uri.push(component); |
var component = relativePath[i]; |
if (component == "..") |
{ |
uri.pop(); |
} |
else if (component != ".") |
{ |
uri.push(component); |
} |
} |
} |
|
return uri.join("/"); |
}; |
return uri.join("/"); |
}; |
|
/** |
* Imports object properties into the global namespace. |
* |
* Convenience method, also for backwards compatibility to versions before |
* strict namespacing. Does not load script files dynamically; use |
* jsx.importFrom() for that and include jsx.net.http. |
* |
* @function |
*/ |
jsx._import = (function () { |
var _jsx_object = jsx.object; |
var _getKeys = _jsx_object.getKeys; |
var _hasOwnProperty = _jsx_object._hasOwnProperty; |
var _isArray = _jsx_object.isArray; |
|
/** |
* @param {Object} obj |
* @param {string|Array|Null} properties (optional) |
* Name or list of names of properties to import. If not |
* provided or <code>null</code>, all own enumerable properties |
* of <var>obj</var> are imported. |
* @param {string} objAlias (optional) |
* The alias property on the Global object that should be used |
* instead of the Global Object. Helps to avoid spoiling |
* the global namespace. |
* @param {string|Array} propertyAliases (optional) |
* The alias(es) that should be used for each property, in order, |
* that is specified in <var>properties</var>. Helps to avoid |
* overwriting property values. |
* There must be specified as many aliases as properties were |
* specified. Ignored if <var>properties</var> is |
* <code>null</code>. |
* @return {boolean} |
* <code>false</code> if <var>properties</var> is provided and not |
* all properties could be imported; <code>true</code> otherwise. |
* @throws TypeError, if <var>obj</var> is not an iterable object |
* Imports object properties into the global namespace. |
* |
* Convenience method, also for backwards compatibility to versions before |
* strict namespacing. Does not load script files dynamically; use |
* jsx.importFrom() for that and include jsx.net.http. |
* |
* @function |
*/ |
return function (obj, properties, objAlias, propertyAliases) { |
if (!obj) |
{ |
return jsx.throwThis("TypeError", |
"expected iterable object, saw " + obj + " : " + (obj === null ? "Null" : typeof obj), |
"jsx._import"); |
} |
jsx._import = (function () { |
var _jsx_object = jsx.object; |
var _getKeys = _jsx_object.getKeys; |
var _hasOwnProperty = _jsx_object._hasOwnProperty; |
var _isArray = _jsx_object.isArray; |
|
var result = true; |
/** |
* @param {Object} obj |
* @param {string|Array|Null} properties (optional) |
* Name or list of names of properties to import. If not |
* provided or <code>null</code>, all own enumerable properties |
* of <var>obj</var> are imported. |
* @param {string} objAlias (optional) |
* The alias property on the Global object that should be used |
* instead of the Global Object. Helps to avoid spoiling |
* the global namespace. |
* @param {string|Array} propertyAliases (optional) |
* The alias(es) that should be used for each property, in order, |
* that is specified in <var>properties</var>. Helps to avoid |
* overwriting property values. |
* There must be specified as many aliases as properties were |
* specified. Ignored if <var>properties</var> is |
* <code>null</code>. |
* @return {boolean} |
* <code>false</code> if <var>properties</var> is provided and not |
* all properties could be imported; <code>true</code> otherwise. |
* @throws TypeError, if <var>obj</var> is not an iterable object |
*/ |
return function (obj, properties, objAlias, propertyAliases) { |
if (!obj) |
{ |
return jsx.throwThis("TypeError", |
"expected iterable object, saw " + obj + " : " + (obj === null ? "Null" : typeof obj), |
"jsx._import"); |
} |
|
var root = jsx.global; |
if (objAlias != null) |
{ |
root[objAlias] = {}; |
root = root[objAlias]; |
} |
var result = true; |
|
var propertiesArg = properties; |
if (properties == null) |
{ |
properties = _getKeys(obj); |
} |
else if (!_isArray(properties)) |
{ |
properties = [properties]; |
} |
|
var len = properties.length; |
if (propertiesArg != null && propertyAliases != null) |
{ |
if (!_isArray(propertyAliases)) |
var root = jsx.global; |
if (objAlias != null) |
{ |
propertyAliases = [propertyAliases]; |
root[objAlias] = {}; |
root = root[objAlias]; |
} |
|
if (len != propertyAliases.length) |
var propertiesArg = properties; |
if (properties == null) |
{ |
return jsx.throwThis(jsx.InvalidArgumentError, |
["Different number of property names and aliases", |
len, propertyAliases.length], |
"jsx._import"); |
properties = _getKeys(obj); |
} |
} |
else if (!_isArray(properties)) |
{ |
properties = [properties]; |
} |
|
for (var i = 0; i < len; ++i) |
{ |
var sourceProperty = properties[i]; |
if (propertiesArg == null || _hasOwnProperty(obj, sourceProperty)) |
var len = properties.length; |
if (propertiesArg != null && propertyAliases != null) |
{ |
var targetProperty = sourceProperty; |
if (propertiesArg != null && propertyAliases != null) |
if (!_isArray(propertyAliases)) |
{ |
targetProperty = propertyAliases[i]; |
propertyAliases = [propertyAliases]; |
} |
|
root[targetProperty] = obj[sourceProperty]; |
if (len != propertyAliases.length) |
{ |
return jsx.throwThis(jsx.InvalidArgumentError, |
["Different number of property names and aliases", |
len, propertyAliases.length], |
"jsx._import"); |
} |
} |
else |
|
for (var i = 0; i < len; ++i) |
{ |
result = false; |
var sourceProperty = properties[i]; |
if (propertiesArg == null || _hasOwnProperty(obj, sourceProperty)) |
{ |
var targetProperty = sourceProperty; |
if (propertiesArg != null && propertyAliases != null) |
{ |
targetProperty = propertyAliases[i]; |
} |
|
root[targetProperty] = obj[sourceProperty]; |
} |
else |
{ |
result = false; |
} |
} |
} |
|
return result; |
}; |
}()); |
return result; |
}; |
}()); |
|
/* ES 5: Reserved words may be used in MemberExpression */ |
jsx["import"] = jsx._import; |
/* ES 5: Reserved words may be used in MemberExpression */ |
jsx["import"] = jsx._import; |
|
/** |
* Imports a script, and optionally the object it defines, or some of their |
* properties, into the global namespace. |
* |
* NOTE: Issues a synchronously-handled HTTP request which blocks all script |
* execution until a response is received or the request times out. |
* Can therefore not be used to import jsx.net.http. |
* |
* @function |
* @requires jsx.net.http#Request |
* @return {boolean} |
* <code>true</code> if the script could be successfully <em>loaded</em> |
* (not: included). |
*/ |
jsx.importFrom = (function () { |
/* Imports */ |
var _import = jsx._import; |
var _Request; |
|
/** |
* @param {string} uri |
* URI of the script to be imported |
* @param {Object} obj |
* Object from the script to be imported (optional) |
* @param {Array} properties (optional) |
* Properties of the object from the script to be imported (optional). |
* See {@link jsx#_import}. |
* @param {string} objAlias (optional) |
* See {@link jsx#_import}. |
* @param {Array} propertyAliases (optional) |
* See {@link jsx#_import}. |
* Imports a script, and optionally the object it defines, or some of their |
* properties, into the global namespace. |
* |
* NOTE: Issues a synchronously-handled HTTP request which blocks all script |
* execution until a response is received or the request times out. |
* Can therefore not be used to import jsx.net.http. |
* |
* @function |
* @requires jsx.net.http#Request |
* @return {boolean} |
* <code>true</code> if the script could be successfully <em>loaded</em> |
* (not: included). |
*/ |
function jsx_importFrom (uri, obj, properties, objAlias, propertyAliases) |
{ |
/* One-time import */ |
if (!_Request) |
jsx.importFrom = (function () { |
/* Imports */ |
var _import = jsx._import; |
var _Request; |
|
/** |
* @param {string} uri |
* URI of the script to be imported |
* @param {Object} obj |
* Object from the script to be imported (optional) |
* @param {Array} properties (optional) |
* Properties of the object from the script to be imported (optional). |
* See {@link jsx#_import}. |
* @param {string} objAlias (optional) |
* See {@link jsx#_import}. |
* @param {Array} propertyAliases (optional) |
* See {@link jsx#_import}. |
*/ |
function jsx_importFrom (uri, obj, properties, objAlias, propertyAliases) |
{ |
_Request = jsx.net.http.Request; |
} |
|
jsx_importFrom.lastImport = uri; |
var req = new _Request(uri, "GET", false, function (response) { |
/* |
* NOTE: Passing response.responseText to eval() is not ES5-compatible; |
* conforming implementations create a new execution context with |
* EMPTY scope chain. |
*/ |
var script = document.createElement("script"); |
script.type = "text/javascript"; |
|
if (typeof script.text == "undefined") |
/* One-time import */ |
if (!_Request) |
{ |
script.appendChild(document.createTextNode(response.responseText)); |
_Request = jsx.net.http.Request; |
} |
else |
{ |
script.text = response.responseText; |
} |
|
/* NOTE: document.head was introduced with HTML5 WD */ |
(document.head || document.getElementsByTagName("head")[0]).appendChild(script); |
jsx_importFrom.lastImport = uri; |
var req = new _Request(uri, "GET", false, function (response) { |
/* |
* NOTE: Passing response.responseText to eval() is not ES5-compatible; |
* conforming implementations create a new execution context with |
* EMPTY scope chain. |
*/ |
var script = document.createElement("script"); |
script.type = "text/javascript"; |
|
if (arguments.length > 1) |
{ |
return _import(obj, properties, objAlias, propertyAliases); |
} |
if (typeof script.text == "undefined") |
{ |
script.appendChild(document.createTextNode(response.responseText)); |
} |
else |
{ |
script.text = response.responseText; |
} |
|
return true; |
}); |
/* NOTE: document.head was introduced with HTML5 WD */ |
(document.head || document.getElementsByTagName("head")[0]).appendChild(script); |
|
return req.send(); |
} |
if (arguments.length > 1) |
{ |
return _import(obj, properties, objAlias, propertyAliases); |
} |
|
return jsx_importFrom; |
}()); |
return true; |
}); |
|
/** |
* Imports once an object or some of its properties |
* from a script resource into the global namespace. |
* |
* @function |
* @see jsx#importFrom |
*/ |
jsx.importOnce = (function () { |
var _getProperty = jsx.object.getProperty; |
var _absPath = jsx.absPath; |
var _importFrom = jsx.importFrom; |
return req.send(); |
} |
|
return jsx_importFrom; |
}()); |
|
/** |
* @param {string} uri |
* URI of the resource to be imported |
* @param {Object} obj |
* Object to import |
* @param {Array} properties (optional) |
* Properties of the object from the script to be imported. |
* See {@link jsx#_import}. |
* @param {string} objAlias (optional) |
* See {@link jsx#_import}. |
* @param {Array} propertyAliases (optional) |
* See {@link jsx#_import}. |
* @return {boolean} |
* <code>true</code> if the script specified by <var>uri</var> |
* has already been included; <code>false</code> otherwise. |
* Imports once an object or some of its properties |
* from a script resource into the global namespace. |
* |
* @function |
* @see jsx#importFrom |
*/ |
function importOnce (uri, obj, properties, objAlias, propertyAliases) |
{ |
jsx.importOnce = (function () { |
var _getProperty = jsx.object.getProperty; |
var _absPath = jsx.absPath; |
var _importFrom = jsx.importFrom; |
|
/** |
* @param {string} uri |
* URI of the resource to be imported |
* @param {Object} obj |
* Object to import |
* @param {Array} properties (optional) |
* Properties of the object from the script to be imported. |
* See {@link jsx#_import}. |
* @param {string} objAlias (optional) |
* See {@link jsx#_import}. |
* @param {Array} propertyAliases (optional) |
* See {@link jsx#_import}. |
* @return {boolean} |
* <code>true</code> if the script specified by <var>uri</var> |
* has already been included; <code>false</code> otherwise. |
*/ |
function scriptIncluded (uri) |
function importOnce (uri, obj, properties, objAlias, propertyAliases) |
{ |
var scripts = document.getElementsByTagName("script"); |
if (scripts) |
/** |
* @param {string} uri |
*/ |
function scriptIncluded (uri) |
{ |
var uriAbsPath = _absPath(uri); |
for (var i = 0, len = scripts.length; i < len; ++i) |
var scripts = document.getElementsByTagName("script"); |
if (scripts) |
{ |
var script = scripts[i]; |
if (_absPath(script.src) == uriAbsPath) |
var uriAbsPath = _absPath(uri); |
for (var i = 0, len = scripts.length; i < len; ++i) |
{ |
return true; |
var script = scripts[i]; |
if (_absPath(script.src) == uriAbsPath) |
{ |
return true; |
} |
} |
} |
|
return false; |
} |
|
return false; |
} |
var result = false; |
|
var result = false; |
|
if (uri |
&& !scriptIncluded(uri) |
&& !_getProperty(importOnce.imports, uri, null)) |
{ |
result = _importFrom(uri, obj, properties, objAlias, propertyAliases); |
if (result) |
if (uri |
&& !scriptIncluded(uri) |
&& !_getProperty(importOnce.imports, uri, null)) |
{ |
importOnce.imports[uri] = true; |
result = _importFrom(uri, obj, properties, objAlias, propertyAliases); |
if (result) |
{ |
importOnce.imports[uri] = true; |
} |
} |
|
return result; |
} |
|
return result; |
} |
importOnce.imports = {}; |
|
importOnce.imports = {}; |
return importOnce; |
}()); |
|
return importOnce; |
}()); |
|
/** |
* Executes a function if and once its dependencies are met. |
* |
* If the required HTML5 features are not supported, the code |
* is executed immediately. Any dependencies have to be |
* resolved manually then. |
* |
* @function |
*/ |
jsx.require = (function () { |
var _jsx = jsx; |
var _map = _jsx.array.map; |
var _importOnce = _jsx.importOnce; |
var _jsx_object = _jsx.object; |
var _getFeature = _jsx_object.getFeature; |
var _isArray = _jsx_object.isArray; |
var _addEventListener; |
|
/** |
* @param {string|Array} dependencies |
* URI-reference or <code>Array</code> of URI-references |
* specifying the dependency/dependencies |
* @param {Function} callback (optional) |
* Function to be executed |
* @return {any} |
* The return value of <var>callback</var>, |
* <code>undefined</code> otherwise. |
* Executes a function if and once its dependencies are met. |
* |
* If the required HTML5 features are not supported, the code |
* is executed immediately. Any dependencies have to be |
* resolved manually then. |
* |
* @function |
*/ |
return function jsx_require (dependencies, callback) { |
var success; |
jsx.require = (function () { |
var _jsx = jsx; |
var _map = _jsx.array.map; |
var _importOnce = _jsx.importOnce; |
var _jsx_object = _jsx.object; |
var _getFeature = _jsx_object.getFeature; |
var _isArray = _jsx_object.isArray; |
var _addEventListener; |
|
if (!_isArray(dependencies)) |
{ |
dependencies = [dependencies]; |
} |
/** |
* @param {string|Array} dependencies |
* URI-reference or <code>Array</code> of URI-references |
* specifying the dependency/dependencies |
* @param {Function} callback (optional) |
* Function to be executed |
* @return {any} |
* The return value of <var>callback</var>, |
* <code>undefined</code> otherwise. |
*/ |
return function jsx_require (dependencies, callback) { |
var success; |
|
dependencies = _map(dependencies, function (urn) { |
var m; |
if ((m = urn.match(/^([^:]+):([^\/]|\/[^\/])/))) |
if (!_isArray(dependencies)) |
{ |
var scheme = m[1]; |
var uri = (jsx_require.urnPrefixes || jsx.object.getDataObject())[scheme]; |
if (typeof uri != "undefined") |
dependencies = [dependencies]; |
} |
|
dependencies = _map(dependencies, function (urn) { |
var m; |
if ((m = urn.match(/^([^:]+):([^\/]|\/[^\/])/))) |
{ |
urn = urn.replace(m[0], uri + m[2]); |
var scheme = m[1]; |
var uri = (jsx_require.urnPrefixes || jsx.object.getDataObject())[scheme]; |
if (typeof uri != "undefined") |
{ |
urn = urn.replace(m[0], uri + m[2]); |
} |
else |
{ |
jsx.warn('jsx.require.urnPrefixes["' + scheme + '"] is not defined.' |
+ ' Leaving it unchanged.\nDid you mean "' + scheme + '://..."?'); |
} |
} |
else |
{ |
jsx.warn('jsx.require.urnPrefixes["' + scheme + '"] is not defined.' |
+ ' Leaving it unchanged.\nDid you mean "' + scheme + '://..."?'); |
} |
} |
|
return urn; |
}); |
return urn; |
}); |
|
var script = document.createElement("script"); |
var script = document.createElement("script"); |
|
if (!script) |
{ |
return false; |
} |
if (!script) |
{ |
return false; |
} |
|
if (typeof _addEventListener == "undefined") |
{ |
_addEventListener = _getFeature(jsx, ["dom", "addEventListener"]); |
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) |
{ |
/* no wrapper, try W3C DOM directly */ |
_addEventListener = function (target, eventType, listener) { |
return jsx.tryThis( |
function () { |
target.addEventListener(eventType, listener, false); |
return listener; |
}); |
}; |
} |
} |
} |
|
if (_addEventListener) |
{ |
var listenerSupported = _addEventListener(script, "load", |
function () { |
dependencies.shift(); |
if (_addEventListener) |
{ |
var listenerSupported = _addEventListener(script, "load", |
function () { |
dependencies.shift(); |
|
if (dependencies.length == 0) |
{ |
/* All dependencies loaded successfully */ |
if (typeof callback == "function") |
if (dependencies.length == 0) |
{ |
return callback(); |
/* All dependencies loaded successfully */ |
if (typeof callback == "function") |
{ |
return callback(); |
} |
|
return true; |
} |
|
return true; |
} |
jsx_require(dependencies, callback); |
}); |
} |
|
jsx_require(dependencies, callback); |
if (listenerSupported) |
{ |
_addEventListener(script, "error", function (e) { |
jsx.error(e); |
}); |
} |
|
if (listenerSupported) |
{ |
_addEventListener(script, "error", function (e) { |
jsx.error(e); |
}); |
script.src = dependencies[0]; |
(document.head || document.getElementsByTagName("head")[0]) |
.appendChild(script); |
} |
else |
{ |
jsx.warn('The "load" event is not supported on "script" elements.' |
+ ' Attempting to resolve dependencies using synchronous XHR (blocking).'); |
|
script.src = dependencies[0]; |
(document.head || document.getElementsByTagName("head")[0]) |
.appendChild(script); |
} |
else |
{ |
jsx.warn('The "load" event is not supported on "script" elements.' |
+ ' Attempting to resolve dependencies using synchronous XHR (blocking).'); |
for (var i = 0, len = dependencies.length; i < len; ++i) |
{ |
if (!_importOnce(dependencies[i])) |
{ |
success = false; |
break; |
} |
} |
|
for (var i = 0, len = dependencies.length; i < len; ++i) |
{ |
if (!_importOnce(dependencies[i])) |
if (success) |
{ |
success = false; |
break; |
return callback(); |
} |
} |
}; |
}()); |
|
if (success) |
{ |
return callback(); |
} |
} |
}; |
}()); |
|
if (jsx.options.augmentBuiltins) |
{ |
if (jsx.options.augmentPrototypes) |
if (jsx.options.augmentBuiltins) |
{ |
// if (jsx.options.augmentObjectPrototype) |
// { |
// jsx.object.extend(Object.prototype, { |
// extend: extend, |
// clone: clone, |
// findNewProperty: findNewProperty, |
// _hasOwnProperty: _hasOwnProperty |
// }); |
// } |
if (jsx.options.augmentPrototypes) |
{ |
// if (jsx.options.augmentObjectPrototype) |
// { |
// jsx.object.extend(Object.prototype, { |
// extend: extend, |
// clone: clone, |
// findNewProperty: findNewProperty, |
// _hasOwnProperty: _hasOwnProperty |
// }); |
// } |
|
/* |
* KJS 3.5.1 does not support named FunctionExpressions within Object |
* literals if the literal is an AssignmentExpression (right-hand side |
* of an assignment or a passed function argument). |
* fixed since <http://bugs.kde.org/show_bug.cgi?id=123529> |
*/ |
|
jsx.object.extend(Function.prototype, { |
/** |
* Applies a method of another object in the context |
* of a different object (the calling object). |
* |
* @memberOf Function.prototype |
* @function |
/* |
* KJS 3.5.1 does not support named FunctionExpressions within Object |
* literals if the literal is an AssignmentExpression (right-hand side |
* of an assignment or a passed function argument). |
* fixed since <http://bugs.kde.org/show_bug.cgi?id=123529> |
*/ |
apply: (function () { |
var |
jsx_object = jsx.object, |
jsx_global = jsx.global; |
|
jsx.object.extend(Function.prototype, { |
/** |
* @param {Object} thisArg |
* Reference to the calling object |
* @param {Array} argArray |
* Arguments for the object |
* @return {any} |
* Applies a method of another object in the context |
* of a different object (the calling object). |
* |
* @memberOf Function.prototype |
* @function |
*/ |
return function (thisArg, argArray) { |
if (!thisArg) |
{ |
thisArg = jsx_global; |
} |
|
apply: (function () { |
var |
o = {}, |
p = jsx_object.findNewProperty(o); |
jsx_object = jsx.object, |
jsx_global = jsx.global; |
|
if (p) |
{ |
o[p] = thisArg || this; |
|
var a = []; |
for (var i = 0, len = argArray.length; i < len; i++) |
/** |
* @param {Object} thisArg |
* Reference to the calling object |
* @param {Array} argArray |
* Arguments for the object |
* @return {any} |
*/ |
return function (thisArg, argArray) { |
if (!thisArg) |
{ |
a[i] = "argArray[" + i + "]"; |
thisArg = jsx_global; |
} |
|
eval("o[p](" + a + ")"); |
var |
o = {}, |
p = jsx_object.findNewProperty(o); |
|
delete o[p]; |
} |
}; |
}()), |
if (p) |
{ |
o[p] = thisArg || this; |
|
/** |
* Calls (executes) a method of another object in the |
* context of a different object (the calling object). |
* |
* @memberOf Function.prototype |
* @param {Object} thisArg |
* Reference to the calling object. SHOULD NOT |
* be a host object, since augmentation is required. |
* @params {_} |
* Arguments for the object. |
*/ |
call: function (thisArg) { |
var a = []; |
var a = []; |
for (var i = 0, len = argArray.length; i < len; i++) |
{ |
a[i] = "argArray[" + i + "]"; |
} |
|
for (var i = 1, len = arguments.length; i < len; i++) |
{ |
a[i] = "arguments[" + i + "]"; |
} |
eval("o[p](" + a + ")"); |
|
if (!thisArg) |
{ |
thisArg = jsx.global; |
} |
delete o[p]; |
} |
}; |
}()), |
|
var |
o = {}, |
p = jsx.object.findNewProperty(o); |
|
if (p) |
{ |
o[p] = this; |
eval("o[p](" + a + ")"); |
delete o[p]; |
o = null; |
} |
}, |
|
/** |
* Returns a <code>Function</code> that has a defined |
* <code>this</code> value and calls the calling |
* <code>Function</code> with default parameters. |
* |
* @function |
* @return {Function} |
* @see 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]]) |
*/ |
bind: (function () { |
var _slice; |
var _getClass = jsx.object.getClass; |
|
/** |
* Calls (executes) a method of another object in the |
* context of a different object (the calling object). |
* |
* @memberOf Function.prototype |
* @param {Object} thisArg |
* <code>this</code> value of the returned |
* <code>Function</code> |
* @params Default parameters |
* Reference to the calling object. SHOULD NOT |
* be a host object, since augmentation is required. |
* @params {_} |
* Arguments for the object. |
*/ |
return function (thisArg) { |
var target = this; |
if (typeof target != "function") |
call: function (thisArg) { |
var a = []; |
|
for (var i = 1, len = arguments.length; i < len; i++) |
{ |
return jsx.throwThis("TypeError"); |
a[i] = "arguments[" + i + "]"; |
} |
|
if (!_slice) |
if (!thisArg) |
{ |
_slice = Array.prototype.slice; |
thisArg = jsx.global; |
} |
|
var boundArgs = _slice.call(arguments, 1); |
var f = function () { |
return target.apply(thisArg, boundArgs.concat(_slice.call(arguments))); |
}; |
var |
o = {}, |
p = jsx.object.findNewProperty(o); |
|
if (_getClass(target) == "Function") |
if (p) |
{ |
f.length = target.length + boundArgs.length; |
o[p] = this; |
eval("o[p](" + a + ")"); |
delete o[p]; |
o = null; |
} |
else |
{ |
if (typeof Object.defineProperty == "function") |
}, |
|
/** |
* Returns a <code>Function</code> that has a defined |
* <code>this</code> value and calls the calling |
* <code>Function</code> with default parameters. |
* |
* @function |
* @return {Function} |
* @see 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]]) |
*/ |
bind: (function () { |
var _slice; |
var _getClass = jsx.object.getClass; |
|
/** |
* @param {Object} thisArg |
* <code>this</code> value of the returned |
* <code>Function</code> |
* @params Default parameters |
*/ |
return function (thisArg) { |
var target = this; |
if (typeof target != "function") |
{ |
/* |
* [[Writable]]: false, [[Enumerable]]: false, |
* [[Configurable]]: false |
*/ |
Object.defineProperty(f, "length"); |
return jsx.throwThis("TypeError"); |
} |
|
if (!_slice) |
{ |
_slice = Array.prototype.slice; |
} |
|
var boundArgs = _slice.call(arguments, 1); |
var f = function () { |
return target.apply(thisArg, boundArgs.concat(_slice.call(arguments))); |
}; |
|
if (_getClass(target) == "Function") |
{ |
f.length = target.length + boundArgs.length; |
} |
else |
{ |
f.length = 0; |
if (typeof Object.defineProperty == "function") |
{ |
/* |
* [[Writable]]: false, [[Enumerable]]: false, |
* [[Configurable]]: false |
*/ |
Object.defineProperty(f, "length"); |
} |
else |
{ |
f.length = 0; |
} |
} |
} |
|
return f; |
}; |
}()), |
return f; |
}; |
}()), |
|
/** |
* Constructs a new object using the calling object as constructor |
* and elements of the referred array as items of the arguments list. |
* <p> |
* Example: |
* <pre><code>var o = Foo.construct(["bar", "baz"]);</code></pre> |
* is equivalent to |
* <pre><code>var o = new Foo("bar", "baz");</code></pre> |
* but, by contrast, allows for passing an arbitrary number of |
* arguments per the array's elements. |
* </p> |
*/ |
construct: (function () { |
var _jsx_object = jsx.object; |
var _inheritFrom = _jsx_object.inheritFrom; |
var _isObject = _jsx_object.isObject; |
|
/** |
* @param {Array} argArray |
* @return {Object} Reference to the new instance |
*/ |
return function (argArray) { |
var o = _inheritFrom(this.prototype); |
var result = this.apply(o, argArray); |
|
if (_isObject(result)) |
{ |
o = result; |
} |
|
return o; |
}; |
}()) |
}); |
} |
|
jsx.object.extend(Date, { |
/** |
* Constructs a new object using the calling object as constructor |
* and elements of the referred array as items of the arguments list. |
* Constructs a new {@link Date} instance using the calling object |
* as constructor and elements of the referred array as items of |
* the arguments list. |
* <p> |
* <em>Requires {@link jsx.options.augmentBuiltins}. |
* Does not work in strict mode.</em> |
* </p><p> |
* Example: |
* <pre><code>var o = Foo.construct(["bar", "baz"]);</code></pre> |
* <pre><code>var d = Date.construct([2009, 8, 1]);</code></pre> |
* is equivalent to |
* <pre><code>var o = new Foo("bar", "baz");</code></pre> |
* <pre><code>var d = new Date(2009, 8, 1);</code></pre> |
* but, by contrast, allows for passing an arbitrary number of |
* arguments per the array's elements. |
* </p> |
* @memberOf Date |
* @param {Array} argArray |
* @return {Date} Reference to the new instance |
*/ |
construct: (function () { |
var _jsx_object = jsx.object; |
var _inheritFrom = _jsx_object.inheritFrom; |
var _isObject = _jsx_object.isObject; |
construct: function (argArray) { |
var a = []; |
for (var i = 0, len = argArray.length; i < len; ++i) |
{ |
a[i] = "argArray[" + i + "]"; |
} |
|
/** |
* @param {Array} argArray |
* @return {Object} Reference to the new instance |
*/ |
return function (argArray) { |
var o = _inheritFrom(this.prototype); |
var result = this.apply(o, argArray); |
return eval("new this(" + a + ")"); |
} |
}, jsx.object.ADD_OVERWRITE); |
} |
|
if (_isObject(result)) |
{ |
o = result; |
} |
/** |
* Includes the prototype object of another object in the prototype |
* chain of objects created with the calling Function object. |
* <p> |
* Used with constructors to establish multi-level prototype-based |
* inheritance (much like class-based inheritance in Java). To that end, |
* this method adds a <code>_super</code> property to the function to refer |
* to <var>Constructor</var>, the constructor of the parent prototype. |
* Likewise, instances constructed with the resulting function have a |
* <code>_super</code> property to refer to their constructor. |
* </p><p> |
* NOTE: Because of this, you need to use the constructor's |
* <code>_super</code> property if you want to refer to the parent's |
* constructor in the instance's constructor; using the instance's |
* <code>_super</code> property would result in infinite recursion, |
* and ultimately a stack overflow. You may call the parent's |
* constructor explicitly within the constructor of the child, using |
* the (equivalent of the) <code>arguments.callee._super.call()</code> |
* method (or calling it explicitly as a method of the inheriting |
* prototype); in prototype methods, use |
* <code><var>Constructor</var>._super.prototype.method.call()</code> |
* or refer to the parent constructor directly. |
* </p> |
* <p><em>Not to be confused with {@link jsx.object#extend}.</em></p> |
* |
* @function |
* @return {Function} |
* A reference to the constructor of the extended prototype object |
* if successful; <code>null</code> otherwise. |
*/ |
Function.prototype.extend = (function () { |
var _jsx = jsx; |
var _jsx_object = _jsx.object; |
|
return o; |
}; |
}()) |
}); |
} |
|
jsx.object.extend(Date, { |
/** |
* Constructs a new {@link Date} instance using the calling object |
* as constructor and elements of the referred array as items of |
* the arguments list. |
* <p> |
* <em>Requires {@link jsx.options.augmentBuiltins}. |
* Does not work in strict mode.</em> |
* </p><p> |
* Example: |
* <pre><code>var d = Date.construct([2009, 8, 1]);</code></pre> |
* is equivalent to |
* <pre><code>var d = new Date(2009, 8, 1);</code></pre> |
* but, by contrast, allows for passing an arbitrary number of |
* arguments per the array's elements. |
* </p> |
* @memberOf Date |
* @param {Array} argArray |
* @return {Date} Reference to the new instance |
* @private |
* @function |
* @return {Object} |
*/ |
construct: function (argArray) { |
var a = []; |
for (var i = 0, len = argArray.length; i < len; ++i) |
var _iterator = (function () { |
/* Optimize if ECMAScript 5 features were available */ |
if (typeof Object.defineProperties == "function") |
{ |
a[i] = "argArray[" + i + "]"; |
return function () { |
return this; |
}; |
} |
|
return eval("new this(" + a + ")"); |
} |
}, jsx.object.ADD_OVERWRITE); |
} |
return function () { |
_jsx.warn("for (var p in o.iterator()) { f(); } is inefficient," |
+ " consider using o.forEach(f, ...) instead"); |
|
/** |
* Includes the prototype object of another object in the prototype |
* chain of objects created with the calling Function object. |
* <p> |
* Used with constructors to establish multi-level prototype-based |
* inheritance (much like class-based inheritance in Java). To that end, |
* this method adds a <code>_super</code> property to the function to refer |
* to <var>Constructor</var>, the constructor of the parent prototype. |
* Likewise, instances constructed with the resulting function have a |
* <code>_super</code> property to refer to their constructor. |
* </p><p> |
* NOTE: Because of this, you need to use the constructor's |
* <code>_super</code> property if you want to refer to the parent's |
* constructor in the instance's constructor; using the instance's |
* <code>_super</code> property would result in infinite recursion, |
* and ultimately a stack overflow. You may call the parent's |
* constructor explicitly within the constructor of the child, using |
* the (equivalent of the) <code>arguments.callee._super.call()</code> |
* method (or calling it explicitly as a method of the inheriting |
* prototype); in prototype methods, use |
* <code><var>Constructor</var>._super.prototype.method.call()</code> |
* or refer to the parent constructor directly. |
* </p> |
* <p><em>Not to be confused with {@link jsx.object#extend}.</em></p> |
* |
* @function |
* @return {Function} |
* A reference to the constructor of the extended prototype object |
* if successful; <code>null</code> otherwise. |
*/ |
Function.prototype.extend = (function () { |
var _jsx = jsx; |
var _jsx_object = _jsx.object; |
var o = {}; |
|
/** |
* @private |
* @function |
* @return {Object} |
*/ |
var _iterator = (function () { |
/* Optimize if ECMAScript 5 features were available */ |
if (typeof Object.defineProperties == "function") |
{ |
return function () { |
return this; |
}; |
} |
for (var p2 in this) |
{ |
switch (p2) |
{ |
case "_super": |
case "constructor": |
case "iterator": |
case "forEach": |
break; |
|
return function () { |
_jsx.warn("for (var p in o.iterator()) { f(); } is inefficient," |
+ " consider using o.forEach(f, ...) instead"); |
default: |
o[p2] = true; |
} |
} |
|
var o = {}; |
return o; |
}; |
}()); |
|
for (var p2 in this) |
function _forEach(fCallback, thisObj) |
{ |
var t = typeof fCallback; |
if (!_jsx_object.isMethod(fCallback)) |
{ |
switch (p2) |
return _jsx.throwThis( |
"TypeError", |
(!/^\s*unknown\s*$/i.test(t) ? fCallback : "arguments[0]") |
+ " is not a function", |
this + ".forEach"); |
} |
|
for (var p in this) |
{ |
switch (p) |
{ |
case "_super": |
case "constructor": |
3488,464 → 3523,437 |
break; |
|
default: |
o[p2] = true; |
/* also supports host object's methods */ |
Function.prototype.call.call(fCallback, thisObj, this[p], p, this); |
} |
} |
} |
|
return o; |
}; |
}()); |
/** |
* @param {Function} fSuper |
* Constructor from whose prototype object should be inherited. |
* @param {Object} oProtoProps |
* Object from which to shallow-copy properties as prototype |
* properties. Of those, the <code>_super</code>, |
* <code>constructor</code>, and <code>_userDefined</code> |
* properties are ignored as they are used internally. |
*/ |
return function (fSuper, oProtoProps) { |
var me = this; |
|
function _forEach(fCallback, thisObj) |
{ |
var t = typeof fCallback; |
if (!_jsx_object.isMethod(fCallback)) |
{ |
return _jsx.throwThis( |
"TypeError", |
(!/^\s*unknown\s*$/i.test(t) ? fCallback : "arguments[0]") |
+ " is not a function", |
this + ".forEach"); |
} |
|
for (var p in this) |
{ |
switch (p) |
/* |
* Allows constructor to be null or undefined to inherit from |
* Object.prototype by default (see below) |
*/ |
if (fSuper == null) |
{ |
case "_super": |
case "constructor": |
case "iterator": |
case "forEach": |
break; |
if (typeof fSuper == "undefined") |
{ |
/* Passing undefined is probably unintentional, so warn about it */ |
_jsx.warn((_jsx_object.getFunctionName(me) || "[anonymous Function]") |
+ ".extend(" + "undefined, " + oProtoProps + "):" |
+ " Parent constructor is undefined, using Object"); |
} |
|
default: |
/* also supports host object's methods */ |
Function.prototype.call.call(fCallback, thisObj, this[p], p, this); |
fSuper = "Object"; |
} |
} |
} |
|
/** |
* @param {Function} fSuper |
* Constructor from whose prototype object should be inherited. |
* @param {Object} oProtoProps |
* Object from which to shallow-copy properties as prototype |
* properties. Of those, the <code>_super</code>, |
* <code>constructor</code>, and <code>_userDefined</code> |
* properties are ignored as they are used internally. |
*/ |
return function (fSuper, oProtoProps) { |
var me = this; |
/* |
* Supports strings being passed that denote properties of the |
* Global Object. |
* |
* TODO: An API that only registers strings as references to features |
* defined later, and implements inheritance using this registry |
* on user call only, might be useful for constructors defined |
* in Object initializers. |
*/ |
if (typeof fSuper.valueOf() == "string") |
{ |
fSuper = _jsx.global[fSuper]; |
} |
|
/* |
* Allows constructor to be null or undefined to inherit from |
* Object.prototype by default (see below) |
*/ |
if (fSuper == null) |
{ |
if (typeof fSuper == "undefined") |
var t = typeof fSuper; |
if (t != "function") |
{ |
/* Passing undefined is probably unintentional, so warn about it */ |
_jsx.warn((_jsx_object.getFunctionName(me) || "[anonymous Function]") |
+ ".extend(" + "undefined, " + oProtoProps + "):" |
+ " Parent constructor is undefined, using Object"); |
_jsx.throwThis("TypeError", |
(/\s*unknown\s*/i.test(t) ? "Unknown" : t) + " is not a function"); |
return null; |
} |
|
fSuper = "Object"; |
} |
var super_proto = fSuper.prototype; |
this.prototype = _jsx_object.inheritFrom(super_proto); |
|
/* |
* Supports strings being passed that denote properties of the |
* Global Object. |
* |
* TODO: An API that only registers strings as references to features |
* defined later, and implements inheritance using this registry |
* on user call only, might be useful for constructors defined |
* in Object initializers. |
*/ |
if (typeof fSuper.valueOf() == "string") |
{ |
fSuper = _jsx.global[fSuper]; |
} |
|
var t = typeof fSuper; |
if (t != "function") |
{ |
_jsx.throwThis("TypeError", |
(/\s*unknown\s*/i.test(t) ? "Unknown" : t) + " is not a function"); |
return null; |
} |
|
var super_proto = fSuper.prototype; |
this.prototype = _jsx_object.inheritFrom(super_proto); |
|
if (oProtoProps) |
{ |
for (var p in oProtoProps) |
if (oProtoProps) |
{ |
var prop = this.prototype[p] = oProtoProps[p]; |
for (var p in oProtoProps) |
{ |
var prop = this.prototype[p] = oProtoProps[p]; |
|
if (typeof prop == "function" |
&& typeof super_proto[p] == "function") |
{ |
prop._super = super_proto[p]; |
if (typeof prop == "function" |
&& typeof super_proto[p] == "function") |
{ |
prop._super = super_proto[p]; |
} |
} |
} |
} |
|
this._super = fSuper; |
this.prototype._super = super_proto; |
this.prototype.constructor = this; |
this._userDefined = true; |
this._super = fSuper; |
this.prototype._super = super_proto; |
this.prototype.constructor = this; |
this._userDefined = true; |
|
/* PERF: for (var p in o.iterator()) is rather inefficient */ |
/** |
* @deprecated |
* @return {Object} |
*/ |
if (typeof this.prototype.iterator != "function") |
{ |
this.prototype.iterator = _iterator; |
} |
|
/* Optimize iteration if ECMAScript 5 features are available */ |
if (typeof Object.defineProperties == "function") |
{ |
var |
userDefProtoProps = ["_super", "constructor", "iterator"], |
oDescriptors = {}, |
proto = this.prototype; |
|
for (var i = userDefProtoProps.length; i--;) |
/* PERF: for (var p in o.iterator()) is rather inefficient */ |
/** |
* @deprecated |
* @return {Object} |
*/ |
if (typeof this.prototype.iterator != "function") |
{ |
p = userDefProtoProps[i]; |
oDescriptors[p] = { |
value: proto[p], |
enumerable: false |
}; |
this.prototype.iterator = _iterator; |
} |
|
_jsx.tryThis( |
function () { |
Object.defineProperties(proto, oDescriptors); |
}, |
function (e) { |
_jsx.warn(_jsx_object.getFunctionName(me) + ".extend(" |
+ _jsx_object.getFunctionName(fSuper) + ", " |
+ oProtoProps + "): " + e.name + ': ' + e.message); |
}); |
} |
/* Optimize iteration if ECMAScript 5 features are available */ |
if (typeof Object.defineProperties == "function") |
{ |
var |
userDefProtoProps = ["_super", "constructor", "iterator"], |
oDescriptors = {}, |
proto = this.prototype; |
|
if (typeof this.prototype.forEach != "function") |
{ |
/** |
* Calls a function for each real property of the object |
* in arbitrary order. Workaround for for-in iteration |
* on objects with augmented prototype object. |
* |
* @param {Function} fCallback |
* @param {Object} thisObj (optional) |
* @throws TypeError |
*/ |
this.prototype.forEach = _forEach; |
for (var i = userDefProtoProps.length; i--;) |
{ |
p = userDefProtoProps[i]; |
oDescriptors[p] = { |
value: proto[p], |
enumerable: false |
}; |
} |
|
/* Optimize iteration if ECMAScript 5 features are available */ |
if (typeof Object.defineProperty == "function") |
{ |
_jsx.tryThis( |
function () { |
Object.defineProperty(me.prototype, "forEach", { |
value: me.prototype.forEach, |
enumerable: false |
}); |
Object.defineProperties(proto, oDescriptors); |
}, |
function (e) { |
/* IE 8 goes here */ |
_jsx.warn( |
'Borken implementation: Object.defineProperty is a method' |
+ ' but [[Call]](this.prototype, "forEach") throws exception ("' |
+ e.name + ': ' + e.message + '")'); |
} |
); |
_jsx.warn(_jsx_object.getFunctionName(me) + ".extend(" |
+ _jsx_object.getFunctionName(fSuper) + ", " |
+ oProtoProps + "): " + e.name + ': ' + e.message); |
}); |
} |
} |
|
/* DEBUG */ |
// document.write("<pre>" + ["this = " + this, "this._super = " + this._super].join("\n\n") + "\n===</pre>"); |
if (typeof this.prototype.forEach != "function") |
{ |
/** |
* Calls a function for each real property of the object |
* in arbitrary order. Workaround for for-in iteration |
* on objects with augmented prototype object. |
* |
* @param {Function} fCallback |
* @param {Object} thisObj (optional) |
* @throws TypeError |
*/ |
this.prototype.forEach = _forEach; |
|
return this; |
}; |
}()); |
/* Optimize iteration if ECMAScript 5 features are available */ |
if (typeof Object.defineProperty == "function") |
{ |
_jsx.tryThis( |
function () { |
Object.defineProperty(me.prototype, "forEach", { |
value: me.prototype.forEach, |
enumerable: false |
}); |
}, |
function (e) { |
/* IE 8 goes here */ |
_jsx.warn( |
'Borken implementation: Object.defineProperty is a method' |
+ ' but [[Call]](this.prototype, "forEach") throws exception ("' |
+ e.name + ': ' + e.message + '")'); |
} |
); |
} |
} |
|
/** |
* General exception |
* |
* @constructor |
* @extends Error |
* @param {string} sMsg |
*/ |
jsx.Error = function jsx_Error (sMsg) { |
var msg = (sMsg || "Unspecified error"); |
var _super = jsx_Error._super; |
var e = null; |
/* DEBUG */ |
// document.write("<pre>" + ["this = " + this, "this._super = " + this._super].join("\n\n") + "\n===</pre>"); |
|
if (typeof _super == "function") |
{ |
_super.call(this, msg); |
return this; |
}; |
}()); |
|
jsx.tryThis(function () { e = new _super(); }); |
} |
/** |
* General exception |
* |
* @constructor |
* @extends Error |
* @param {string} sMsg |
*/ |
jsx.Error = function jsx_Error (sMsg) { |
var msg = (sMsg || "Unspecified error"); |
var _super = jsx_Error._super; |
var e = null; |
|
if (!this.message) |
{ |
/** |
* @type string |
*/ |
this.message = msg; |
} |
if (typeof _super == "function") |
{ |
_super.call(this, msg); |
|
if (!this.lineNumber && e) |
{ |
/** |
* @type number |
*/ |
this.lineNumber = e.lineNumber || e.line; |
} |
jsx.tryThis(function () { e = new _super(); }); |
} |
|
if (!this.stack && e && e.stack) |
{ |
var stack = String(e.stack).split(/\r?\n|\r/).slice(2); |
this.stack = stack.join("\n"); |
} |
}; |
if (!this.message) |
{ |
/** |
* @type string |
*/ |
this.message = msg; |
} |
|
jsx.Error.extend( |
(typeof Error != "undefined" && Error !== null ? Error : function () {}), |
{ |
/** |
* @memberOf jsx.Error.prototype |
*/ |
name: "jsx.Error", |
getMessage: function () { return this.message; }, |
getStackTrace: function () { return this.stack; }, |
printStackTrace: function () { |
var s = this.getStackTrace(); |
jsx.dmsg(s) || window.alert(s); |
} |
}); |
if (!this.lineNumber && e) |
{ |
/** |
* @type number |
*/ |
this.lineNumber = e.lineNumber || e.line; |
} |
|
if (jsx.options.augmentPrototypes) |
{ |
/* |
* Defines Array.prototype.get(), .indexOf(), .map() and .slice() |
* if not already defined |
*/ |
jsx.object.extend(Array.prototype, { |
/** |
* @see jsx.array.get() |
*/ |
get: function (index) { |
return jsx.array.get(this, index); |
}, |
if (!this.stack && e && e.stack) |
{ |
var stack = String(e.stack).split(/\r?\n|\r/).slice(2); |
this.stack = stack.join("\n"); |
} |
}; |
|
/** |
* @see jsx.array.set() |
*/ |
set: function (index, value) { |
return jsx.array.set(this, index, value); |
}, |
jsx.Error.extend( |
(typeof Error != "undefined" && Error !== null ? Error : function () {}), |
{ |
/** |
* @memberOf jsx.Error.prototype |
*/ |
name: "jsx.Error", |
getMessage: function () { return this.message; }, |
getStackTrace: function () { return this.stack; }, |
printStackTrace: function () { |
var s = this.getStackTrace(); |
jsx.dmsg(s) || window.alert(s); |
} |
}); |
|
/** |
* Returns the first index at which a given element can be found in |
* the array, or -1 if it is not present. |
* |
* @param searchElement |
* Element to locate in the array. |
* @param {Number} fromIndex |
* The index at which to begin the search. Defaults to 0, i.e. |
* the whole array will be searched. If the index is greater than |
* or equal to the length of the array, -1 is returned, i.e. |
* the array will not be searched. If negative, it is taken as |
* the offset from the end of the array. Note that even when |
* the index is negative, the array is still searched from front |
* to back. If the calculated index is less than 0, the whole array |
* will be searched. |
* @return {number} |
* The first index at which a given element can be found in |
* the array, or -1 if it is not present. |
* @author Courtesy of developer.mozilla.org, unverified |
* @memberOf Array.prototype |
* @see ECMAScript Language Specification, 5.1 Edition, section 15.4.4.14 |
if (jsx.options.augmentPrototypes) |
{ |
/* |
* Defines Array.prototype.get(), .indexOf(), .map() and .slice() |
* if not already defined |
*/ |
indexOf: function (searchElement, fromIndex) { |
if (this === void 0 || this === null) |
{ |
throw new TypeError(); |
} |
jsx.object.extend(Array.prototype, { |
/** |
* @see jsx.array.get() |
*/ |
get: function (index) { |
return jsx.array.get(this, index); |
}, |
|
var t = Object(this); |
/** |
* @see jsx.array.set() |
*/ |
set: function (index, value) { |
return jsx.array.set(this, index, value); |
}, |
|
var len = t.length >>> 0; |
if (len === 0) { |
return -1; |
} |
/** |
* Returns the first index at which a given element can be found in |
* the array, or -1 if it is not present. |
* |
* @param searchElement |
* Element to locate in the array. |
* @param {Number} fromIndex |
* The index at which to begin the search. Defaults to 0, i.e. |
* the whole array will be searched. If the index is greater than |
* or equal to the length of the array, -1 is returned, i.e. |
* the array will not be searched. If negative, it is taken as |
* the offset from the end of the array. Note that even when |
* the index is negative, the array is still searched from front |
* to back. If the calculated index is less than 0, the whole array |
* will be searched. |
* @return {number} |
* The first index at which a given element can be found in |
* the array, or -1 if it is not present. |
* @author Courtesy of developer.mozilla.org, unverified |
* @memberOf Array.prototype |
* @see ECMAScript Language Specification, 5.1 Edition, section 15.4.4.14 |
*/ |
indexOf: function (searchElement, fromIndex) { |
if (this === void 0 || this === null) |
{ |
throw new TypeError(); |
} |
|
var n = 0; |
if (arguments.length > 0) |
{ |
n = Number(fromIndex); |
if (n !== n) { |
/* shortcut for verifying if it's NaN */ |
n = 0; |
var t = Object(this); |
|
var len = t.length >>> 0; |
if (len === 0) { |
return -1; |
} |
else if (n !== 0 && n !== Infinity && n !== -Infinity) |
|
var n = 0; |
if (arguments.length > 0) |
{ |
n = (n > 0 || -1) * Math.floor(Math.abs(n)); |
n = Number(fromIndex); |
if (n !== n) { |
/* shortcut for verifying if it's NaN */ |
n = 0; |
} |
else if (n !== 0 && n !== Infinity && n !== -Infinity) |
{ |
n = (n > 0 || -1) * Math.floor(Math.abs(n)); |
} |
} |
} |
|
if (n >= len) |
{ |
return -1; |
} |
if (n >= len) |
{ |
return -1; |
} |
|
var k = (n >= 0 ? n : Math.max(len - Math.abs(n), 0)); |
for (; k < len; k++) |
{ |
if (k in t && t[k] === searchElement) |
var k = (n >= 0 ? n : Math.max(len - Math.abs(n), 0)); |
for (; k < len; k++) |
{ |
return k; |
if (k in t && t[k] === searchElement) |
{ |
return k; |
} |
} |
} |
|
return -1; |
}, |
return -1; |
}, |
|
/** |
* Maps one array to another |
* |
* @param {Callable} callback |
* @param {Object} oThis (optional) |
* @return {Array} |
* The original array with <var>callback</var> applied to each element. |
* @see ECMAScript Language Specification, 5.1 Edition, section 15.4.4.19 |
*/ |
map: function (callback, oThis) { |
return jsx.array.map(this, callback, oThis); |
}, |
/** |
* Maps one array to another |
* |
* @param {Callable} callback |
* @param {Object} oThis (optional) |
* @return {Array} |
* The original array with <var>callback</var> applied to each element. |
* @see ECMAScript Language Specification, 5.1 Edition, section 15.4.4.19 |
*/ |
map: function (callback, oThis) { |
return jsx.array.map(this, callback, oThis); |
}, |
|
/** |
* @param {Number} start |
* @param {Number} end |
* @return {Array} |
*/ |
slice: function (start, end) { |
var a = []; |
var len = this.length >>> 0; |
var relativeStart = parseInt(start, 10); |
var k = (relativeStart < 0 |
? Math.max(len + relativeStart, 0) |
: Math.min(relativeStart, len)); |
var relativeEnd = (typeof end == "undefined" |
? len |
: parseInt(end, 10)); |
var _final = (relativeEnd < 0 |
? Math.max(len + relativeEnd, 0) |
: Math.min(relativeEnd, len)); |
var n = 0; |
while (k < _final) |
{ |
if ((k in this)) |
/** |
* @param {Number} start |
* @param {Number} end |
* @return {Array} |
*/ |
slice: function (start, end) { |
var a = []; |
var len = this.length >>> 0; |
var relativeStart = parseInt(start, 10); |
var k = (relativeStart < 0 |
? Math.max(len + relativeStart, 0) |
: Math.min(relativeStart, len)); |
var relativeEnd = (typeof end == "undefined" |
? len |
: parseInt(end, 10)); |
var _final = (relativeEnd < 0 |
? Math.max(len + relativeEnd, 0) |
: Math.min(relativeEnd, len)); |
var n = 0; |
while (k < _final) |
{ |
a[n] = this[k]; |
if ((k in this)) |
{ |
if ((k in this)) |
{ |
a[n] = this[k]; |
} |
|
++k; |
++n; |
} |
|
return a; |
} |
|
++k; |
++n; |
} |
}); |
} |
|
return a; |
} |
}); |
} |
/** |
* Formats a value for debug output |
* |
* @param value |
* @returns {string} |
*/ |
jsx.debugValue = function jsx_debugValue (value) { |
var type = typeof value; |
var _class = jsx.object.getClass(value); |
|
/** |
* Formats a value for debug output |
* |
* @param value |
* @returns {string} |
*/ |
jsx.debugValue = function jsx_debugValue (value) { |
var type = typeof value; |
var _class = jsx.object.getClass(value); |
return ( |
(_class == "Array" |
? "[" + value.map(jsx_debugValue).join(", ") + "]" |
: (jsx.object.isString(value) |
? '"' + value.replace(/["\\]/g, "\\$&") + '"' |
: value)) |
+ " : " |
+ (type == "object" || type == "function" ? _class : type) |
); |
}; |
|
return ( |
(_class == "Array" |
? "[" + value.map(jsx_debugValue).join(", ") + "]" |
: (jsx.object.isString(value) |
? '"' + value.replace(/["\\]/g, "\\$&") + '"' |
: value)) |
+ " : " |
+ (type == "object" || type == "function" ? _class : type) |
); |
}; |
|
/** |
* Invalid argument |
* |
* @constructor |
* @extends jsx.Error |
* @param {string} sReason |
* @param sGot |
* @param sExpected |
*/ |
jsx.InvalidArgumentError = |
function jsx_InvalidArgumentError (sReason, sGot, sExpected) { |
var argc = arguments.length; |
|
jsx_InvalidArgumentError._super.call(this, |
(sReason || "Invalid argument(s)") |
+ (argc > 1 ? ": " + jsx.debugValue(sGot) : "") |
+ (argc > 2 ? "; expected " + sExpected : "")); |
}; |
jsx.InvalidArgumentError.extend(jsx.Error, { |
/** |
* @memberOf jsx.InvalidArgumentError.prototype |
* Invalid argument |
* |
* @constructor |
* @extends jsx.Error |
* @param {string} sReason |
* @param sGot |
* @param sExpected |
*/ |
name: "jsx.InvalidArgumentError" |
}); |
jsx.InvalidArgumentError = |
function jsx_InvalidArgumentError (sReason, sGot, sExpected) { |
var argc = arguments.length; |
|
/** |
* Object-related exception |
* |
* @constructor |
* @param {string} sMsg |
* @extends jsx.Error |
*/ |
jsx.object.ObjectError = function jsx_object_ObjectError (sMsg) { |
jsx_object_ObjectError._super.call(this, sMsg); |
}; |
jsx.object.ObjectError.extend(jsx.Error, { |
jsx_InvalidArgumentError._super.call(this, |
(sReason || "Invalid argument(s)") |
+ (argc > 1 ? ": " + jsx.debugValue(sGot) : "") |
+ (argc > 2 ? "; expected " + sExpected : "")); |
}; |
jsx.InvalidArgumentError.extend(jsx.Error, { |
/** |
* @memberOf jsx.InvalidArgumentError.prototype |
*/ |
name: "jsx.InvalidArgumentError" |
}); |
|
/** |
* @memberOf jsx.object.ObjectError.prototype |
* Object-related exception |
* |
* @constructor |
* @param {string} sMsg |
* @extends jsx.Error |
*/ |
name: "jsx.object.ObjectError" |
}); |
jsx.object.ObjectError = function jsx_object_ObjectError (sMsg) { |
jsx_object_ObjectError._super.call(this, sMsg); |
}; |
jsx.object.ObjectError.extend(jsx.Error, { |
/** |
* @memberOf jsx.object.ObjectError.prototype |
*/ |
name: "jsx.object.ObjectError" |
}); |
|
/** |
* Property-related exception |
* |
* @constructor |
* @param {string} sMsg |
* @extends #ObjectError |
*/ |
jsx.object.PropertyError = function jsx_object_PropertyError (sMsg) { |
jsx_object_PropertyError._super.call( |
this, "No such property" + (arguments.length > 0 ? (": " + sMsg) : "")); |
}; |
jsx.object.PropertyError.extend(jsx.object.ObjectError, { |
/** |
* @memberOf jsx.object.PropertyError.prototype |
* Property-related exception§ |
* |
* @constructor |
* @param {string} sMsg |
* @extends #ObjectError |
*/ |
name: "jsx.object.PropertyError" |
}); |
jsx.object.PropertyError = function jsx_object_PropertyError (sMsg) { |
jsx_object_PropertyError._super.call( |
this, "No such property" + (arguments.length > 0 ? (": " + sMsg) : "")); |
}; |
jsx.object.PropertyError.extend(jsx.object.ObjectError, { |
/** |
* @memberOf jsx.object.PropertyError.prototype |
*/ |
name: "jsx.object.PropertyError" |
}); |
}(this)); |