97,33 → 97,34 |
var jsx = {}; |
} |
|
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"; |
/** |
* @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; |
|
if (typeof document != "undefined") |
/* Private variables */ |
var _hasDocumentAll = false; |
var _hasDocumentLayers = false; |
var _hasGetElementsByTagName = false; |
|
function _dummy() |
{ |
jsx.dom.hasDocumentAll = false; |
return null; |
} |
|
jsx.dom.getElementById = jsx.dom.getElemById = jsx.dom.getEBI = jsx.dom.gEBI = ( |
function () { |
var _getElementById = (function () { |
if (typeof document == "undefined") |
{ |
return function () { |
return null; |
}; |
return _dummy; |
} |
|
var jsx_object = jsx.object; |
|
if (jsx_object.isMethod(document, "getElementById")) |
if (_isMethod(document, "getElementById")) |
{ |
/** |
* @param {string} sId |
140,7 → 141,7 |
}; |
} |
|
if ((jsx.dom.hasDocumentAll = jsx_object.isMethod(document, "all"))) |
if ((_hasDocumentAll = _isMethod(document, "all"))) |
{ |
return function (sId) { |
return document.all(sId); |
150,24 → 151,15 |
return function (sId) { |
return document[sId]; |
}; |
} |
)(); |
}()); |
|
jsx.dom.hasDocumentLayers = false; |
|
jsx.dom.getElementsByName = jsx.dom.getElemByName = jsx.dom.gEBN = ( |
function () { |
function dummy() |
{ |
return null; |
} |
|
var _getElementsByName = (function () { |
if (typeof document == "undefined") |
{ |
return dummy; |
return _dummy; |
} |
|
if (jsx.object.isMethod(document, "getElementsByName")) |
if (_isMethod(document, "getElementsByName")) |
{ |
/* W3C DOM Level 2 HTML */ |
/** |
185,7 → 177,7 |
return result; |
}; |
} |
else if (jsx.dom.hasDocumentAll) |
else if (_hasDocumentAll) |
{ |
/* IE4 DOM */ |
return function (sName, index) { |
198,7 → 190,7 |
return result; |
}; |
} |
else if ((jsx.dom.hasDocumentLayers = (typeof document.layers == "object"))) |
else if ((_hasDocumentLayers = (typeof document.layers == "object"))) |
{ |
/* NN4 DOM */ |
return function (sName, index) { |
212,17 → 204,11 |
}; |
} |
|
return dummy; |
}() |
); |
return _dummy; |
}()); |
|
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")) |
var _getElementsByTagName = (function () { |
if (_jsx_object.isNativeMethod(jsx, "xpath", "evaluate")) |
{ |
/* W3C DOM Level 3 XPath */ |
/** |
262,9 → 248,9 |
}; |
} |
|
if ((jsx.dom.hasGetElementsByTagName = |
if ((_hasGetElementsByTagName = |
(typeof document != "undefined" |
&& jsx_object.isMethod(document, "getElementsByTagName")))) |
&& _isMethod(document, "getElementsByTagName")))) |
{ |
/* W3C DOM Level 2 Core */ |
/** |
295,7 → 281,7 |
oContextNode = document; |
} |
|
if (!jsx_object.isMethod(oContextNode, "getElementsByTagName")) |
if (!_isMethod(oContextNode, "getElementsByTagName")) |
{ |
return null; |
} |
310,7 → 296,7 |
}; |
} |
|
if (jsx.dom.hasDocumentAll && isMethod(document.all, "tags")) |
if (_hasDocumentAll && isMethod(document.all, "tags")) |
{ |
/** |
* @param {string} sTagName |
335,7 → 321,7 |
oContextNode = document; |
} |
|
if (!jsx.object.isMethod(oContextNode, "all", "tags")) |
if (!_isMethod(oContextNode, "all", "tags")) |
{ |
return null; |
} |
353,21 → 339,15 |
return function () { |
return null; |
}; |
}() |
); |
}()); |
|
jsx.dom.getElementByIndex = jsx.dom.getElemByIndex = jsx.dom.gEBIdx = (function () { |
function dummy() |
{ |
return null; |
} |
|
var _getElementByIndex = (function () { |
if (typeof document == "undefined") |
{ |
return dummy; |
return _dummy; |
} |
|
if (jsx.dom.hasGetElementsByTagName) |
if (_hasGetElementsByTagName) |
{ |
/** |
* @param {number} index |
378,7 → 358,7 |
}; |
} |
|
if (jsx.dom.hasDocumentAll) |
if (_hasDocumentAll) |
{ |
/** |
* @param {number} index |
389,7 → 369,7 |
}; |
} |
|
if (jsx.dom.hasDocumentLayers) |
if (_hasDocumentLayers) |
{ |
/** |
* @param {number} index |
400,56 → 380,654 |
}; |
} |
|
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]; |
} |
|
/* |
* Apart from isNS4DOM, none of these object-inference properties is used |
* anymore; they are still here for backwards compatibility only |
var strToValue = |
/** |
* Converts a string, if possible, to a number |
* |
* @param {string} s |
* @return {string|number} |
* The converted value |
*/ |
//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; |
function (s) { |
s = s.replace(/^["']|["']$/g, ""); |
return isNaN(s) ? s : +s; |
}; |
|
/* 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); |
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(); |
|
/* allows for de.pointedears.jsx.dom */ |
if (typeof de == "undefined") |
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; |
} |
|
/** |
* @namespace |
* 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 |
*/ |
var de = {}; |
function _createNodesFromObj (data) |
{ |
if (typeof data.valueOf() == "string") |
{ |
return document.createTextNode(data); |
} |
|
if (typeof de.pointedears == "undefined") |
/* Support ES5 strict mode */ |
var me = _createNodesFromObj; |
|
/* If input is an Array, output is an Array of Nodes */ |
if (_isArray(data)) |
{ |
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; |
} |
|
/** |
* @namespace |
* 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. |
*/ |
de.pointedears = {}; |
function _hasClassName (o, sClassName) |
{ |
if (sClassName) |
{ |
if (_isHostMethod(o, "classList", "contains")) |
{ |
/* W3C DOM Level 4 */ |
return o.classList.contains(sClassName); |
} |
|
if (typeof de.pointedears.jsx == "undefined") |
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 (_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); |
} |
|
/** |
* @namespace |
* 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. |
*/ |
de.pointedears.jsx = jsx; |
function _appendChild (parentNode, childNode) |
{ |
if (parentNode) |
{ |
if (_isMethod(parentNode, "appendChild")) |
{ |
parentNode.appendChild(childNode); |
return true; |
} |
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. |
* |
457,8 → 1035,9 |
* Error message to be displayed. |
* @return {boolean} |
* Always <code>false</code> |
* @deprecated |
*/ |
jsx.dom.DHTMLException = function (sMessage) { |
DHTMLException: function (sMessage) { |
/* Prevent exceptions from "bubbling" on (keyboard) event */ |
if (!jsx.dom.allowExceptionMsg) |
{ |
469,7 → 1048,7 |
|
jsx.setErrorHandler(); |
var stackTrace = |
jsx.object.isMethod(_global, "Error") && (new Error()).stack || ""; |
_isMethod(_global, "Error") && (new Error()).stack || ""; |
|
jsx.clearErrorHandler(); |
|
489,9 → 1068,9 |
|
jsx.dom.allowExceptionMsg = true; |
return false; |
}; |
}, |
|
jsx.dom.write = function (s) { |
write: function (s) { |
var result = jsx.tryThis( |
function () { |
document.write(s); |
516,7 → 1095,7 |
if (scripts && scripts.length > 0) |
{ |
var lastScript = scripts[scripts.length - 1]; |
result2 = !!lastScript.parentNode.insertBefore( |
result2 = !!_insertBefore(lastScript.parentNode, |
document.createTextNode(s), lastScript.nextSibling); |
} |
|
524,11 → 1103,8 |
}); |
}); |
|
/* fix circular reference */ |
s = null; |
|
return result; |
}; |
}, |
|
/** |
* Retrieves an HTMLElement object or a collection of such |
553,7 → 1129,7 |
* specified criteria; <code>null</code> if no matching object |
* exists. |
*/ |
jsx.dom.getElem = function (sType, sValue, index) { |
getElem: function (sType, sValue, index) { |
/** |
* Calls DHTMLException() for an invalid type. |
*/ |
606,7 → 1182,7 |
} |
|
return o; |
}; |
}, |
|
/** |
* Retrieves the content of an HTMLElement object. |
622,7 → 1198,7 |
* no such element object exists or if the DOM does not provide |
* retrieval of the element's content. |
*/ |
jsx.dom.getCont = function (oElement, bHTML) { |
getCont: function (oElement, bHTML) { |
var sResult = ""; |
|
if (oElement) |
656,7 → 1232,7 |
} |
|
return sResult; |
}; |
}, |
|
/** |
* Specifies the content of an HTMLElement object. |
670,7 → 1246,7 |
* <code>true</code> if successful, <code>false</code> |
* otherwise. |
*/ |
jsx.dom.setCont = function (oElement, sNodeValue) { |
setCont: function (oElement, sNodeValue) { |
if (oElement) |
{ |
/* DOM Level 2 Core */ |
707,7 → 1283,7 |
} |
|
return false; |
}; |
}, |
|
/** |
* Returns the text content of a document node. |
723,7 → 1299,7 |
* The text content of @{(oNode)}. |
* @todo Duplicate of getCont(..., false)? |
*/ |
jsx.dom.getContent = function (oNode, bGetHTML) { |
getContent: function (oNode, bGetHTML) { |
var text = ""; |
|
if (oNode) |
760,7 → 1336,7 |
} |
|
return text; |
}; |
}, |
|
/** |
* Sets the text content of a document node. |
771,9 → 1347,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. |
*/ |
jsx.dom.setTextContent = function (oNode, sContent) { |
setTextContent: function (oNode, sContent) { |
var result = false; |
|
if (oNode) |
805,7 → 1381,7 |
} |
|
return result; |
}; |
}, |
|
/** |
* Retrieves the value of an attribute of an HTMLElement object |
824,12 → 1400,12 |
* a null-string if no matching object exists or if the DOM |
* does not provide retrieval of the attribute's values. |
*/ |
jsx.dom.getAttr = function (oElement, sAttrName) { |
getAttr: function (oElement, sAttrName) { |
var result = ""; |
|
if (oElement) |
{ |
if (jsx.object.isMethod(oElement, "getAttribute")) |
if (_isMethod(oElement, "getAttribute")) |
{ |
result = oElement.getAttribute(sAttrName); |
} |
840,129 → 1416,13 |
} |
|
return result; |
}; |
}, |
|
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" |
}; |
attrMap: _attrMap, |
|
setAttr: _setAttr, |
|
/** |
* 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. |
*/ |
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, |
969,16 → 1429,6 |
* it is tried to use the start tag as is instead of passing |
* only the element type, and adding properties later. |
* |
* @function |
* @author |
* © 2004, 2006, 2010 Thomas Lahn <dhtml.js@PointedEars.de> |
* @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, |
990,14 → 1440,28 |
* and the <code>localName</code>, <code>prefix</code>, |
* and <code>namespaceURI</code> properties set to |
* <code>null</code>. |
* @author |
* © 2004, 2006, 2010 Thomas Lahn <dhtml.js@PointedEars.de> |
* @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> |
*/ |
return function (sTag) { |
createElement: function (sTag, sNamespaceURI) { |
var o = null; |
|
if (sTag |
&& typeof document != "undefined" |
&& jsx.object.isMethod(document, "createElement")) |
if (sTag && typeof document != "undefined") |
{ |
/* 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); |
1005,10 → 1469,10 |
|
if (!o) |
{ |
/* 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]); |
o = document.createElement(local_name); |
} |
} |
|
if (o) |
{ |
aTagComponents.shift(); |
1020,17 → 1484,15 |
} |
} |
} |
} |
|
return o; |
}; |
}()); |
}, |
|
/** |
* Creates a node or several nodes from an object. |
* Creates a SGML/HTML markup 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: |
* Returns a {@link string} from the argument, depending on |
* its type: |
* <table> |
* <thead> |
* <tr> |
1041,17 → 1503,34 |
* <tbody> |
* <tr> |
* <th>{@link String}</th> |
* <td>{@link Text}</td> |
* <td><code>string</code> with characters |
* escaped according to the following table: |
* <table> |
* <tr> |
* <th>Character</th> |
* <th>Escape</th> |
* </tr> |
* <tr><td><code>"</code></td><td><code>&quot;</code></td></tr> |
* <tr><td><code>&</code></td><td><code>&amp;</code></td></tr> |
* <tr><td><code><</code></td><td><code>&lt;</code></td></tr> |
* <tr><td><code>></code></td><td><code>&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><code>Array</code> of <code>Node</code>. The input |
* <code>Array</code>'s elements are processed recursively.</td> |
* <td>Markup s<code>string</code> of elements and text. |
* 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: |
* <td>Markup <code>string</code> for one element and, |
* optionally, its content. The following of |
* the input <code>Object</code>'s properties |
* are considered: |
* <table> |
* <thead> |
* <th>Property</th> |
1098,28 → 1577,30 |
* </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 |
* @return TextNode|Array[Node]|Element |
* @param {boolean} bXML |
* If a true-value, empty elements use XML <code>SHORTTAG</code> |
* syntax: <code><foo/></code> instead of |
* <code><foo></foo></code>. |
* @return {string} |
*/ |
return function (data) { |
createMarkupFromObj: function _createMarkupFromObj (data, bXML) { |
if (typeof data.valueOf() == "string") |
{ |
return document.createTextNode(data); |
return data.replace(/["&<>]/g, function (m) { |
return ({ |
'"': """, |
"&": "&", |
"<": "<", |
">": ">" |
})[m]; |
}); |
} |
|
/* Support ES5 strict mode */ |
var me = jsx.dom.createNodeFromObj; |
var me = _createMarkupFromObj; |
|
/* If input is an Array, output is an Array of Nodes */ |
/* If input is an Array, output is string of markup */ |
if (_isArray(data)) |
{ |
var a = []; |
1129,27 → 1610,24 |
a[i] = me(data[i]); |
} |
|
return a; |
return a.join(""); |
} |
|
var el = document.createElement(data.elementType || data.type); |
if (!el) |
var type = (data.elementType || data.type); |
var el = ["<" + type]; |
|
var attributes = data.attributes; |
if (attributes) |
{ |
return null; |
var keys = _getKeys(attributes); |
|
for (var i = 0, len = keys.length; i < len; ++i) |
{ |
var attrName = keys[i]; |
el.push(" " + attrName + '="' + me(attributes[attrName]) + '"'); |
} |
} |
|
// 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) |
{ |
1161,81 → 1639,55 |
|
if (propName == "style") |
{ |
el.push(' 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 _uncamelize = jsx.object.getFeature(jsx.dom, "css", "uncamelize") |
|| function (s) { return s; }; |
|
var styleKeys = _getKeys(style); |
for (var i = 0, len = styleKeys.length; i < len; ++i) |
{ |
var stylePropName = styleKeys[i]; |
_setStyleProperty(el, stylePropName, style[stylePropName]); |
el.push(" " + me(_uncamelize(stylePropName)) + ": " + me(style[stylePropName])); |
} |
} |
} |
else |
{ |
el[propName] = properties[propName]; |
el.push(" " + propName + '="' + me(properties[propName]) + '"'); |
} |
} |
} |
|
var nodes = data.childNodes; |
for (var i = 0, len = nodes && nodes.length; i < len; ++i) |
var bEmpty = (!nodes || !nodes.length); |
if (bXML && bEmpty) |
{ |
el.appendChild(me(nodes[i])); |
el.push("/"); |
} |
|
return el; |
}; |
}()); |
el.push(">"); |
|
/** |
* 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")) |
for (var i = 0, len = nodes && nodes.length; i < len; ++i) |
{ |
/* W3C DOM Level 4 */ |
o.classList.remove(sClassName); |
el.push(me(nodes[i], bXML)); |
} |
else |
{ |
var curClassNames = o.className; |
var newClassNames = curClassNames.replace( |
new RegExp(sRxClassName, "g"), |
"$3"); |
o.className = newClassNames; |
|
if (!newClassNames && jsx.object.isMethod(o, "removeAttribute")) |
if (!bEmpty) |
{ |
o.removeAttribute("class"); |
el.push("</" + type + ">"); |
} |
} |
|
return !((new RegExp(sRxClassName)).test(o.className)); |
}; |
return el.join(""); |
}, |
|
jsx.dom.addClassName = (function () { |
var _removeClassName = jsx.dom.removeClassName; |
createElementFromObj: _createNodesFromObj, |
createNodeFromObj: _createNodesFromObj, |
createNodesFromObj: _createNodesFromObj, |
|
hasClassName: _hasClassName, |
removeClassName: _removeClassName, |
|
/** |
* Adds a class name to the <code>class</code> attribute of |
* an {@link Element}. |
1252,15 → 1704,12 |
* <code>true</code> if the class name could be added successfully or |
* was already there, <code>false</code> otherwise. |
*/ |
function _addClassName (o, sClassName, bRemove) |
{ |
var rx = new RegExp("(^\\s*|\\s+)" + sClassName + "(\\s*$|\\s)"); |
|
addClassName: function (o, sClassName, bRemove) { |
if (bRemove) |
{ |
_removeClassName(o, sClassName); |
} |
else if (rx.test(o.className)) |
else if (_hasClassName(o, sClassName)) |
{ |
return true; |
} |
1267,7 → 1716,7 |
|
if (sClassName) |
{ |
if (jsx.object.isHostMethod(o, "classList", "add")) |
if (_isHostMethod(o, "classList", "add")) |
{ |
/* W3C DOM Level 4 */ |
o.classList.add(sClassName); |
1284,12 → 1733,11 |
} |
} |
|
return rx.test(o.className); |
return _hasClassName(o, sClassName); |
} |
} |
}, |
|
return _addClassName; |
}()); |
appendChild: _appendChild, |
|
/** |
* Appends several child nodes to a parent node in the specified order. |
1299,21 → 1747,40 |
* @return {boolean} |
* <code>true</code> on success, <code>false</code> otherwise. |
*/ |
jsx.dom.appendChildren = function (parentNode, childNodes) { |
appendChildren: function (parentNode, childNodes) { |
if (parentNode) |
{ |
var result = true; |
|
for (var i = 0, len = childNodes.length; i < len; ++i) |
{ |
parentNode.appendChild(childNodes[i]); |
var success = _appendChild(parentNode, childNodes[i]); |
if (!success && result) |
{ |
result = false; |
} |
} |
|
return true; |
return result; |
} |
|
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 |
1325,9 → 1792,10 |
* @return {boolean} |
* <code>true</code> on success, <code>false</code> otherwise. |
*/ |
jsx.dom.removeChildren = function (parentNode, childNodes) { |
removeChildren: function (parentNode, childNodes) { |
if (parentNode) |
{ |
var result = true; |
if (arguments.length < 2) |
{ |
childNodes = parentNode.childNodes; |
1335,16 → 1803,20 |
|
for (var i = childNodes.length; i--;) |
{ |
parentNode.removeChild(childNodes[i]); |
var success = _removeChild(parentNode, childNodes[i]); |
if (!success && result) |
{ |
result = false; |
} |
} |
|
return true; |
return result; |
} |
|
return false; |
}; |
}, |
|
jsx.dom.html2nodes = function (sHTML) { |
html2nodes: function (sHTML) { |
var m, |
rx = /(<([^\s>]+)(\s+[^>]*)?>)|([^<]+)/g, |
node = document.createElement("html"); |
1371,12 → 1843,202 |
} |
|
return node; |
}; |
}, |
|
jsx.dom.HTMLSerializer = ( |
function () { |
InvalidNodeError: _InvalidNodeError, |
|
/** |
* 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 = { |
1456,22 → 2118,15 |
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. |
*/ |
jsx.dom.getFirstChild = function (oNode) { |
getFirstChild: function (oNode) { |
var result = null; |
|
if (oNode) |
1480,6 → 2135,37 |
{ |
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); |
1487,7 → 2173,7 |
} |
|
return result; |
}; |
}, |
|
/** |
* Returns the parent node of a node |
1495,7 → 2181,7 |
* @param {Node} oNode |
* @return {Node} The parent node of <var>oNode</var> |
*/ |
jsx.dom.getParent = function (oNode) { |
getParent: function (oNode) { |
var result = null; |
|
if (oNode) |
1511,12 → 2197,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 |
1528,7 → 2214,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 |
1537,11 → 2223,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> |
1567,8 → 2253,7 |
* <code>false</code> if the script could not be loaded, |
* <code>true</code> otherwise. |
*/ |
jsx.dom.loadScript = |
function jsx_dom_loadScript (sURI, sType, sLanguage, bReload) { |
loadScript: function jsx_dom_loadScript (sURI, sType, sLanguage, bReload) { |
var |
jsx_object = jsx.object, |
result = false; |
1583,10 → 2268,10 |
var parent = document.body; |
if (!parent || parent.tagName.toLowerCase() === "frameset") |
{ |
parent = jsx.dom.getElemByTagName("script", 0); |
parent = _getElementsByTagName("script", 0); |
if (!parent) |
{ |
parent = document.head || jsx.dom.getElemByTagName("head", 0); |
parent = document.head || _getElementsByTagName("head", 0); |
} |
|
if (!parent) |
1595,7 → 2280,7 |
} |
} |
|
if (!jsx_object.isHostMethod(document, "createElement")) |
if (!_isHostMethod(document, "createElement")) |
{ |
return false; |
} |
1627,7 → 2312,7 |
oScript.defer = true; |
} |
|
if (jsx_object.isHostMethod(parent, "appendChild")) |
if (_isHostMethod(parent, "appendChild")) |
{ |
parent.appendChild(oScript); |
result = ( |
1634,7 → 2319,7 |
typeof parent.lastChild != "undefined" |
&& parent.lastChild == oScript); |
} |
else if (jsx_object.isHostMethod(parent, "insertAdjacentElement")) |
else if (_isHostMethod(parent, "insertAdjacentElement")) |
{ |
parent.insertAdjacentElement("beforeEnd", oScript); |
result = true; |
1651,98 → 2336,11 |
} |
|
return result; |
}; |
}, |
|
/** |
* 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(); |
getElementsByTabIndex: _getElementsByTabIndex, |
|
/* 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) { |
isDescendantOfOrSelf: function (node, ancestor) { |
if (arguments.length < 2) |
{ |
jsx.throwThis(null, "No ancestor provided"); |
1758,7 → 2356,7 |
while ((node = node.parentNode)); |
|
return false; |
}; |
}, |
|
/** |
* Applies hyphenation to the context node. |
1770,9 → 2368,8 |
* @function |
* @requires jsx.string.hyphenation#hyphenate() |
*/ |
jsx.dom.hyphenate = (function () { |
var _isArray = jsx.object.isArray; |
var _hyphenation, _hyphenate, _me; |
hyphenate: (function () { |
var _hyphenation, _hyphenate; |
|
/** |
* @param {Array} contextNodes = document |
1784,7 → 2381,7 |
* @param {boolean} hyphenateAll |
* If a true-value, |
*/ |
return function (contextNodes, hyphenateAll) { |
return function jsx_dom_hyphenate (contextNodes, hyphenateAll) { |
/* imports */ |
if (!_hyphenate) |
{ |
1794,10 → 2391,7 |
|
_hyphenation.setHyphenateAll(hyphenateAll); |
|
if (!_me) |
{ |
_me = jsx.dom.hyphenate; |
} |
var me = jsx_dom_hyphenate; |
|
/* optional arguments */ |
if (typeof contextNodes == "undefined") |
1835,7 → 2429,7 |
|
if (node.nodeType == 1) |
{ |
_me(node, hyphenateAll); |
me(node, hyphenateAll); |
} |
else |
{ |
1844,4 → 2438,33 |
} |
} |
}; |
}()) |
}; |
|
_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; |
}()); |