Subversion Repositories JSX

Compare Revisions

Last modification

Regard whitespace Rev 536 → Rev 535

/branches/live/dom.js
97,34 → 97,33
var jsx = {};
}
 
/**
* @namespace
*/
jsx.dom = (/** @constructor */ function () {
/* Imports */
var _jsx_object = jsx.object;
var _isMethod = _jsx_object.isMethod;
var _isHostMethod = _jsx_object.isHostMethod;
var _getKeys = _jsx_object.getKeys;
var _isArray = _jsx_object.isArray;
jsx.dom = {
version: "$Id$",
//var dhtmlDocURL = dhtmlPath + "dhtml.htm";
copyright: "Copyright \xA9 2002-2013",
author: "Thomas Lahn",
email: "js@PointedEars.de",
path: "http://pointedears.de/scripts/"
};
jsx.dom.URI = jsx.dom.path + "dom.js";
//this.docURI = this.path + "dhtml.htm";
 
/* Private variables */
var _hasDocumentAll = false;
var _hasDocumentLayers = false;
var _hasGetElementsByTagName = false;
 
function _dummy()
if (typeof document != "undefined")
{
return null;
}
jsx.dom.hasDocumentAll = false;
 
var _getElementById = (function () {
jsx.dom.getElementById = jsx.dom.getElemById = jsx.dom.getEBI = jsx.dom.gEBI = (
function () {
if (typeof document == "undefined")
{
return _dummy;
return function () {
return null;
};
}
 
if (_isMethod(document, "getElementById"))
var jsx_object = jsx.object;
 
if (jsx_object.isMethod(document, "getElementById"))
{
/**
* @param {string} sId
141,7 → 140,7
};
}
 
if ((_hasDocumentAll = _isMethod(document, "all")))
if ((jsx.dom.hasDocumentAll = jsx_object.isMethod(document, "all")))
{
return function (sId) {
return document.all(sId);
151,15 → 150,24
return function (sId) {
return document[sId];
};
}());
}
)();
 
var _getElementsByName = (function () {
jsx.dom.hasDocumentLayers = false;
 
jsx.dom.getElementsByName = jsx.dom.getElemByName = jsx.dom.gEBN = (
function () {
function dummy()
{
return null;
}
 
if (typeof document == "undefined")
{
return _dummy;
return dummy;
}
 
if (_isMethod(document, "getElementsByName"))
if (jsx.object.isMethod(document, "getElementsByName"))
{
/* W3C DOM Level 2 HTML */
/**
177,7 → 185,7
return result;
};
}
else if (_hasDocumentAll)
else if (jsx.dom.hasDocumentAll)
{
/* IE4 DOM */
return function (sName, index) {
190,7 → 198,7
return result;
};
}
else if ((_hasDocumentLayers = (typeof document.layers == "object")))
else if ((jsx.dom.hasDocumentLayers = (typeof document.layers == "object")))
{
/* NN4 DOM */
return function (sName, index) {
204,11 → 212,17
};
}
 
return _dummy;
}());
return dummy;
}()
);
 
var _getElementsByTagName = (function () {
if (_jsx_object.isNativeMethod(jsx, "xpath", "evaluate"))
jsx.dom.hasGetElementsByTagName = false;
 
jsx.dom.getElementsByTagName = jsx.dom.getElemByTagName = jsx.dom.gEBTN = (
function () {
var jsx_object = jsx.object;
 
if (jsx_object.isNativeMethod(jsx, "xpath", "evaluate"))
{
/* W3C DOM Level 3 XPath */
/**
248,9 → 262,9
};
}
 
if ((_hasGetElementsByTagName =
if ((jsx.dom.hasGetElementsByTagName =
(typeof document != "undefined"
&& _isMethod(document, "getElementsByTagName"))))
&& jsx_object.isMethod(document, "getElementsByTagName"))))
{
/* W3C DOM Level 2 Core */
/**
281,7 → 295,7
oContextNode = document;
}
 
if (!_isMethod(oContextNode, "getElementsByTagName"))
if (!jsx_object.isMethod(oContextNode, "getElementsByTagName"))
{
return null;
}
296,7 → 310,7
};
}
 
if (_hasDocumentAll && isMethod(document.all, "tags"))
if (jsx.dom.hasDocumentAll && isMethod(document.all, "tags"))
{
/**
* @param {string} sTagName
321,7 → 335,7
oContextNode = document;
}
 
if (!_isMethod(oContextNode, "all", "tags"))
if (!jsx.object.isMethod(oContextNode, "all", "tags"))
{
return null;
}
339,15 → 353,21
return function () {
return null;
};
}());
}()
);
 
var _getElementByIndex = (function () {
jsx.dom.getElementByIndex = jsx.dom.getElemByIndex = jsx.dom.gEBIdx = (function () {
function dummy()
{
return null;
}
 
if (typeof document == "undefined")
{
return _dummy;
return dummy;
}
 
if (_hasGetElementsByTagName)
if (jsx.dom.hasGetElementsByTagName)
{
/**
* @param {number} index
358,7 → 378,7
};
}
 
if (_hasDocumentAll)
if (jsx.dom.hasDocumentAll)
{
/**
* @param {number} index
369,7 → 389,7
};
}
 
if (_hasDocumentLayers)
if (jsx.dom.hasDocumentLayers)
{
/**
* @param {number} index
380,654 → 400,56
};
}
 
return _dummy;
return dummy;
}());
 
var _attrMap = {
alink: "aLink",
accesskey: "accessKey",
bgcolor: "bgColor",
cellpadding: "cellPadding",
cellspacing: "cellSpacing",
"char": "ch",
charoff: "chOff",
"class": "className",
codebase: "codeBase",
codetype: "codeType",
colspan: "colSpan",
datetime: "dateTime",
frameborder: "frameBorder",
"for": "htmlFor",
ismap: "isMap",
longdesc: "longDesc",
maxlength: "maxLength",
marginheight: "marginHeight",
marginwidth: "marginWidth",
nohref: "noHref",
noresize: "noResize",
noshade: "noShade",
nowrap: "noWrap",
readonly: "readOnly",
rowspan: "rowSpan",
tabindex: "tabIndex",
usemap: "useMap",
valuetype: "valueType",
vlink: "vLink"
};
 
/**
* Sets the value of an attribute of an HTMLElement object.
*
* @author
* (C) 2003, 2006 Thomas Lahn <dhtml.js@PointedEars.de>
* @param o
* @param {string} sAttrName
* Name of the attribute for which the value should be set.
* Attribute names for which an ECMAScript language binding
* is defined in W3C DOM Level 2 HTML, are automatically
* mapped to the corresponding element object property.
* All attribute names are automatically mapped to their
* camelCased equivalent.
*
* Semicolon-separated style property declarations (in
* form of colon-separated name-value pairs each) of a
* <code>style</code> attribute value are mapped to the
* corresponding properties of the object referenced by
* the <code>style</code> property of the element object.
* Declarations are evaluated from left to right, where
* property values complement or replace the previously
* defined ones.
* @param attrValue
* Value of the attribute to be set. The value is
* converted to number if it can be interpreted as such.
* @return {any}
* The value of the attribute of the element object;
* a null-string if no matching object exists or if the DOM
* does not provide retrieval of the attribute's values.
*/
function _setAttr (o, sAttrName, attrValue)
{
var result = "";
 
if (o && sAttrName)
{
/* camel-case specific attribute names */
if (typeof attrMap[sAttrName] != "undefined")
{
sAttrName = _attrMap[sAttrName];
}
 
var strToValue =
/**
* Converts a string, if possible, to a number
*
* @param {string} s
* @return {string|number}
* The converted value
/*
* Apart from isNS4DOM, none of these object-inference properties is used
* anymore; they are still here for backwards compatibility only
*/
function (s) {
s = s.replace(/^["']|["']$/g, "");
return isNaN(s) ? s : +s;
};
//this.isW3CDOM = jsx.object.isMethod(document, "getElementById");
//this.isOpera = typeof window.opera != "undefined";
jsx.dom.isNS4DOM = typeof document.layers != "undefined";
//this.isIE4DOM = typeof document.all == "object" && !this.isOpera;
//this.supported = this.isW3CDOM || this.isNS4DOM || this.isOpera
// || this.isIE4DOM;
 
if (typeof attrValue != "undefined")
{
attrValue = strToValue(attrValue);
if (sAttrName == "style" && typeof attrValue == "string")
{
var styleProps = attrValue.split(/\s*;\s*/);
for (var i = 0, len = styleProps.length; i < len; i++)
{
var
stylePair = styleProps[i].split(/\s*:\s*/),
stylePropName = stylePair[0].toLowerCase();
/* DOM preselection (why?) */
//this.W3CDOM = 3;
//this.IE4DOM = 2;
//this.NS4DOM = 1;
//this.DOM = this.supported
// && (this.isW3CDOM && this.W3CDOM)
// || (this.isIE4DOM && this.IE4DOM)
// || (this.isNS4DOM && this.NS4DOM);
 
jsx.dom.css.setStyleProperty(o, stylePropName,
strToValue(stylePair[1]));
result = jsx.dom.css.getStyleProperty(o, stylePropName);
}
}
else
/* allows for de.pointedears.jsx.dom */
if (typeof de == "undefined")
{
result = o[sAttrName] = attrValue;
}
}
else if (!(o[sAttrName] = true))
{
result = o[sAttrName] = sAttrName;
}
}
 
return result;
}
 
/**
* Creates a node or several nodes from an object.
*
* Creates a DOM {@link Node} or an {@link Array} of several
* <code>Node</code>s from the argument, depending on its type:
* <table>
* <thead>
* <tr>
* <th>Type</th>
* <th>Return value</th>
* </tr>
* </thead>
* <tbody>
* <tr>
* <th>{@link String}</th>
* <td>{@link Text}</td>
* </tr>
* <tr>
* <th><code>Array</code> of {@link Object} or <code>String</code></th>
* <td><code>Array</code> of <code>Node</code>. The input
* <code>Array</code>'s elements are processed recursively.</td>
* </tr>
* <tr>
* <th><code>Object</code></th>
* <td>{@link Element}. The following of the input
* <code>Object</code>'s properties are considered:
* <table>
* <thead>
* <th>Property</th>
* <th>Expected type</th>
* <th>Meaning</th>
* </thead>
* <tbody>
* <tr>
* <th><code><var>elementType</var></code> or
* <code><var>type</var></code></th>
* <td><code>String</code></td>
* <td>Element type (case-sensitivity depends on
* the document type)</td>
* </tr>
* <!--<tr>
* <th><code><var>attributes</var></code></th>
* <td><code>Object</code></td>
* <td>Attributes of the element. All attributes
* are created in the <code>null</code> namespace.</td>
* </tr>-->
* <tr>
* <th><code><var>properties</var></code></th>
* <td><code>Object</code></td>
* <td>Properties of the element object. The property
* <code>style</code> is handled specially: Its
* value should be an <code>Object</code> whose
* property names are <code>style</code> property
* names and whose property values are the
* corresponding values, as supported by
* {@link jsx.dom.css#setStyleProperty()}.
* <!--Note that some properties may overwrite
* attributes.-->
* </tr>
* <tr>
* <th><code><var>childNodes</var></code></th>
* <td><code>Array</code> of <code>Object</code>
* or <code>String</code></td>
* <td>Child nodes of the element node.
* The elements of the <code>Array</code>
* are processed recursively.
* </tr>
* </tbody>
* </table></td>
* </tr>
* </tbody>
* </table>
* @param {Array|Object} data
* @return TextNode|Array[Node]|Element
* @namespace
*/
function _createNodesFromObj (data)
{
if (typeof data.valueOf() == "string")
{
return document.createTextNode(data);
var de = {};
}
 
/* Support ES5 strict mode */
var me = _createNodesFromObj;
 
/* If input is an Array, output is an Array of Nodes */
if (_isArray(data))
if (typeof de.pointedears == "undefined")
{
var a = [];
 
for (var i = 0, len = data.length; i < len; ++i)
{
a[i] = me(data[i]);
}
 
return a;
}
 
var el = document.createElement(data.elementType || data.type);
if (!el)
{
return null;
}
 
var attributes = data.attributes;
if (attributes && _isHostMethod(el, "setAttribute"))
{
var keys = _getKeys(attributes);
 
for (var i = 0, len = keys.length; i < len; ++i)
{
var attrName = keys[i];
el.setAttribute(attrName, attributes[attrName]);
}
}
 
var properties = data.properties;
if (properties)
{
keys = _getKeys(properties);
 
for (i = 0, len = keys.length; i < len; ++i)
{
var propName = keys[i];
 
if (propName == "style")
{
var style = properties[propName];
var _setStyleProperty = jsx.object.getFeature(jsx.dom, "css", "setStyleProperty");
if (typeof style != "string" && typeof _setStyleProperty != "function")
{
jsx.warn("JSX:dom/css.js:jsx.dom.css.setStyleProperty()"
+ " is recommended for setting style object properties");
el[propName] = style;
}
else
{
var styleKeys = _getKeys(style);
for (var i = 0, len = styleKeys.length; i < len; ++i)
{
var stylePropName = styleKeys[i];
_setStyleProperty(el, stylePropName, style[stylePropName]);
}
}
}
else
{
el[propName] = properties[propName];
}
}
}
 
var nodes = data.childNodes;
for (var i = 0, len = nodes && nodes.length; i < len; ++i)
{
el.appendChild(me(nodes[i]));
}
 
return el;
}
 
/**
* Adds a class name to the <code>class</code> attribute of
* an {@link Element}.
*
* @param {Element} o
* @param {string} sClassName
* @return {boolean}
* <code>true</code> if the class name could be added successfully or
* was already there, <code>false</code> otherwise.
* @namespace
*/
function _hasClassName (o, sClassName)
{
if (sClassName)
{
if (_isHostMethod(o, "classList", "contains"))
{
/* W3C DOM Level 4 */
return o.classList.contains(sClassName);
de.pointedears = {};
}
 
var rx = new RegExp("(^\\s*|\\s+)" + sClassName + "(\\s*$|\\s)");
return rx.test(sClassName);
}
}
 
/**
* Removes all occurences of a class name from the
* <code>class</code> attribute of an {@link Element}.
*
* For compatibility, if possible removes the <code>class</code>
* attribute if it is empty afterwards.
*
* @param {Element} o
* @param {string} sClassName
* @return {boolean}
* <code>true</code> if successful, <code>false</code> otherwise.
*/
function _removeClassName (o, sClassName)
if (typeof de.pointedears.jsx == "undefined")
{
if (_isHostMethod(o, "classList", "remove"))
{
/* W3C DOM Level 4 */
o.classList.remove(sClassName);
}
else
{
var curClassNames = o.className;
var newClassNames = curClassNames.replace(
new RegExp(("(^\\s*|\\s+)" + sClassName + "(\\s*$|(\\s))"), "g"),
"$3");
o.className = newClassNames;
 
if (!newClassNames && _isMethod(o, "removeAttribute"))
{
o.removeAttribute("class");
}
}
 
return !_hasClassName(o, sClassName);
}
 
/**
* Appends a child node to a parent node.
*
* @param {Node} parentNode
* @param {Node} childNode
* @return {boolean}
* <code>true</code> on success, <code>false</code> otherwise.
* @namespace
*/
function _appendChild (parentNode, childNode)
{
if (parentNode)
{
if (_isMethod(parentNode, "appendChild"))
{
parentNode.appendChild(childNode);
return true;
de.pointedears.jsx = jsx;
}
else if (_isMethod(parentNode, "insertAdjacentElement"))
{
parentNode.insertAdjacentElement("beforeEnd", childNode);
return true;
}
}
 
return false;
}
 
function _insertBefore (parentNode, newChild, refChild)
{
if (parentNode)
{
if (_isMethod(parentNode, "insertBefore"))
{
/* W3C DOM */
parentNode.insertBefore(newChild, refChild);
return true;
}
 
/* MSHTML 4 DOM */
if (refChild)
{
if (_isMethod(refChild, "insertAdjacentElement"))
{
refChild.insertAdjacentElement("beforeBegin", newChild);
return true;
}
}
else
{
if (_isMethod(parentNode, "insertAdjacentElement"))
{
parentNode.insertAdjacentElement("afterBegin", newChild);
return true;
}
}
}
 
return false;
}
 
/**
* Removes a child node from a parent node.
*
* @param {Node} parentNode
* @param {Node} childNode
* @return {boolean}
* <code>true</code> on success, <code>false</code> otherwise.
*/
function _removeChild (parentNode, childNode)
{
if (parentNode)
{
if (_isMethod(parentNode, "removeChild"))
{
/* W3C DOM */
parentNode.removeChild(childNode);
return true;
}
else if (_isMethod(childNode, "removeNode"))
{
/* MSHTML 4 DOM */
childNode.removeNode(true);
return true;
}
}
 
return false;
}
 
/**
* Exception thrown if an invalid Node reference is passed
*
* @function
*/
var _InvalidNodeError = (function (contextNode) {
jsx.Error.call(this, contextNode);
}).extend(jsx.Error, {
name: "jsx.dom.InvalidNodeError"
});
 
function jsx_dom_collectNamespaces (namespaces, contextNode) {
var me = jsx_dom_collectNamespaces;
 
if (!namespaces)
{
jsx.warn("`namespaces' is not convertible to an Object; argument is not modified.");
namespaces = {};
}
 
/* Scan entire document by default */
if (!contextNode)
{
contextNode = document.documentElement;
}
 
/* if DOCUMENT_NODE, use root element */
if (contextNode.nodeType == 9)
{
contextNode = contextNode.documentElement;
}
 
if (!contextNode || contextNode.nodeType != 1)
{
jsx.throwThis(_InvalidNodeError, contextNode);
return null;
}
 
for (var i = 0, attribs = contextNode.attributes, len = attribs && attribs.length;
i < len;
++i)
{
var attr = attribs[i];
var attr_name = attr.name;
var matches;
 
if ((matches = String(attr_name).match(/^xmlns($|:(.+))/)))
{
var original_prefix = matches[2];
var prefix = original_prefix || "_";
 
if (typeof namespaces[prefix] == "undefined")
{
var attr_value = attr.value;
 
/*
* Default NS declaration with empty value means _no_ namespace,
* see <http://www.w3.org/TR/REC-xml-names/#defaulting>
*/
if (!original_prefix && attr_value == "")
{
attr_value = null;
}
 
namespaces[prefix] = attr_value;
}
}
}
 
for (var i = 0, childNodes = contextNode.childNodes, len = childNodes && childNodes.length;
i < len;
++i)
{
var childNode = childNodes[i];
 
/* If ELEMENT_NODE, recurse */
if (childNode.nodeType == 1)
{
jsx.tryThis(
function() {
me(namespaces, childNode);
},
function (e) {
if (e.constructor == _InvalidNodeError)
{
jsx.throwThis(e);
}
});
}
}
 
return namespaces;
}
 
/**
* Retrieves descendant focusable elements in order of their
* "tabindex" attribute.
*
* @author
* (C) 2004 Thomas Lahn <dhtml.js@PointedEars.de>
* @requires
* http://pointedears.de/scripts/collection.js
* @param {Document|Element} o (optional)
* Reference to a {@link dom2-core#Document Document} or
* {@link dom2-core#Element Element} object from which to retrieve
* descendant elements. If omitted or evaluated to
* <code>false</code>, it is tried to use the calling object.
* @return {Collection}
* A reference to a {@link #Collection} object containing
* the descendant elements of <var>o</var> or the calling
* {@link dom2-core#Document Document}/{@link dom2-core#Element Element}
* object in "tabindex" order: Elements with "tabindex" > 0 come first,
* followed by elements with "tabindex" == 0 or where either
* "tabindex" is not set or not applicable. Note: An element
* with a "tabindex" of 1 will will be the first element
* in the resulting collection but for design reasons will
* have an index of 0 (but since the Collection prototype
* provides an iterator, this does not need to disturb you).
* Additional note: Unlike specified, disabled elements will
* participate in the tabbing order (so they can be enabled
* later without this method to be re-called.)
*/
function _getElementsByTabIndex (o)
{
var aIndexedElements = new Array();
var aUnindexedElements = new Array();
 
/* makes the method applicable to Document and Element objects */
if (!o
&& typeof this.constructor != "undefined"
&& /Document|Element/.test(this.constructor))
{
o = this;
}
 
if (_isMethod(o, "getElementsByTagName"))
{
var es = o.getElementsByTagName("*");
 
if (es && typeof es.length != "undefined")
{
var l = es.length;
 
for (var i = 0, e; i < l; i++)
{
e = es[i];
 
if (typeof e.tabIndex != "undefined")
{
/* !null && !0 */
if (e.tabIndex)
{
/*
* tabindex="1" --> index == 0; use e.tabIndex
* and a "zero dummy" if you do not like this
*/
aIndexedElements[e.tabIndex - 1] = e;
}
else
{
aUnindexedElements[aUnindexedElements.length] = e;
}
}
}
}
}
 
return new Collection(aIndexedElements.concat(aUnindexedElements));
}
 
var _jsx_dom = {
/**
* @memberOf jsx.dom
*/
version: "$Id$",
copyright: "Copyright \xA9 2002-2013",
author: "Thomas Lahn",
email: "js@PointedEars.de",
path: "http://pointedears.de/scripts/",
 
hasDocumentAll: _hasDocumentAll,
hasDocumentLayers: _hasDocumentLayers,
hasGetElementsByTagName: _hasGetElementsByTagName,
 
/*
* Apart from isNS4DOM, none of these object-inference properties is used
* anymore; they are still here for backwards compatibility only
*/
//isW3CDOM: _isMethod(document, "getElementById"),
//isOpera: typeof window.opera != "undefined";
isNS4DOM: typeof document.layers != "undefined",
//isIE4DOM: typeof document.all == "object" && !this.isOpera,
 
/* DOM preselection (why?) */
//W3CDOM: 3,
//IE4DOM: 2,
//NS4DOM: 1;
 
getElementById: _getElementById,
getElemById: _getElementById,
getEBI: _getElementById,
gEBI: _getElementById,
 
getElementsByName: _getElementsByName,
getElemByName: _getElementsByName,
gEBN: _getElementsByName,
 
getElementsByTagName: _getElementsByTagName,
getElemByTagName: _getElementsByTagName,
gEBTN: _getElementsByTagName,
 
getElementByIndex: _getElementByIndex,
getElemByIndex: _getElementByIndex,
gEBIdx: _getElementByIndex,
 
/**
* Shows an exception alert and allows for
* displaying a stack trace.
*
1035,9 → 457,8
* Error message to be displayed.
* @return {boolean}
* Always <code>false</code>
* @deprecated
*/
DHTMLException: function (sMessage) {
jsx.dom.DHTMLException = function (sMessage) {
/* Prevent exceptions from "bubbling" on (keyboard) event */
if (!jsx.dom.allowExceptionMsg)
{
1048,7 → 469,7
 
jsx.setErrorHandler();
var stackTrace =
_isMethod(_global, "Error") && (new Error()).stack || "";
jsx.object.isMethod(_global, "Error") && (new Error()).stack || "";
 
jsx.clearErrorHandler();
 
1068,9 → 489,9
 
jsx.dom.allowExceptionMsg = true;
return false;
},
};
 
write: function (s) {
jsx.dom.write = function (s) {
var result = jsx.tryThis(
function () {
document.write(s);
1095,7 → 516,7
if (scripts && scripts.length > 0)
{
var lastScript = scripts[scripts.length - 1];
result2 = !!_insertBefore(lastScript.parentNode,
result2 = !!lastScript.parentNode.insertBefore(
document.createTextNode(s), lastScript.nextSibling);
}
 
1103,8 → 524,11
});
});
 
/* fix circular reference */
s = null;
 
return result;
},
};
 
/**
* Retrieves an HTMLElement object or a collection of such
1129,7 → 553,7
* specified criteria; <code>null</code> if no matching object
* exists.
*/
getElem: function (sType, sValue, index) {
jsx.dom.getElem = function (sType, sValue, index) {
/**
* Calls DHTMLException() for an invalid type.
*/
1182,7 → 606,7
}
 
return o;
},
};
 
/**
* Retrieves the content of an HTMLElement object.
1198,7 → 622,7
* no such element object exists or if the DOM does not provide
* retrieval of the element's content.
*/
getCont: function (oElement, bHTML) {
jsx.dom.getCont = function (oElement, bHTML) {
var sResult = "";
 
if (oElement)
1232,7 → 656,7
}
 
return sResult;
},
};
 
/**
* Specifies the content of an HTMLElement object.
1246,7 → 670,7
* <code>true</code> if successful, <code>false</code>
* otherwise.
*/
setCont: function (oElement, sNodeValue) {
jsx.dom.setCont = function (oElement, sNodeValue) {
if (oElement)
{
/* DOM Level 2 Core */
1283,7 → 707,7
}
 
return false;
},
};
 
/**
* Returns the text content of a document node.
1299,7 → 723,7
* The text content of @{(oNode)}.
* @todo Duplicate of getCont(..., false)?
*/
getContent: function (oNode, bGetHTML) {
jsx.dom.getContent = function (oNode, bGetHTML) {
var text = "";
 
if (oNode)
1336,7 → 760,7
}
 
return text;
},
};
 
/**
* Sets the text content of a document node.
1347,9 → 771,9
* Reference to the document node.
* @param {string} sContent
* @return {boolean}
* <code>true</code> if successful, <code>false</code> otherwise.
* <code>true</code> if successful, <code<false</code> otherwise.
*/
setTextContent: function (oNode, sContent) {
jsx.dom.setTextContent = function (oNode, sContent) {
var result = false;
 
if (oNode)
1381,7 → 805,7
}
 
return result;
},
};
 
/**
* Retrieves the value of an attribute of an HTMLElement object
1400,12 → 824,12
* a null-string if no matching object exists or if the DOM
* does not provide retrieval of the attribute's values.
*/
getAttr: function (oElement, sAttrName) {
jsx.dom.getAttr = function (oElement, sAttrName) {
var result = "";
 
if (oElement)
{
if (_isMethod(oElement, "getAttribute"))
if (jsx.object.isMethod(oElement, "getAttribute"))
{
result = oElement.getAttribute(sAttrName);
}
1416,13 → 840,129
}
 
return result;
},
};
 
attrMap: _attrMap,
jsx.dom.attrMap = {
alink: "aLink",
accesskey: "accessKey",
bgcolor: "bgColor",
cellpadding: "cellPadding",
cellspacing: "cellSpacing",
"char": "ch",
charoff: "chOff",
"class": "className",
codebase: "codeBase",
codetype: "codeType",
colspan: "colSpan",
datetime: "dateTime",
frameborder: "frameBorder",
"for": "htmlFor",
ismap: "isMap",
longdesc: "longDesc",
maxlength: "maxLength",
marginheight: "marginHeight",
marginwidth: "marginWidth",
nohref: "noHref",
noresize: "noResize",
noshade: "noShade",
nowrap: "noWrap",
readonly: "readOnly",
rowspan: "rowSpan",
tabindex: "tabIndex",
usemap: "useMap",
valuetype: "valueType",
vlink: "vLink"
};
 
setAttr: _setAttr,
 
/**
* Sets the value of an attribute of an HTMLElement object.
*
* @author
* (C) 2003, 2006 Thomas Lahn &lt;dhtml.js@PointedEars.de&gt;
* @param o
* @param {string} sAttrName
* Name of the attribute for which the value should be set.
* Attribute names for which an ECMAScript language binding
* is defined in W3C DOM Level 2 HTML, are automatically
* mapped to the corresponding element object property.
* All attribute names are automatically mapped to their
* camelCased equivalent.
*
* Semicolon-separated style property declarations (in
* form of colon-separated name-value pairs each) of a
* <code>style</code> attribute value are mapped to the
* corresponding properties of the object referenced by
* the <code>style</code> property of the element object.
* Declarations are evaluated from left to right, where
* property values complement or replace the previously
* defined ones.
* @param attrValue
* Value of the attribute to be set. The value is
* converted to number if it can be interpreted as such.
* @return {any}
* The value of the attribute of the element object;
* a null-string if no matching object exists or if the DOM
* does not provide retrieval of the attribute's values.
*/
jsx.dom.setAttr = function (o, sAttrName, attrValue) {
var result = "";
 
if (o && sAttrName)
{
var attrMap = jsx.dom.attrMap;
 
/* camel-case specific attribute names */
if (typeof attrMap[sAttrName] != "undefined")
{
sAttrName = attrMap[sAttrName];
}
 
var strToValue =
/**
* Converts a string, if possible, to a number
*
* @param {string} s
* @return {string|number}
* The converted value
*/
function (s) {
s = s.replace(/^["']|["']$/g, "");
return isNaN(s) ? s : +s;
};
 
if (typeof attrValue != "undefined")
{
attrValue = strToValue(attrValue);
if (sAttrName == "style" && typeof attrValue == "string")
{
var styleProps = attrValue.split(/\s*;\s*/);
for (var i = 0, len = styleProps.length; i < len; i++)
{
var
stylePair = styleProps[i].split(/\s*:\s*/),
stylePropName = stylePair[0].toLowerCase();
 
jsx.dom.css.setStyleProperty(o, stylePropName,
strToValue(stylePair[1]));
result = jsx.dom.css.getStyleProperty(o, stylePropName);
}
}
else
{
result = o[sAttrName] = attrValue;
}
}
else if (!(o[sAttrName] = true))
{
result = o[sAttrName] = sAttrName;
}
}
 
return result;
};
 
/**
* Creates an element of the type specified, using the
* <code>document.createElement()</code> method if supported.
* This method works with MSIE, too, for if JScript is used,
1429,6 → 969,16
* it is tried to use the start tag as is instead of passing
* only the element type, and adding properties later.
*
* @function
* @author
* &copy; 2004, 2006, 2010 Thomas Lahn &lt;dhtml.js@PointedEars.de&gt;
* @see <a href="dom2-core#ID-2141741547">DOM Level 2 Core: Document::createElement()</a>
* @see <a href="msdn#workshop/author/dhtml/reference/methods/createelement.asp">MSDN Library: createElement()</a>
*/
jsx.dom.createElement = (function () {
var _setAttr = jsx.dom.setAttr;
 
/**
* @param {string} sTag
* Start tag or element type of the element to be created.
* Passing a start tag even works if the UA is not MSIE,
1440,28 → 990,14
* and the <code>localName</code>, <code>prefix</code>,
* and <code>namespaceURI</code> properties set to
* <code>null</code>.
* @author
* &copy; 2004, 2006, 2010 Thomas Lahn &lt;dhtml.js@PointedEars.de&gt;
* @see <a href="dom2-core#ID-2141741547">DOM Level 2 Core: Document::createElement()</a>
* @see <a href="msdn#workshop/author/dhtml/reference/methods/createelement.asp">MSDN Library: createElement()</a>
*/
createElement: function (sTag, sNamespaceURI) {
return function (sTag) {
var o = null;
 
if (sTag && typeof document != "undefined")
if (sTag
&& typeof document != "undefined"
&& jsx.object.isMethod(document, "createElement"))
{
/* NOTE: Uses RegExp() to work around misconfigured PHP (short_open_tag=1) */
var aTagComponents = sTag.replace(new RegExp("^<\?\\s*|\\s*>?$", "g"), "")
.replace(/\s*=\s*/g, "=").split(/\s+/);
 
var local_name = aTagComponents[0];
if (sNamespaceURI && _isMethod(document, "createElementNS"))
{
o = document.createElementNS(sNamespaceURI, local_name);
}
 
if (!o && _isMethod(document, "createElement"))
{
/*@cc_on @*/
/*@if (@_jscript)
o = document.createElement(sTag);
1469,10 → 1005,10
 
if (!o)
{
o = document.createElement(local_name);
}
}
 
/* NOTE: Uses RegExp() to work around misconfigured PHP (short_open_tag=1) */
var aTagComponents = sTag.replace(new RegExp("^<\?\\s*|\\s*>?$", "g"), "")
.replace(/\s*=\s*/g, "=").split(/\s+/);
o = document.createElement(aTagComponents[0]);
if (o)
{
aTagComponents.shift();
1484,15 → 1020,17
}
}
}
}
 
return o;
},
};
}());
 
/**
* Creates a SGML/HTML markup from an object.
* Creates a node or several nodes from an object.
*
* Returns a {@link string} from the argument, depending on
* its type:
* Creates a DOM {@link Node} or an {@link Array} of several
* <code>Node</code>s from the argument, depending on its type:
* <table>
* <thead>
* <tr>
1503,34 → 1041,17
* <tbody>
* <tr>
* <th>{@link String}</th>
* <td><code>string</code> with characters
* escaped according to the following table:
* <table>
* <tr>
* <th>Character</th>
* <th>Escape</th>
* <td>{@link Text}</td>
* </tr>
* <tr><td><code>"</code></td><td><code>&amp;quot;</code></td></tr>
* <tr><td><code>&amp;</code></td><td><code>&amp;amp;</code></td></tr>
* <tr><td><code>&lt;</code></td><td><code>&amp;lt;</code></td></tr>
* <tr><td><code>></code></td><td><code>&amp;gt;</code></td></tr>
* </table>
* <p>This is also used internally to ensure that
* attribute values and element content is
* properly escaped.</p></td>
* </tr>
* <tr>
* <th><code>Array</code> of {@link Object} or <code>String</code></th>
* <td>Markup s<code>string</code> of elements and text.
* The input <code>Array</code>'s elements are processed
* recursively.</td>
* <td><code>Array</code> of <code>Node</code>. The input
* <code>Array</code>'s elements are processed recursively.</td>
* </tr>
* <tr>
* <th><code>Object</code></th>
* <td>Markup <code>string</code> for one element and,
* optionally, its content. The following of
* the input <code>Object</code>'s properties
* are considered:
* <td>{@link Element}. The following of the input
* <code>Object</code>'s properties are considered:
* <table>
* <thead>
* <th>Property</th>
1577,30 → 1098,28
* </tr>
* </tbody>
* </table>
* @function
*/
jsx.dom.createElementFromObj = jsx.dom.createNodeFromObj =
jsx.dom.createNodesFromObj = (function () {
var _getKeys = jsx.object.getKeys;
var _isArray = jsx.object.isArray;
var _isHostMethod = jsx.object.isHostMethod;
 
/**
* @param {Array|Object} data
* @param {boolean} bXML
* If a true-value, empty elements use XML <code>SHORTTAG</code>
* syntax: <code>&lt;foo/></code> instead of
* <code>&lt;foo>&lt;/foo></code>.
* @return {string}
* @return TextNode|Array[Node]|Element
*/
createMarkupFromObj: function _createMarkupFromObj (data, bXML) {
return function (data) {
if (typeof data.valueOf() == "string")
{
return data.replace(/["&<>]/g, function (m) {
return ({
'"': "&quot;",
"&": "&amp;",
"<": "&lt;",
">": "&gt;"
})[m];
});
return document.createTextNode(data);
}
 
/* Support ES5 strict mode */
var me = _createMarkupFromObj;
var me = jsx.dom.createNodeFromObj;
 
/* If input is an Array, output is string of markup */
/* If input is an Array, output is an Array of Nodes */
if (_isArray(data))
{
var a = [];
1610,24 → 1129,27
a[i] = me(data[i]);
}
 
return a.join("");
return a;
}
 
var type = (data.elementType || data.type);
var el = ["<" + type];
 
var attributes = data.attributes;
if (attributes)
var el = document.createElement(data.elementType || data.type);
if (!el)
{
var keys = _getKeys(attributes);
 
for (var i = 0, len = keys.length; i < len; ++i)
{
var attrName = keys[i];
el.push(" " + attrName + '="' + me(attributes[attrName]) + '"');
return null;
}
}
 
// var attributes = data.attributes;
// if (attributes && _isHostMethod(el, "setAttribute"))
// {
// var keys = _getKeys(attributes);
//
// for (var i = 0, len = keys.length; i < len; ++i)
// {
// var attrName = keys[i];
// el.setAttribute(attrName, attributes[attrName]);
// }
// }
 
var properties = data.properties;
if (properties)
{
1639,55 → 1161,81
 
if (propName == "style")
{
el.push(' style="');
 
var style = properties[propName];
var _uncamelize = jsx.object.getFeature(jsx.dom, "css", "uncamelize")
|| function (s) { return s; };
 
var _setStyleProperty = jsx.object.getFeature(jsx.dom, "css", "setStyleProperty");
if (typeof style != "string" && typeof _setStyleProperty != "function")
{
jsx.warn("JSX:dom/css.js:jsx.dom.css.setStyleProperty()"
+ " is recommended for setting style object properties");
el[propName] = style;
}
else
{
var styleKeys = _getKeys(style);
for (var i = 0, len = styleKeys.length; i < len; ++i)
{
var stylePropName = styleKeys[i];
el.push(" " + me(_uncamelize(stylePropName)) + ": " + me(style[stylePropName]));
_setStyleProperty(el, stylePropName, style[stylePropName]);
}
}
}
else
{
el.push(" " + propName + '="' + me(properties[propName]) + '"');
el[propName] = properties[propName];
}
}
}
 
var nodes = data.childNodes;
var bEmpty = (!nodes || !nodes.length);
if (bXML && bEmpty)
for (var i = 0, len = nodes && nodes.length; i < len; ++i)
{
el.push("/");
el.appendChild(me(nodes[i]));
}
 
el.push(">");
return el;
};
}());
 
for (var i = 0, len = nodes && nodes.length; i < len; ++i)
/**
* Removes all occurences of a class name from the
* <code>class</code> attribute of an {@link Element}.
*
* For compatibility, if possible removes the <code>class</code>
* attribute if it is empty afterwards.
*
* @param {Element} o
* @param {string} sClassName
* @return {boolean}
* <code>true</code> if successful, <code>false</code> otherwise.
*/
jsx.dom.removeClassName = function (o, sClassName) {
var sRxClassName = "(^\\s*|\\s+)" + sClassName + "(\\s*$|(\\s))";
 
if (jsx.object.isHostMethod(o, "classList", "remove"))
{
el.push(me(nodes[i], bXML));
/* W3C DOM Level 4 */
o.classList.remove(sClassName);
}
else
{
var curClassNames = o.className;
var newClassNames = curClassNames.replace(
new RegExp(sRxClassName, "g"),
"$3");
o.className = newClassNames;
 
if (!bEmpty)
if (!newClassNames && jsx.object.isMethod(o, "removeAttribute"))
{
el.push("</" + type + ">");
o.removeAttribute("class");
}
}
 
return el.join("");
},
return !((new RegExp(sRxClassName)).test(o.className));
};
 
createElementFromObj: _createNodesFromObj,
createNodeFromObj: _createNodesFromObj,
createNodesFromObj: _createNodesFromObj,
jsx.dom.addClassName = (function () {
var _removeClassName = jsx.dom.removeClassName;
 
hasClassName: _hasClassName,
removeClassName: _removeClassName,
 
/**
* Adds a class name to the <code>class</code> attribute of
* an {@link Element}.
1704,12 → 1252,15
* <code>true</code> if the class name could be added successfully or
* was already there, <code>false</code> otherwise.
*/
addClassName: function (o, sClassName, bRemove) {
function _addClassName (o, sClassName, bRemove)
{
var rx = new RegExp("(^\\s*|\\s+)" + sClassName + "(\\s*$|\\s)");
 
if (bRemove)
{
_removeClassName(o, sClassName);
}
else if (_hasClassName(o, sClassName))
else if (rx.test(o.className))
{
return true;
}
1716,7 → 1267,7
 
if (sClassName)
{
if (_isHostMethod(o, "classList", "add"))
if (jsx.object.isHostMethod(o, "classList", "add"))
{
/* W3C DOM Level 4 */
o.classList.add(sClassName);
1733,11 → 1284,12
}
}
 
return _hasClassName(o, sClassName);
return rx.test(o.className);
}
},
}
 
appendChild: _appendChild,
return _addClassName;
}());
 
/**
* Appends several child nodes to a parent node in the specified order.
1747,40 → 1299,21
* @return {boolean}
* <code>true</code> on success, <code>false</code> otherwise.
*/
appendChildren: function (parentNode, childNodes) {
jsx.dom.appendChildren = function (parentNode, childNodes) {
if (parentNode)
{
var result = true;
 
for (var i = 0, len = childNodes.length; i < len; ++i)
{
var success = _appendChild(parentNode, childNodes[i]);
if (!success && result)
{
result = false;
parentNode.appendChild(childNodes[i]);
}
}
 
return result;
return true;
}
 
return false;
},
};
 
/**
* Inserts a child node before a reference child node.
*
* @param {Node} parentNode
* @param {Node} newChild
* @param {Node} refChild
* @return {boolean}
* <code>true</code> on success, <code>false</code> otherwise.
*/
insertBefore: _insertBefore,
 
removeChild: _removeChild,
 
/**
* Removes several child nodes of a parent node in reverse order.
*
* @param {Node} parentNode
1792,10 → 1325,9
* @return {boolean}
* <code>true</code> on success, <code>false</code> otherwise.
*/
removeChildren: function (parentNode, childNodes) {
jsx.dom.removeChildren = function (parentNode, childNodes) {
if (parentNode)
{
var result = true;
if (arguments.length < 2)
{
childNodes = parentNode.childNodes;
1803,20 → 1335,16
 
for (var i = childNodes.length; i--;)
{
var success = _removeChild(parentNode, childNodes[i]);
if (!success && result)
{
result = false;
parentNode.removeChild(childNodes[i]);
}
}
 
return result;
return true;
}
 
return false;
},
};
 
html2nodes: function (sHTML) {
jsx.dom.html2nodes = function (sHTML) {
var m,
rx = /(<([^\s>]+)(\s+[^>]*)?>)|([^<]+)/g,
node = document.createElement("html");
1843,202 → 1371,12
}
 
return node;
},
};
 
InvalidNodeError: _InvalidNodeError,
jsx.dom.HTMLSerializer = (
function () {
 
/**
* Collects and returns the namespaces of a node and its ancestors.
*
* Collects the namespace prefixes and URIs of <var>contextNode</var> and
* its ancestor element nodes. Duplicate prefixes with different namespace
* URI are ignored and must be resolved manually using the <var>namespaces</var>
* argument of {@link jsx.dom.xpath.createFullNSResolver()}.
*
* @param {Object} namespaces
* Contains the collected namespace declarations. Existing properties
* are preserved.
* @param {Document|Element} contextNode
* The parent node from where to start searching for namespace
* declarations. If it is a Document node, the document element node
* is used instead. The default is the document element node.
* @return {Object}
* The resulting value of <var>namespaces</var> if successful,
* <code>null</code> otherwise.
* @throws jsx.dom.InvalidNodeError if a value has been specified
* for <var>contextNode</var> that is not a reference to a Document
* node or an Element node.
* @see jsx.dom.xpath.createFullNSResolver()
*/
collectNamespaces: jsx_dom_collectNamespaces,
 
DOMParser: function (text) {
if (typeof text != "undefined")
{
this.text = text;
}
}.extend(null, {
parseFromString: function (text, contentType, namespaceURI, qualifiedName, documentType) {
function _unescape (text)
{
return text.replace(
/&(#((\d+)|x[\dA-Fa-f])|lt|gt|amp);/g,
function (m, entity, cr, dec_cr) {
if (cr)
{
if (dec_cr)
{
return String.fromCharCode(cr);
}
 
return String.fromCharCode(parseInt("0" + cr, 16));
}
 
return {
"lt": "<",
"gt": ">",
"amp": "&"
}[entity];
}
);
}
 
var text = (typeof this.text != "undefined"
? this.text
: text);
 
var rxAttributes = /\s+((\w+):)?(\w+)(\s*=\s*("[^"]*"|'[^']*'|([^\s\/>]|\/[^>])+))?/g;
var sMarkup = /[^<]+|<(\/?)(((\w+):)?(\w+))?/.source
+ "(" + rxAttributes.source + ")*"
+ /\s*(\/?)>/.source;
var rxTag = new RegExp(sMarkup, "g");
 
var root_node = null;
 
if (contentType || namespaceURI || qualifiedName || documentType)
{
if (_isMethod(document, "implementation", "createDocument"))
{
root_node = document.implementation.createDocument(
namespaceURI || {
"application/xhtml+xml": "http://www.w3.org/1999/xhtml"
}[contentType] || null,
qualifiedName || "html",
documentType || null);
}
}
 
if (!root_node && _isMethod(document, "createDocumentFragment"))
{
root_node = document.createDocumentFragment();
}
 
if (!root_node)
{
if (/\/xml$/i.test(contentType))
{
root_node = document.createElement(qualifiedName || "xml");
}
else
{
root_node = document.createElement(qualifiedName || "html");
}
}
 
var node = root_node;
 
var m;
while ((m = rxTag.exec(text)))
{
var end_tag = m[1];
var node_name = m[2];
var prefix = m[4];
var local_name = m[5];
var attributes_spec = m[6];
var self_closing = m[13];
 
if (node_name)
{
if (end_tag)
{
node = node.parentNode;
}
else
{
var namespace_URI = null;
 
if (prefix)
{
var namespaces = jsx_dom_collectNamespaces(node);
namespace_URI = namespaces && namespaces[prefix] || null;
}
 
if (namespace_URI)
{
var new_node = document.createElementNS(namespace_URI, local_name);
}
else
{
new_node = document.createElement(local_name);
}
 
node.appendChild(new_node);
node = new_node;
 
if (attributes_spec)
{
rxAttributes.lastIndex = m.index + node_name.length;
 
var mAttrib;
while ((mAttrib = rxAttributes.exec(text)))
{
var attr_prefix = mAttrib[2];
var attr_local_name = mAttrib[3];
var attr_value = mAttrib[5];
attr_value = attr_value ? _unescape(attr_value) : attr_local_name;
 
var attr_namespace_URI = null;
 
if (attr_prefix)
{
if (!namespaces)
{
 
}
 
attr_namespace_URI = namespaces && namespaces[attr_prefix] || null;
}
 
if (attr_namespace_URI)
{
node.setAttributeNS(attr_namespace_URI, attr_local_name, attr_value);
}
else
{
node.setAttribute(attr_local_name, attr_value);
}
}
}
 
if (self_closing)
{
node = node.parentNode;
}
}
}
else
{
var text = _unescape(m[0]);
node.appendChild(document.createTextNode(text));
}
}
 
return root_node;
}
}),
 
HTMLSerializer: (
function () {}
).extend("Object", {
serializeToString: (function () {
var elemInfo = {
2118,15 → 1456,22
return oNode.textContent;
};
})()
}),
});
 
/**
* Returns the first child node of another node.
*
* <p>
* NOTE: This method was written to support the MSHTML 4 DOM as well as
* newer DOMs. It is <em>NOT</em> intended to work around the issue that
* MSHTML removes white-space text nodes from the document tree, while
* standards-compliant DOMs do not. In particular, it does <em>NOT</em>
* return the first child <em>element</em> node, and return values do vary
* across DOMs.
* </p>
* @param {Node} oNode
* @return {Node} The first child node of another node.
*/
getFirstChild: function (oNode) {
jsx.dom.getFirstChild = function (oNode) {
var result = null;
 
if (oNode)
2135,37 → 1480,6
{
result = oNode.firstChild;
}
else if (oNode.children)
{
result = oNode.children[0];
}
}
 
return result;
},
 
/**
* Returns the first element child of another node.
* @param {Node} oNode
* @return {Node} The first child element of another node.
*/
getFirstElementChild: function (oNode) {
var result = null;
 
if (oNode)
{
if (oNode.firstElementChild)
{
result = oNode.firstElementChild;
}
if (oNode.firstChild)
{
result = oNode.firstChild;
while (result && result.nodeType != 1)
{
result = result.nextSibling;
}
}
else if (oNode.document && oNode.document.all)
{
result = oNode.document.all(0);
2173,7 → 1487,7
}
 
return result;
},
};
 
/**
* Returns the parent node of a node
2181,7 → 1495,7
* @param {Node} oNode
* @return {Node} The parent node of <var>oNode</var>
*/
getParent: function (oNode) {
jsx.dom.getParent = function (oNode) {
var result = null;
 
if (oNode)
2197,12 → 1511,12
}
 
return result;
},
};
 
/**
* Loads a script resource asynchonrously by appending
* a <code>script</code> element to the current (X)HTML document.
* <p>
*
* A <code>script</code> element is being created and appended as
* child to the <code>body</code> element or the <code>head</code>
* element of the document, whichever is available first. In a
2214,7 → 1528,7
* it is disabled by the frameset. In that case the
* <code>script</code> element is appended to the <code>head</code>
* element instead.
* </p><p>
*
* Note that previous versions of this method appended to the
* <code>head</code> element only. However, this limited its use
* to scripts that did not modify the body content. You may still
2223,11 → 1537,11
* <code>document.write()</code>. This method intentionally does
* not use <code>document.write()</code> to avoid the possibility
* that a loaded document could be overwritten.
* </p><p>
*
* NOTE: Tested successfully with MSIE and Mozilla/5.0; however,
* do not rely on that the script was included, but <em>test</em>
* for it.
* </p>
*
* @author
* (C) 2004-2009, 2013 Thomas Lahn <dhtml.js@PointedEars.de>,
* 2004 Ulrich Kritzner <droeppez@web.de>
2253,7 → 1567,8
* <code>false</code> if the script could not be loaded,
* <code>true</code> otherwise.
*/
loadScript: function jsx_dom_loadScript (sURI, sType, sLanguage, bReload) {
jsx.dom.loadScript =
function jsx_dom_loadScript (sURI, sType, sLanguage, bReload) {
var
jsx_object = jsx.object,
result = false;
2268,10 → 1583,10
var parent = document.body;
if (!parent || parent.tagName.toLowerCase() === "frameset")
{
parent = _getElementsByTagName("script", 0);
parent = jsx.dom.getElemByTagName("script", 0);
if (!parent)
{
parent = document.head || _getElementsByTagName("head", 0);
parent = document.head || jsx.dom.getElemByTagName("head", 0);
}
 
if (!parent)
2280,7 → 1595,7
}
}
 
if (!_isHostMethod(document, "createElement"))
if (!jsx_object.isHostMethod(document, "createElement"))
{
return false;
}
2312,7 → 1627,7
oScript.defer = true;
}
 
if (_isHostMethod(parent, "appendChild"))
if (jsx_object.isHostMethod(parent, "appendChild"))
{
parent.appendChild(oScript);
result = (
2319,7 → 1634,7
typeof parent.lastChild != "undefined"
&& parent.lastChild == oScript);
}
else if (_isHostMethod(parent, "insertAdjacentElement"))
else if (jsx_object.isHostMethod(parent, "insertAdjacentElement"))
{
parent.insertAdjacentElement("beforeEnd", oScript);
result = true;
2336,11 → 1651,98
}
 
return result;
},
};
 
getElementsByTabIndex: _getElementsByTabIndex,
/**
* Retrieves descendant focusable elements in order of their
* "tabindex" attribute.
*
* @author
* (C) 2004 Thomas Lahn <dhtml.js@PointedEars.de>
* @requires
* http://pointedears.de/scripts/collection.js
* @param {Document|Element} o (optional)
* Reference to a {@link dom2-core#Document Document} or
* {@link dom2-core#Element Element} object from which to retrieve
* descendant elements. If omitted or evaluated to
* <code>false</code>, it is tried to use the calling object.
* @return {Collection}
* A reference to a {@link #Collection} object containing
* the descendant elements of <var>o</var> or the calling
* {@link dom2-core#Document Document}/{@link dom2-core#Element Element}
* object in "tabindex" order: Elements with "tabindex" > 0 come first,
* followed by elements with "tabindex" == 0 or where either
* "tabindex" is not set or not applicable. Note: An element
* with a "tabindex" of 1 will will be the first element
* in the resulting collection but for design reasons will
* have an index of 0 (but since the Collection prototype
* provides an iterator, this does not need to disturb you).
* Additional note: Unlike specified, disabled elements will
* participate in the tabbing order (so they can be enabled
* later without this method to be re-called.)
*/
jsx.dom.getElementsByTabIndex = function (o) {
var aIndexedElements = new Array();
var aUnindexedElements = new Array();
 
isDescendantOfOrSelf: function (node, ancestor) {
/* makes the method applicable to Document and Element objects */
if (!o
&& typeof this.constructor != "undefined"
&& /Document|Element/.test(this.constructor))
{
o = this;
}
 
if (jsx.object.isMethod(o, "getElementsByTagName"))
{
var es = o.getElementsByTagName("*");
 
if (es && typeof es.length != "undefined")
{
var l = es.length;
 
for (var i = 0, e; i < l; i++)
{
e = es[i];
 
if (typeof e.tabIndex != "undefined")
{
/* !null && !0 */
if (e.tabIndex)
{
/*
* tabindex="1" --> index == 0; use e.tabIndex
* and a "zero dummy" if you do not like this
*/
aIndexedElements[e.tabIndex - 1] = e;
}
else
{
aUnindexedElements[aUnindexedElements.length] = e;
}
}
}
}
}
 
return new Collection(aIndexedElements.concat(aUnindexedElements));
};
 
if (typeof jsx.types != "undefined"
&& jsx.types.isFeature("HTMLDocument", "prototype")
&& !jsx.object.isMethod(HTMLDocument.prototype, "getElementsByTabIndex"))
{
HTMLDocument.prototype.getElementsByTabIndex = jsx.dom.getElementsByTabIndex;
}
 
if (typeof jsx.types != "undefined"
&& jsx.types.isFeature("HTMLElement", "prototype")
&& !jsx.object.isMethod(HTMLElement.prototype, "getElementsByTabIndex"))
{
HTMLElement.prototype.getElementsByTabIndex = jsx.dom.getElementsByTabIndex;
}
 
jsx.dom.isDescendantOfOrSelf = function (node, ancestor) {
if (arguments.length < 2)
{
jsx.throwThis(null, "No ancestor provided");
2356,7 → 1758,7
while ((node = node.parentNode));
 
return false;
},
};
 
/**
* Applies hyphenation to the context node.
2368,8 → 1770,9
* @function
* @requires jsx.string.hyphenation#hyphenate()
*/
hyphenate: (function () {
var _hyphenation, _hyphenate;
jsx.dom.hyphenate = (function () {
var _isArray = jsx.object.isArray;
var _hyphenation, _hyphenate, _me;
 
/**
* @param {Array} contextNodes = document
2381,7 → 1784,7
* @param {boolean} hyphenateAll
* If a true-value,
*/
return function jsx_dom_hyphenate (contextNodes, hyphenateAll) {
return function (contextNodes, hyphenateAll) {
/* imports */
if (!_hyphenate)
{
2391,7 → 1794,10
 
_hyphenation.setHyphenateAll(hyphenateAll);
 
var me = jsx_dom_hyphenate;
if (!_me)
{
_me = jsx.dom.hyphenate;
}
 
/* optional arguments */
if (typeof contextNodes == "undefined")
2429,7 → 1835,7
 
if (node.nodeType == 1)
{
me(node, hyphenateAll);
_me(node, hyphenateAll);
}
else
{
2438,33 → 1844,4
}
}
};
}())
};
 
_jsx_dom.URI = _jsx_dom.path + "dom.js";
//_jsx_dom.docURI = _jsx_dom.path + "dhtml.htm";
 
// _jsx_dom.supported = _jsx_dom.isW3CDOM || _jsx_dom.isNS4DOM || _jsx_dom.isOpera
// || _jsx_dom.isIE4DOM;
 
// _jsx_dom.DOM = _jsx_dom.supported
// && (_jsx_dom.isW3CDOM && _jsx_dom.W3CDOM)
// || (_jsx_dom.isIE4DOM && _jsx_dom.IE4DOM)
// || (_jsx_dom.isNS4DOM && _jsx_dom.NS4DOM);
 
if (typeof jsx.types != "undefined"
&& jsx.types.isFeature("HTMLDocument", "prototype")
&& !_isMethod(HTMLDocument.prototype, "getElementsByTabIndex"))
{
HTMLDocument.prototype.getElementsByTabIndex = _getElementsByTabIndex;
}
 
if (typeof jsx.types != "undefined"
&& jsx.types.isFeature("HTMLElement", "prototype")
&& !_isMethod(HTMLElement.prototype, "getElementsByTabIndex"))
{
HTMLElement.prototype.getElementsByTabIndex = _getElementsByTabIndex;
}
 
return _jsx_dom;
}());
/branches/live
Property changes:
Deleted: svn:mergeinfo
## -0,1 +0,0 ##
Reverse-merged /trunk:r509-535