dom-debug.js revision d913de804d806a22bae4363ccbdac36dd6403399
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers * The DOM utility provides a cross-browser abtraction layer
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers * normalizing DOM tasks, and adds extra helper functionality
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers * for other common tasks.
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers * @module dom
afe3ab588a6b2992efe5a9b22ed038545ba3cdbfLennart Poettering * @submodule dom-base
d19e85f0d474ed1882561b458d528cbae49f640eZbigniew Jędrzejewski-Szmek * Provides DOM helper methods.
3f85ef0f05ffc51e19f86fb83a1c51e8e3cd6817Harald Hoyer * @class DOM
3e495a6651609d0a45b62aab5c3ed5a3b40e11abZbigniew Jędrzejewski-Szmek OWNER_DOCUMENT = 'ownerDocument',
58f55364fa00a6a4706df2c4a01c6967f432e531Lennart Poettering COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
83a1ff25e5228b0a5b2cc942fd4f964d10bb73b0Zbigniew Jędrzejewski-Szmek documentElement = document.documentElement,
5ad65d628facbce5219ac2749bc835ab92ca6c39Lennart Poettering * Returns the HTMLElement with the given ID (Wrapper for document.getElementById).
5ad65d628facbce5219ac2749bc835ab92ca6c39Lennart Poettering * @method byId
f93b36affa5ac5710cd84bfb8ff0dafabe99fbf1Lennart Poettering * @param {String} id the id attribute
f93b36affa5ac5710cd84bfb8ff0dafabe99fbf1Lennart Poettering * @param {Object} doc optional The document to search. Defaults to current document
20760dcf5df7e253c21a51886cdb02dee612730bLennart Poettering * @return {HTMLElement | null} The HTMLElement with the id, or null if none found.
20760dcf5df7e253c21a51886cdb02dee612730bLennart Poettering // TODO: IE Name
df22b0bbfde403b3fa71f3c2f1e2ca38af946388Lennart Poettering // @deprecated
df22b0bbfde403b3fa71f3c2f1e2ca38af946388Lennart Poettering ret = Y.Selector.query('> ' + tag, node);
b9be39bfb4ed8e43a7c445831131e44be998eb32Lennart Poettering // @deprecated
b9be39bfb4ed8e43a7c445831131e44be998eb32Lennart Poettering return ret || null;
c05482281c32bd408808b14c5fb03e706e65602dLennart Poettering * Returns the text content of the HTMLElement.
c05482281c32bd408808b14c5fb03e706e65602dLennart Poettering * @method getText
2aeed6760e9759d95418bdb2e80d0032ffcb768eLennart Poettering * @param {HTMLElement} element The html element.
2aeed6760e9759d95418bdb2e80d0032ffcb768eLennart Poettering * @return {String} The text content of the element (includes text of any descending elements).
2aeed6760e9759d95418bdb2e80d0032ffcb768eLennart Poettering getText: (documentElement.textContent !== undefined) ?
73cb77549536deab85d8d1261b5381e87d80ab23Lennart Poettering } : function(element) {
477e75ef9ea6bb2e7e8cc76278c442942110f227Lennart Poettering * Sets the text content of the HTMLElement.
477e75ef9ea6bb2e7e8cc76278c442942110f227Lennart Poettering * @method setText
477e75ef9ea6bb2e7e8cc76278c442942110f227Lennart Poettering * @param {HTMLElement} element The html element.
477e75ef9ea6bb2e7e8cc76278c442942110f227Lennart Poettering * @param {String} content The content to add.
7dfb0404b3b6882d582a571f61a52b2f56961675Lennart Poettering setText: (documentElement.textContent !== undefined) ?
687f6a0ba77872299b9fb1f2f04d31c977088a63Lennart Poettering * Finds the previous sibling of the element.
2bc39683c0cada86c9dc39e5f3d0ea475cf12e57Lennart Poettering * @method previous
2bc39683c0cada86c9dc39e5f3d0ea475cf12e57Lennart Poettering * @deprecated Use elementByAxis
687f6a0ba77872299b9fb1f2f04d31c977088a63Lennart Poettering * @param {HTMLElement} element The html element.
31a11e8f30449a81867e8fd081e3e76cf6664bb4Lennart Poettering * @param {Function} fn optional An optional boolean test to apply.
31a11e8f30449a81867e8fd081e3e76cf6664bb4Lennart Poettering * The optional function is passed the current DOM node being tested as its only argument.
dbdee28bfadd6d8bd93cb34c85ce1fc325dd8120Lennart Poettering * If no function is given, the first sibling is returned.
dbdee28bfadd6d8bd93cb34c85ce1fc325dd8120Lennart Poettering * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
17fe56148c44dfa5583a8643c1918fd6eccf2aeeLennart Poettering * @return {HTMLElement | null} The matching DOM node or null if none found.
17fe56148c44dfa5583a8643c1918fd6eccf2aeeLennart Poettering return Y.DOM.elementByAxis(element, PREVIOUS_SIBLING, fn, all);
7687f85ea6bab434324bb985e2898bf6373891bfLennart Poettering * Finds the next sibling of the element.
02c74033ed65e7825d1b87ee051820c9fbfa0f50Lennart Poettering * @method next
02c74033ed65e7825d1b87ee051820c9fbfa0f50Lennart Poettering * @deprecated Use elementByAxis
c14db9b32ab90738973071d31f259d1a457d7b4aLennart Poettering * @param {HTMLElement} element The html element.
c14db9b32ab90738973071d31f259d1a457d7b4aLennart Poettering * @param {Function} fn optional An optional boolean test to apply.
fa607802f332e06f4044c3eb38dbea41076c803dLennart Poettering * The optional function is passed the current DOM node being tested as its only argument.
fa607802f332e06f4044c3eb38dbea41076c803dLennart Poettering * If no function is given, the first sibling is returned.
cc98b3025eeb89addb76a27390cb2baca4eab8b9Torstein Husebø * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
a47e6701bfc45519a4e038daa52e9236e932f59aLennart Poettering * @return {HTMLElement | null} The matching DOM node or null if none found.
92ff080be100aff15f292e2631921131c610afe7Lennart Poettering return Y.DOM.elementByAxis(element, NEXT_SIBLING, fn, all);
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering * Finds the ancestor of the element.
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering * @method ancestor
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering * @deprecated Use elementByAxis
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering * @param {HTMLElement} element The html element.
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering * @param {Function} fn optional An optional boolean test to apply.
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering * The optional function is passed the current DOM node being tested as its only argument.
de146bb2aac13361ade3050d37696499ac4ca9aeLennart Poettering * If no function is given, the parentNode is returned.
de146bb2aac13361ade3050d37696499ac4ca9aeLennart Poettering * @param {Boolean} testSelf optional Whether or not to include the element in the scan
358ba19e5e18304258f053e30e6120a3b6adf322Lennart Poettering * @return {HTMLElement | null} The matching DOM node or null if none found.
91f4347ef7bde17418b365ed3a97a752fe65bd50Lennart Poettering ancestor: function(element, fn, testSelf) {
de146bb2aac13361ade3050d37696499ac4ca9aeLennart Poettering ret = (!fn || fn(element)) ? element : null;
c3a0d00d6dd6f5997d673e133ef6f9f856550b0aLennart Poettering return ret || Y.DOM.elementByAxis(element, PARENT_NODE, fn, null);
d2f81fb00cc3c49e21b31000ba7d37b81a260257Lennart Poettering * Searches the element by the given axis for the first matching element.
d2f81fb00cc3c49e21b31000ba7d37b81a260257Lennart Poettering * @method elementByAxis
98cd2651988619bf606f0b27825440c4638a7e0bLennart Poettering * @param {HTMLElement} element The html element.
b7307642391c8ebb9724c99e6b33239e2c0ff944Lennart Poettering * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling).
b7307642391c8ebb9724c99e6b33239e2c0ff944Lennart Poettering * @param {Function} fn optional An optional boolean test to apply.
2a441c8afe7c81f74cc2ceccdf9a71301cd39d4dLennart Poettering * @param {Boolean} all optional Whether all node types should be returned, or just element nodes.
2a441c8afe7c81f74cc2ceccdf9a71301cd39d4dLennart Poettering * The optional function is passed the current HTMLElement being tested as its only argument.
2a441c8afe7c81f74cc2ceccdf9a71301cd39d4dLennart Poettering * If no function is given, the first element is returned.
2a441c8afe7c81f74cc2ceccdf9a71301cd39d4dLennart Poettering * @return {HTMLElement | null} The matching element or null if none found.
40ff4a4abd76d71408e598ed02d7860b8465fa9aLennart Poettering elementByAxis: function(element, axis, fn, all) {
40ff4a4abd76d71408e598ed02d7860b8465fa9aLennart Poettering while (element && (element = element[axis])) { // NOTE: assignment
40ff4a4abd76d71408e598ed02d7860b8465fa9aLennart Poettering if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) {
f131770b1465fbf423881f16ba85523a05f846feVeres Lajos return null;
0a86c1a9d8066267b878dfeddc5e0087dda6a37bLennart Poettering * Determines whether or not one HTMLElement is or contains another HTMLElement.
0a86c1a9d8066267b878dfeddc5e0087dda6a37bLennart Poettering * @method contains
0a86c1a9d8066267b878dfeddc5e0087dda6a37bLennart Poettering * @param {HTMLElement} element The containing html element.
0a86c1a9d8066267b878dfeddc5e0087dda6a37bLennart Poettering * @param {HTMLElement} needle The html element that may be contained.
0a86c1a9d8066267b878dfeddc5e0087dda6a37bLennart Poettering * @return {Boolean} Whether or not the element is or contains the needle.
e3286870fdf20c3c93e944b24fd9af53620f7dbaLennart Poettering if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) {
e3286870fdf20c3c93e944b24fd9af53620f7dbaLennart Poettering if (Y.UA.opera || needle[NODE_TYPE] === 1) { // IE & SAF contains fail if needle not an ELEMENT_NODE
a195cbad3796dfda3d1016e4819c612c859e3c7bLennart Poettering ret = Y.DOM._bruteContains(element, needle);
8514b67754c5ff7fa628929b3d27131010c21842Lennart Poettering } else if (element[COMPARE_DOCUMENT_POSITION]) { // gecko
6c78f43c7b0e54e695af49917fda79b584f46830Lennart Poettering if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) {
264b8070715d2d19344c4991ace21147d998f56dLennart Poettering * Determines whether or not the HTMLElement is part of the document.
264b8070715d2d19344c4991ace21147d998f56dLennart Poettering * @method inDoc
7e27f3121e5a10629302b5221eb21345f832724aLennart Poettering * @param {HTMLElement} element The containing html element.
7e27f3121e5a10629302b5221eb21345f832724aLennart Poettering * @param {HTMLElement} doc optional The document to check.
f81e67f79fa856aa2ecffad4d014772ce981745cLennart Poettering * @return {Boolean} Whether or not the element is attached to the document.
d48b7bd271b1e70924c8485d2f95c2f5a1ae77cbLennart Poettering // there may be multiple elements with the same ID
8483d73ff158ee0d51ccbba09a470cc6ae9b071aLennart Poettering for (i = 0; node = nodes[i++];) { // check for a match
b42de08aa4c97636e42c28c7bce08f0d7c2a719aZbigniew Jędrzejewski-Szmek ret = root.querySelectorAll('[id="' + id + '"]');
42aeb14a4a0fa7d43da96a8ed0fb0e180a2dd5c8Lennart Poettering if (nodes && nodes.nodeType) { // root.all may return one or many
14a32924c9b46817c92ae11c1147a59dcb62012bLennart Poettering for (i = 0; node = nodes[i++];) { // check for a match
14a32924c9b46817c92ae11c1147a59dcb62012bLennart Poettering if (node.id === id) { // avoid false positive for node.name
d61bb44a89fde3042c7c15ea4975239f7dcb0cb0Lennart Poettering * Creates a new dom node using the provided markup string.
ed220efd6657822332b9563ec53c5ab9f3c33220Lennart Poettering * @method create
ed220efd6657822332b9563ec53c5ab9f3c33220Lennart Poettering * @param {String} html The markup used to create the element
41488fe9024a8955d19811620fd55dcc56a5b2baLennart Poettering * @param {HTMLDocument} doc An optional document context
41488fe9024a8955d19811620fd55dcc56a5b2baLennart Poettering html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
ff3d6560bead6879a2fed1bf99bfe8273b3723f1Zbigniew Jędrzejewski-Szmek nodes = create(html, doc, tag).childNodes;
23c4091dc2b85d117512e89233fdeb47d1ff3d92Lennart Poettering if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
23c4091dc2b85d117512e89233fdeb47d1ff3d92Lennart Poettering ret = nodes[0].parentNode.removeChild(nodes[0]);
9d6db739ce1eaa3eace21801fd606d523b73c8f4Lennart Poettering } else { // return multiple nodes as a fragment
2834ffe78d7fd8be118429aa1449ac72641638c2Lennart Poettering if (nodes && (nodes.push || nodes.item) && nodes[0]) {
a01647e53727107d82382bc5c9d98c894e8f386cLennart Poettering if (nodes.item) { // convert live list to static array
3de03738fc970496d2d3da668c72767a48ccc41bLennart Poettering for (i = 0, len = nodes.length; i < len; i++) {
2b1c3767515672dfd0f5e0a9c9d7ac3a16a6a361Lennart Poettering } // else inline with log for minification
37efac5ddb21fd91ed420c070ed07f375e78b3b9Lennart Poettering else { Y.log('unable to convert ' + nodes + ' to fragment', 'warn', 'dom'); }
e107ed185ef08945102834234a05ec51bb438685Lennart Poettering CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
edb2935c5c5b95c42b8679086f60da5eafad74cbLennart Poettering * Provides a normalized attribute interface.
769918ecd30c0f7ee6e87b9aa6226d956bd2f530Lennart Poettering * @method setAttibute
769918ecd30c0f7ee6e87b9aa6226d956bd2f530Lennart Poettering * @param {String | HTMLElement} el The target element for the attribute.
769918ecd30c0f7ee6e87b9aa6226d956bd2f530Lennart Poettering * @param {String} attr The attribute to set.
769918ecd30c0f7ee6e87b9aa6226d956bd2f530Lennart Poettering * @param {String} val The value of the attribute.
2a781fc9bd33982c81e5ff75974a442a33d4f167Lennart Poettering setAttribute: function(el, attr, val, ieAttr) {
6a3f892a23db71544d0439355f96c44350dafa8fLennart Poettering attr = Y.DOM.CUSTOM_ATTRIBUTES[attr] || attr;
eda8f06755bd98c4639293c26b856c225f0d1fe1Lennart Poettering * Provides a normalized attribute interface.
d4fdc205a4610965cee46408dbd046c922e7620cLennart Poettering * @method getAttibute
d4fdc205a4610965cee46408dbd046c922e7620cLennart Poettering * @param {String | HTMLElement} el The target element for the attribute.
d4fdc205a4610965cee46408dbd046c922e7620cLennart Poettering * @param {String} attr The attribute to get.
af1082b04a3d45a9b1d796b4271f44e87e307026Lennart Poettering * @return {String} The current value of the attribute.
af1082b04a3d45a9b1d796b4271f44e87e307026Lennart Poettering getAttribute: function(el, attr, ieAttr) {
af1082b04a3d45a9b1d796b4271f44e87e307026Lennart Poettering ieAttr = (ieAttr !== undefined) ? ieAttr : 2;
488ad3b32a7e2b5b1380abf4a15e5f65fa65f3feLennart Poettering attr = Y.DOM.CUSTOM_ATTRIBUTES[attr] || attr;
488ad3b32a7e2b5b1380abf4a15e5f65fa65f3feLennart Poettering if (ret === null) {
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering frag = Y.DOM._fragClones[tag] = doc.createElement(tag);
966204e010ed432a1d7a0481d41a326d8ec7b0c8Lennart Poettering * Inserts content in a node at the given location
94676f3e9352cbf1f72e0a512ee0d2ed83ff676dLennart Poettering * @method addHTML
6fd4d0209827e5c3e52fa8c7144852f550f8f95cLennart Poettering * @param {HTMLElement} node The node to insert into
416446221d905b6815175dc4d525d27f8ae43d1bLennart Poettering * @param {String} content The content to be inserted
416446221d905b6815175dc4d525d27f8ae43d1bLennart Poettering * @param {String} where Where to insert the content; default is after lastChild
0aafd43d235982510d1c40564079f7bcec0c7c19Lennart Poettering addHTML: function(node, content, where) {
19aadacf92ad86967ffb678e37b2ff9e83cb9480Jan Engelhardt content = Y.Lang.trim(content); // match IE which trims whitespace from innerHTML
bdeeb6b543a2a2d0a494f17b85f1498859cdfc2fLennart Poettering } else { // create from string and cache
4e09014daf8f98584b3f15e64e93bed232e70a6bLennart Poettering if (where.nodeType) { // insert regardless of relationship to node
6bb648a16ae4a682ad4784412af706d2e6a3e4daTom Gundersen // TODO: check if node.contains(where)?
fa607802f332e06f4044c3eb38dbea41076c803dLennart Poettering where.parentNode.insertBefore(newNode, where);
1f140dd8b048c5f5599a886b8c4d20f3f1065774David Herrmann case 'replace':
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering if (newNode) { // allow empty content to clear node
df98a87ba389bdfc0359beedf47557411f3af434Lennart Poettering case 'before':
2ecfc64e59b5e4e96bed6f68bd36b612ef77a146Lennart Poettering if (node.nextSibling) { // IE errors if refNode is null
6a8b5fa4635ed858788fb10099ec9b62b3359a0aLennart Poettering nodeParent.insertBefore(newNode, node.nextSibling);
ab8e074ce25b9947314c69e17afe1bd2527ee26dLennart Poettering getter = Y.DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];
b5c03638d48c07aa0eaf13b5f54000c7133e1883Lennart Poettering // workaround for IE8 JSON stringify bug
d28315e4aff91560ed4c2fc9f876ec8bfc559f2dJan Engelhardt // which converts empty string values to null
eece8c6fb5f4d354dcef6fd369e876c4f3a3f163Lennart Poettering return (typeof ret === 'string') ? ret : '';
c144692179098c1861f2aeafc67689a74439cf4cLennart Poettering setter = Y.DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];
3679d1126bae52e02f6cd60fca196f616b9e660dLennart Poettering while ((sibling = sibling[PREVIOUS_SIBLING])) {
3679d1126bae52e02f6cd60fca196f616b9e660dLennart Poettering if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
81d112a8f0522a09fcfe317f420363a2b728137cLennart Poettering while ((sibling = sibling[NEXT_SIBLING])) {
490b7e47093d491a2bdb1084fe92b796f4e07eefLennart Poettering if (sibling[TAG_NAME] && (!fn || fn(sibling))) {
e9fd44b728ff1fc0d1f24fccb87a767f6865df27Lennart Poettering * Brute force version of contains.
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * Used for browsers without contains support for non-HTMLElement Nodes (textNodes, etc).
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * @method _bruteContains
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * @param {HTMLElement} element The containing html element.
8ed206517c2be381324ac5832bf34cc14024270eLennart Poettering * @param {HTMLElement} needle The html element that may be contained.
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * @return {Boolean} Whether or not the element is or contains the needle.
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering _bruteContains: function(element, needle) {
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering// TODO: move to Lang?
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering * Memoizes dynamic regular expressions to boost runtime performance.
279f036675536d55c901562b49f9df146af1a0e3Lennart Poettering * @method _getRegExp
279f036675536d55c901562b49f9df146af1a0e3Lennart Poettering * @param {String} str The string to convert to a regular expression.
279f036675536d55c901562b49f9df146af1a0e3Lennart Poettering * @param {String} flags optional An optinal string of flags.
279f036675536d55c901562b49f9df146af1a0e3Lennart Poettering * @return {RegExp} An instance of RegExp
279f036675536d55c901562b49f9df146af1a0e3Lennart Poettering Y.DOM._regexCache = Y.DOM._regexCache || {};
279f036675536d55c901562b49f9df146af1a0e3Lennart Poettering Y.DOM._regexCache[str + flags] = new RegExp(str, flags);
e673ad0415d89c322e5b1a121e411f1b1d8075c0Lennart Poettering// TODO: make getDoc/Win true privates?
e673ad0415d89c322e5b1a121e411f1b1d8075c0Lennart Poettering * returns the appropriate document.
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * @method _getDoc
c06bf414042cd1bf94e0af63e9e2a0c291bfc546Kay Sievers * @param {HTMLElement} element optional Target element.
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * @return {Object} The document for the given element or the default document.
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering return (element[NODE_TYPE] === 9) ? element : // element === document
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering element[OWNER_DOCUMENT] || // element === DOM node
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering element.document || // element === window
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * returns the appropriate window.
f47ec8ebb3858553dec870e1c596e39525f46360Lennart Poettering * @method _getWin
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering * @param {HTMLElement} element optional Target element.
038cf33420afa5f913fe5cbf3e7138574c33d97bZbigniew Jędrzejewski-Szmek * @return {Object} The window for the given element or the default window.
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering return doc[DEFAULT_VIEW] || doc[PARENT_WINDOW] || Y.config.win;
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering _batch: function(nodes, fn, arg1, arg2, arg3, etc) {
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering fn = (typeof name === 'string') ? Y.DOM[fn] : fn;
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering if ((result = fn.call(Y.DOM, node, arg1, arg2, arg3, etc)) !== undefined) {
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/,
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering // TODO: thead/tfoot with nested tbody
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering // IE adds TBODY when creating TABLE elements (which may share this impl)
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering var frag = create(TABLE_OPEN + html + TABLE_CLOSE, doc),
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering if (frag.children.length > 1 && tb && !re_tbody.test(html)) {
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering tb[PARENT_NODE].removeChild(tb); // strip extraneous tbody
f38afcd0c7f558ca5bf0854b42f8c6954f8ad7f3Lennart Poettering return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering // IE: node.value changes the button text, which should be handled via innerHTML
90e071d1d59be05fcba66561439c3ca67c80ee20Lennart Poettering attr = node[OWNER_DOCUMENT].createAttribute('value');
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering return create('<select>' + html + '</select>', doc);
dcfc4b2e5c1af6375488c00bdc6fb8122f86c4d7Lennart Poettering return create('<tbody>' + html + '</tbody>', doc);
1b89884ba31cbe98f159ce2c7d6fac5f6a57698fLennart Poettering return create('<tr>' + html + '</tr>', doc);
b44be3ecf6326c27aa2c6c6d1fe34e22e22592a0Lennart Poettering return create(TABLE_OPEN + html + TABLE_CLOSE, doc);
68f160039eb78fe122cfe0d4c49695ae91f6f0d1Lennart Poettering return (attrs.value && attrs.value.specified) ? node.value : node.text;
0790b9fed42eefc4e22dbbe2337cba9713b7848cLennart Poettering // TODO: implement multipe select
fd4d89b2c0b31da01d134301e30916931ae3c7d9Lennart Poettering Y.log('multiple select normalization not implemented', 'warn', 'DOM');
47ae7201b1df43bd3da83a19e38483b0e5694c99Lennart Poettering val = Y.DOM.getValue(options[node.selectedIndex], 'value');
d3a3f22267a7dac426b07a7ed0baa1632f5daf04Kay Sievers * Determines whether a DOM element has the given className.
d3a3f22267a7dac426b07a7ed0baa1632f5daf04Kay Sievers * @method hasClass
d3a3f22267a7dac426b07a7ed0baa1632f5daf04Kay Sievers * @param {HTMLElement} element The DOM element.
d3a3f22267a7dac426b07a7ed0baa1632f5daf04Kay Sievers * @param {String} className the class name to search for
d3a3f22267a7dac426b07a7ed0baa1632f5daf04Kay Sievers * @return {Boolean} Whether or not the element has the given class.
d3a3f22267a7dac426b07a7ed0baa1632f5daf04Kay Sievers var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
abd55b16547d0bb0ed1c31e72e16838f0f59f48bKay Sievers * Adds a class name to a given DOM element.
abd55b16547d0bb0ed1c31e72e16838f0f59f48bKay Sievers * @method addClass
abd55b16547d0bb0ed1c31e72e16838f0f59f48bKay Sievers * @param {HTMLElement} element The DOM element.
e8d842a0d0b39f298e1e7f70d29759e50b2b16d4Tom Gundersen * @param {String} className the class name to add to the class attribute
169c4f65131fbc7bcb51e7d5487a715cdcd0e0ebLennart Poettering if (!Y.DOM.hasClass(node, className)) { // skip if already present
169c4f65131fbc7bcb51e7d5487a715cdcd0e0ebLennart Poettering node.className = Y.Lang.trim([node.className, className].join(' '));
d0e5a33374cee92962af33dfc03873e470b014f6Lennart Poettering * Removes a class name from a given element.
d0e5a33374cee92962af33dfc03873e470b014f6Lennart Poettering * @method removeClass
d0e5a33374cee92962af33dfc03873e470b014f6Lennart Poettering * @param {HTMLElement} element The DOM element.
d0e5a33374cee92962af33dfc03873e470b014f6Lennart Poettering * @param {String} className the class name to remove from the class attribute
87a8baa35d6d65ac3b58ae8e26e338e67f8ae8edLennart Poettering if (className && hasClass(node, className)) {
87a8baa35d6d65ac3b58ae8e26e338e67f8ae8edLennart Poettering node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' +
f957632b960a0a42999b38ded7089fa602b41745Kay Sievers if ( hasClass(node, className) ) { // in case of multiple adjacent
614cc34f3a2a7c64a21c3f5256f2e2b2c1de1d51Zbigniew Jędrzejewski-Szmek * Replace a class with another class for a given element.
614cc34f3a2a7c64a21c3f5256f2e2b2c1de1d51Zbigniew Jędrzejewski-Szmek * If no oldClassName is present, the newClassName is simply added.
7d441ddb5ca090b5a97f58ac4b4d97b3e84fa81eLennart Poettering * @method replaceClass
d28315e4aff91560ed4c2fc9f876ec8bfc559f2dJan Engelhardt * @param {HTMLElement} element The DOM element
14e639ae7a1dbf156273ce697d30fbc6c6594209Lennart Poettering * @param {String} oldClassName the class name to be replaced
7f8aa67131cfc03ddcbd31c0420754864fc122f0Lennart Poettering * @param {String} newClassName the class name that will be replacing the old class name
72b9ed828bd22f3ddd74b6853c183eebf006d6d8Lennart Poettering //Y.log('replaceClass replacing ' + oldC + ' with ' + newC, 'info', 'Node');
1258097cd3cdbc5dd3d264850119e553a29c5068Lennart Poettering * If the className exists on the node it is removed, if it doesn't exist it is added.
1258097cd3cdbc5dd3d264850119e553a29c5068Lennart Poettering * @method toggleClass
1258097cd3cdbc5dd3d264850119e553a29c5068Lennart Poettering * @param {HTMLElement} element The DOM element
a4c279f87451186b8beb1b8cc21c7cad561ecf4bLennart Poettering * @param {String} className the class name to be toggled
a4c279f87451186b8beb1b8cc21c7cad561ecf4bLennart Poettering * @param {Boolean} addClass optional boolean to indicate whether class
55cdcbacf70f05a40a155af24f6d2da6b478cba6Lennart Poettering * should be added or removed regardless of current state
f28f1daf754a9a07de90e6fc4ada581bf5de677dLennart Poettering toggleClass: function(node, className, force) {
f28f1daf754a9a07de90e6fc4ada581bf5de677dLennart Poettering var add = (force !== undefined) ? force :
a74a8793b04de9886b4f6987b9cb86fa02c73520Lennart Poettering * Add style management functionality to DOM.
3679d1126bae52e02f6cd60fca196f616b9e660dLennart Poettering * @submodule dom-style