Subversion Repositories JSX

Compare Revisions

Last modification

Ignore whitespace Rev 140 → Rev 141

/trunk/types.js
1,17 → 1,21
/**
* <title>Type Function Library</title>
*/
 
/**
* @return undefined
*/
function Types()
{
this.version = "1.29.6.2008050517";
this.version = "1.29.8.2009070702";
/**
* @file types.js
* @partof PointedEars' JavaScript Extensions (JSX)
* @requires object.js
* @author
* (C) 2001-2008 Thomas Lahn &lt;types.js@PointedEars.de&gt;
* (C) 2001-2009 Thomas Lahn &lt;types.js@PointedEars.de&gt;
*/
this.copyright = "Copyright \xA9 1999-2008";
this.copyright = "Copyright \xA9 1999-2009";
this.author = "Thomas Lahn";
this.email = "types.js@PointedEars.de";
this.path = "http://pointedears.de/scripts/";
20,6 → 24,17
}
 
var types = new Types();
 
/* a more compatible approach */
if (typeof jsx == "undefined") var jsx = new Object();
jsx.types = types;
 
/* allows for de.pointedears.jsx.types */
if (typeof de == "undefined") var de = new Object();
if (typeof de.pointedears == "undefined") de.pointedears = new Object();
if (typeof de.pointedears.jsx == "undefined") de.pointedears.jsx = jsx;
de.pointedears.jsx.types = types;
 
/**
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public Licnse
38,6 → 53,7
*
* [1] <http://www.gnu.org/licenses/licenses.html#GPL>
*/
 
/*
* This script file contains JSdoc[tm] comments
* to create an API documentation of it from them, see
45,12 → 61,10
*/
 
/**
* @optional string sMsg
* @return type boolean
* false
* @param sMsg : optional string
* @return false
*/
function TypesException(sMsg)
{
var TypesException = jsx.types.TypesException = function(sMsg) {
alert(
"types.js "
+ types.version
63,19 → 77,19
+ ">\n\n"
+ sMsg);
return false;
}
};
 
/**
* Returns <code>true</code> if a property is defined and its value
* is different from `undefined', <code>false</code> otherwise.
* is different from <code>undefined</code>, <code>false</code> otherwise.
*
* @optional Object o
* Optional base object. The default is the calling object.
* @argument String p
* @param o : optional Object
* Base object; the default is the calling object.
* @param p : String
* Property name; required.
* @return boolean
*/
function isDefined(o, p)
{
var isDefined = jsx.types.isDefined = function(o, p) {
if (!p)
{
p = o;
83,19 → 97,19
}
return (typeof o[p] != "undefined");
}
};
 
/**
* Returns <code>true</code> if a property is undefined or
* its value is `undefined', <code>false</code> otherwise.
*
* @optional Object o
* Optional base object. The default is the calling object.
* @argument String p
* @param o : optional Object
* Base object; the default is the calling object.
* @param p : String
* Property name; required.
* @return boolean
*/
function isUndefined(o, p)
{
var isUndefined = jsx.types.isUndefined = function(o, p) {
if (!p)
{
p = o;
103,71 → 117,37
}
 
return (typeof o[p] == "undefined");
}
};
 
/**
* Implements the instanceof operator of JavaScript 1.5
* down to JavaScript 1.1 for *one* inheritance level:
* <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
* isInstanceOf(o, Object); // yields `false'
* isInstanceOf(o, Foo); // yields `true'
* </code></pre>
*
* @author
* (C) 2003 Thomas Lahn &lt;types.js@PointedEars.de&gt;
* @argument Object a
* Expression to be determined a <var>Prototype</var> object.
* @argument Object Prototype
* Function object to be determined the prototype of a.
* @return type boolean
* <code>true</code> if <code>a</code> is an object derived
* from <var>Prototype</var>, <code>false</code> otherwise.
*/
function isInstanceOf(a, Prototype)
{
return !!(
a && Prototype
&& typeof a.constructor != "undefined"
&& a.constructor == Prototype);
}
/* Moved to object.js */
jsx.types.isInstanceOf = jsx.object.isInstanceOf;
 
/**
* @author
* (C) 2003 Thomas Lahn &lt;types.js@PointedEars.de&gt;
* @partof
* http://pointedears.de/scripts/types.js
* @requires
* isInstanceOf
* @argument Object a
* (C) 2003, 2009 Thomas Lahn &lt;object.js@PointedEars.de&gt;
* @partof http://pointedears.de/scripts/object.js
* @requires jsx.object#isInstanceOf
* @param a : Object
* Expression to be determined an array.
* @return type boolean
* @return
* <code>true</code> if <code>a</code> is an object
* derived from Array, <code>false</code> otherwise.
* Returns also <code>false</code> if the language
* version does not support Array objects (JavaScript
* before 1.1).
* @todo
*/
function isArray(a)
{
return isInstanceOf(a, typeof Array != "undefined" ? Array : null);
}
var isArray = jsx.types.isArray = function(a) {
return jsx.object.isInstanceOf(a, typeof Array != "undefined" ? Array : null);
};
 
/**
* @author
* (C) 2003 Thomas Lahn &lt;types.js@PointedEars.de&gt;
* @argument Object o
* Object to be determined iterable, i.e. to be determined
* @param o : Object
* to be determined iterable, i.e. to be determined
* whether it provides the <code>length</code> property and
* has at least the <code>0<code> (zero) property. This
* has at least the <code>0</code> (zero) property. This
* applies for non-empty <code>Array</code> objects with
* at least a first non-undefined element as well as, e.g.,
* for DOM objects implementing one of the
174,36 → 154,42
* <code>HTMLCollection</code> or
* <code>HTMLOptionsCollection</code> interfaces defined in
* the W3C DOM Level 2 Specification.
* @return type boolean
* @type boolean
* @return
* <code>true</code> if <code>o</code> is an iterable object,
* <code>false</code> otherwise.
*/
function isIterable(o)
{
var isIterable = jsx.types.isIterable = function(o) {
return !!(
o
&& typeof o.length != "undefined"
&& typeof o[0] != "undefined");
}
};
 
/**
* Converts a string using bracket property accessor syntax
* to one that uses dot property accessor syntax.
*
* @param s : string
* String of the form "root['branch']['leaf']['...']..." or
* "root[branch][leaf][...]..." to be converted. Required.
* @return type string
* @return string
* A string of the form `root.branch.leaf...' converted from
* <code>s</code>.
* <var>s</var>.
*/
function bracketsToDots(s)
{
var bracketsToDots = jsx.bracketsToDots = function(s) {
// FIXME: What about non-identifier names?
return s.replace(/\['?/g, '.').replace(/'?\]/g, '');
}
};
 
/**
* @param s: string
* Converts a string using dot property accessor syntax
* to one that uses bracket property accessor syntax.
*
* @param s : string
* of the form `root.branch.leaf' to be converted.
* Required.
* @param bStringsOnly: optional boolean
* @param bStringsOnly : optional boolean = false
* Specifies if all parts of the tree should be converted
* or not. Optional.
* If not provided or <code>false</code>, all parts are
210,203 → 196,68
* converted. If <code>true</code>, only parts are converted
* that are required to (because JavaScript identifiers as
* required by dot notation must start with a character in
* <code>[A-Za-z_$]</code>, though arguments of bracket
* notation may be of any format.)
* @return type string
* <code>[A-Za-z_$]</code>, while parameters of bracket
* notation may be in any format.)
* @return string
* A string of the form "root['branch']['leaf']" converted
* from <code>s</code>.
* from <var>s</var>.
*/
function dotsToBrackets(s, bStringsOnly)
{
var dotsToBrackets = jsx.dotsToBrackets = function(s, bStringsOnly) {
var a = s.split(".");
s = [a[0]];
 
for (var i = 1, len = a.length; i < len; i++)
{
if (!bStringsOnly)
var propName = a[i];
if (bStringsOnly && /^[a-z_$]/i.test(propName))
{
s.push("['", a[i], "']");
s.push(".", propName);
}
else
{
if (/^[a-z_$]/i.test(a[i]))
{
s.push(".", a[i]);
}
else
{
s.push("[", a[i], "]");
}
s.push("['", propName.replace(/'/g, "\\$&"), "']");
}
}
return s.join("");
}
};
 
/**
* Sets 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.
*
* @type boolean
* @return <code>true</code> if the error handler could be assigned
* successfully, <code>false</code> otherwise. Note that one reason
* for failure is that this event handler is no longer supported
* by the UA's DOM due to efforts towards adherence to Web standards.
*/
function setErrorHandler(fHandler)
{
if (!fHandler) fHandler = clearErrorHandler;
if (typeof window != "undefined" && typeof window.onerror != "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);
}
 
/**
* 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.
*
* @type boolean
* @return Always <code>true</code>
*/
function clearErrorHandler()
{
if (typeof window != "undefined" && window.onerror)
{
// 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;
}
 
/**
* Determines whether a property is likely to be callable.
*
* @author
* (C) 2003-2008 Thomas Lahn &lt;types.js@PointedEars.de&gt;
* @params :optional Object|string|(Object,string)
* Objects to be determined a method, i.e. a
* <code>Function</code> object assigned as property of
* another object. Each argument may also be a string
* to be evaluated and so is applicable to unknown properties.
* If an argument is followed by a string argument, it is
* assumed that the argument is the object and the string
* argument is the name of the property to be tested.
* @return
* <code>true</code> if all arguments refer to methods,
* <code>false</code> otherwise.
* @type boolean
* @see isMethodType()
/*
* 1.29.7.2008052911: isMethod() moved to object.js for _hasOwnProperty();
* dependencies should ensure backwards-compatibility
*/
function isMethod()
{
for (var i = 0, len = arguments.length,
rxMethod = /^\s*(function|object|unknown)\s*$/i;
i < len; i++)
{
var arg = arguments[i];
 
if (rxMethod.test(typeof arg) && arg
&& typeof arguments[i + 1] == "string")
{
// if the property is not a method
if (!(rxMethod.test(typeof arg[arguments[i + 1]])
&& arg[arguments[i + 1]]))
{
return false;
}
i++;
continue;
}
if (typeof arg == "string") arg = eval(arg);
 
// if the property is not a method
if (!(rxMethod.test(typeof arg) && arg))
{
return false;
}
}
return true;
}
 
function isMethod2()
{
for (var i = 0, len = arguments.length; i < len; i++)
{
var arg = arguments[i];
 
if (typeof arg == "string")
{
setErrorHandler();
arg = eval(arg);
clearErrorHandler();
}
else if (arg.constructor == Array)
{
setErrorHandler();
var o = (typeof arg[0] == "string")
? eval(arg[0])
: arg[0];
clearErrorHandler();
if (o && arg.length > 1)
{
setErrorHandler();
if (typeof o[arg[1]] == "string")
arg = eval(o[arg[1]]);
clearErrorHandler();
}
else
{
arg = 0;
}
}
 
// if the property is not a method
if (!(/\b(function|object)\b/i.test(typeof arg) && arg))
{
return false;
}
}
return true;
}
 
/**
* Determines whether a feature is available.
*
* @author
* (C) 2008 Thomas Lahn &lt;types.js@PointedEars.de&gt;
* @param o: Object
* @param o : Object
* Base object
* @params string
* @param : string
* Name(s) of the property/properties that are required for
* the feature. For example, passing "foo" and "bar"
* determines whether o["foo"]["bar"] is an available feature.
* @return
* @return boolean
* The feature's value if the arguments refer to a feature,
* <code>false</code> otherwise. Note that if a feature
* has type boolean, you should therefore not use this method
* to determine its availability.
* @type boolean
* has <code>boolean</code> documented as its type, you
* should therefore not use this method to determine its
* availability.
*
* Also, if a reference leading to the feature resolves to
* a value for that the result of the <code>typeof</code>
* operation is <code>"undefined"</code>, testing of further
* arguments will stop and <code>true</code> will be returned
* because <code>"undefined"</code> indicates a host object's
* method in MSHTML and access to the property value causes
* a runtime exception; therefore, in this case you can use
* the return value of this method only as an indicator that
* there is such a method.
*/
function isFeature(o)
{
var isFeature = jsx.types.isFeature = function(o) {
if (typeof o != "undefined" && o)
{
for (var i = 1, len = arguments.length; i < len; i++)
413,9 → 264,12
{
var arg = arguments[i];
if (typeof o[arg] != "undefined" && o[arg])
var t = typeof o[arg], isUnknown;
if ((isUnknown = /^\s*unknown\s*$/i.test(t))
|| !/^\s*undefined\s*$/i.test(t) && o[arg])
{
o = o[arg];
if (isUnknown) break;
}
else
{
426,32 → 280,4
}
return o;
}
 
/**
* @param s: optional string
* String to be determined a method type, i.e. "object"
* or "unknown" in IE, "function" otherwise. The type must
* have been retrieved with the `typeof' operator, thus this
* method is applicable to unknown properties while
* <code>isMethod()</code> is not. 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 && (AND)-combine the <code>isMethodType(...)</code>
* expression with the method reference identifier.
* @type boolean
* @return
* <code>true</code> if <code>s</code> is a method type,
* <code>false</code> otherwise.
* @author
* (C) 2003-2008 Thomas Lahn &lt;types.js@PointedEars.de&gt;
* Distributed under the GNU GPL v3 and later.
* @partof
* http://pointedears.de/scripts/types.js
* @see isMethod()
*/
function isMethodType(s)
{
return /^\s*(function|object|unknown)\s*$/i.test(s);
}
};