/ajax/libs/yui/3.0.0b1/dom/dom.js
https://gitlab.com/Mirros/cdnjs · JavaScript · 1491 lines · 966 code · 197 blank · 328 comment · 238 complexity · d84e8553260bfe5dbab05a27e856b51b MD5 · raw file
- YUI.add('dom-base', function(Y) {
- (function(Y) {
- /**
- * The DOM utility provides a cross-browser abtraction layer
- * normalizing DOM tasks, and adds extra helper functionality
- * for other common tasks.
- * @module dom
- * @submodule dom-base
- *
- */
- /**
- * Provides DOM helper methods.
- * @class DOM
- *
- */
- var NODE_TYPE = 'nodeType',
- OWNER_DOCUMENT = 'ownerDocument',
- DOCUMENT_ELEMENT = 'documentElement',
- DEFAULT_VIEW = 'defaultView',
- PARENT_WINDOW = 'parentWindow',
- TAG_NAME = 'tagName',
- PARENT_NODE = 'parentNode',
- FIRST_CHILD = 'firstChild',
- LAST_CHILD = 'lastChild',
- PREVIOUS_SIBLING = 'previousSibling',
- NEXT_SIBLING = 'nextSibling',
- CONTAINS = 'contains',
- COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
- re_tag = /<([a-z]+)/i;
- Y.DOM = {
- /**
- * Returns the HTMLElement with the given ID (Wrapper for document.getElementById).
- * @method byId
- * @param {String} id the id attribute
- * @param {Object} doc optional The document to search. Defaults to current document
- * @return {HTMLElement | null} The HTMLElement with the id, or null if none found.
- */
- byId: function(id, doc) {
- doc = doc || Y.config.doc;
- // TODO: IE Name
- return doc.getElementById(id);
- },
- /**
- * Returns the text content of the HTMLElement.
- * @method getText
- * @param {HTMLElement} element The html element.
- * @return {String} The text content of the element (includes text of any descending elements).
- */
- getText: (document.documentElement.textContent !== undefined) ?
- function(element) {
- var ret = '';
- if (element) {
- ret = element.textContent;
- }
- return ret || '';
- } : function(element) {
- var ret = '';
- if (element) {
- ret = element.innerText;
- }
- return ret || '';
- },
- /**
- * Sets the text content of the HTMLElement.
- * @method setText
- * @param {HTMLElement} element The html element.
- * @param {String} content The content to add.
- */
- setText: (document.documentElement.textContent !== undefined) ?
- function(element, content) {
- if (element) {
- element.textContent = content;
- }
- } : function(element, content) {
- if (element) {
- element.innerText = content;
- }
- },
- // TODO: pull out sugar (rely on _childBy, byAxis, etc)?
- /*
- * Finds the firstChild of the given HTMLElement.
- * @method firstChild
- * @deprecated Use _childBy
- * @param {HTMLElement} element The html element.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, the first found is returned.
- * @return {HTMLElement | null} The first matching child html element.
- */
- firstChild: function(element, fn) {
- return Y.DOM._childBy(element, null, fn);
- },
- // @deprecated Use _childBy
- firstChildByTag: function(element, tag, fn) {
- return Y.DOM._childBy(element, tag, fn);
- },
- /*
- * Finds the lastChild of the given HTMLElement.
- * @method lastChild
- * @deprecated Use _childBy
- * @param {HTMLElement} element The html element.
- * @param {String} tag The tag to search for.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, the first found is returned.
- * @return {HTMLElement | null} The first matching child html element.
- */
- lastChild: function(element, fn) {
- return Y.DOM._childBy(element, null, fn, true);
- },
- // @deprecated Use _childBy
- lastChildByTag: function(element, tag, fn) {
- return Y.DOM._childBy(element, tag, fn, true);
- },
- /*
- * Finds all HTMLElement childNodes matching the given tag.
- * @method childrenByTag
- * @deprecated Use Selector
- * @param {HTMLElement} element The html element.
- * @param {String} tag The tag to search for.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, all children with the given tag are collected.
- * @return {Array} The collection of child elements.
- * TODO: Webkit children.tags() returns grandchildren
- */
- _childrenByTag: function() {
- if (document[DOCUMENT_ELEMENT].children) {
- return function(element, tag, fn, toArray) { // TODO: keep toArray option?
- tag = (tag && tag !== '*') ? tag.toUpperCase() : null;
- var elements = [],
- wrapFn = fn;
- if (element) {
- if (tag && !Y.UA.webkit) { // children.tags() broken in safari
- elements = element.children.tags(tag);
- } else {
- elements = element.children;
- if (tag) {
- wrapFn = function(el) {
- return el[TAG_NAME].toUpperCase() === tag && (!fn || fn(el));
- };
- }
- }
- elements = Y.DOM.filterElementsBy(elements, wrapFn);
- }
- return elements;
- };
- } else {
- return function(element, tag, fn) {
- tag = (tag && tag !== '*') ? tag.toUpperCase() : null;
- var elements = [],
- wrapFn = fn;
- if (element) {
- elements = element.childNodes;
- if (tag) { // wrap fn and add tag test TODO: allow tag in filterElementsBy?
- wrapFn = function(el) {
- return el[TAG_NAME].toUpperCase() === tag && (!fn || fn(el));
- };
- }
- elements = Y.DOM.filterElementsBy(elements, wrapFn);
- }
- return elements;
- };
- }
- }(),
- /*
- * Finds all HTMLElement childNodes.
- * @method children
- * @deprecated Use Selector
- * @param {HTMLElement} element The html element.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, all children are collected.
- * @return {Array} The collection of child elements.
- */
- children: function(element, fn) {
- return Y.DOM._childrenByTag(element, null, fn);
- },
- /*
- * Finds the previous sibling of the element.
- * @method previous
- * @deprecated Use elementByAxis
- * @param {HTMLElement} element The html element.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current DOM node being tested as its only argument.
- * If no function is given, the first sibling is returned.
- * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
- * @return {HTMLElement | null} The matching DOM node or null if none found.
- */
- previous: function(element, fn, all) {
- return Y.DOM.elementByAxis(element, PREVIOUS_SIBLING, fn, all);
- },
- /*
- * Finds the next sibling of the element.
- * @method next
- * @deprecated Use elementByAxis
- * @param {HTMLElement} element The html element.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current DOM node being tested as its only argument.
- * If no function is given, the first sibling is returned.
- * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
- * @return {HTMLElement | null} The matching DOM node or null if none found.
- */
- next: function(element, fn, all) {
- return Y.DOM.elementByAxis(element, NEXT_SIBLING, fn, all);
- },
- /*
- * Finds the ancestor of the element.
- * @method ancestor
- * @deprecated Use elementByAxis
- * @param {HTMLElement} element The html element.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current DOM node being tested as its only argument.
- * If no function is given, the parentNode is returned.
- * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
- * @return {HTMLElement | null} The matching DOM node or null if none found.
- */
- // TODO: optional stopAt node?
- ancestor: function(element, fn, all) {
- return Y.DOM.elementByAxis(element, PARENT_NODE, fn, all);
- },
- /**
- * Searches the element by the given axis for the first matching element.
- * @method elementByAxis
- * @param {HTMLElement} element The html element.
- * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling).
- * @param {Function} fn optional An optional boolean test to apply.
- * @param {Boolean} all optional Whether all node types should be returned, or just element nodes.
- * The optional function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, the first element is returned.
- * @return {HTMLElement | null} The matching element or null if none found.
- */
- elementByAxis: function(element, axis, fn, all) {
- while (element && (element = element[axis])) { // NOTE: assignment
- if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) {
- return element;
- }
- }
- return null;
- },
- /*
- * Finds all elements with the given tag.
- * @method byTag
- * @deprecated Use Selector
- * @param {String} tag The tag being search for.
- * @param {HTMLElement} root optional An optional root element to start from.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, all elements with the given tag are returned.
- * @return {Array} The collection of matching elements.
- */
- byTag: function(tag, root, fn) {
- root = root || Y.config.doc;
- var elements = root.getElementsByTagName(tag),
- retNodes = [],
- i, len;
- for (i = 0, len = elements.length; i < len; ++i) {
- if ( !fn || fn(elements[i]) ) {
- retNodes[retNodes.length] = elements[i];
- }
- }
- return retNodes;
- },
- /*
- * Finds the first element with the given tag.
- * @method firstByTag
- * @deprecated Use Selector
- * @param {String} tag The tag being search for.
- * @param {HTMLElement} root optional An optional root element to start from.
- * @param {Function} fn optional An optional boolean test to apply.
- * The optional function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, the first match is returned.
- * @return {HTMLElement} The matching element.
- */
- firstByTag: function(tag, root, fn) {
- root = root || Y.config.doc;
- var elements = root.getElementsByTagName(tag),
- ret = null,
- i, len;
- for (i = 0, len = elements.length; i < len; ++i) {
- if ( !fn || fn(elements[i]) ) {
- ret = elements[i];
- break;
- }
- }
- return ret;
- },
- /*
- * Filters a collection of HTMLElements by the given attributes.
- * @method filterElementsBy
- * @param {Array} elements The collection of HTMLElements to filter.
- * @param {Function} fn A boolean test to apply.
- * The function is passed the current HTMLElement being tested as its only argument.
- * If no function is given, all HTMLElements are kept.
- * @return {Array} The filtered collection of HTMLElements.
- */
- filterElementsBy: function(elements, fn, firstOnly) {
- var ret = (firstOnly) ? null : [],
- i, len;
- for (i = 0, len = elements.length; i < len; ++i) {
- if (elements[i][TAG_NAME] && (!fn || fn(elements[i]))) {
- if (firstOnly) {
- ret = elements[i];
- break;
- } else {
- ret[ret.length] = elements[i];
- }
- }
- }
- return ret;
- },
- /**
- * Determines whether or not one HTMLElement is or contains another HTMLElement.
- * @method contains
- * @param {HTMLElement} element The containing html element.
- * @param {HTMLElement} needle The html element that may be contained.
- * @return {Boolean} Whether or not the element is or contains the needle.
- */
- contains: function(element, needle) {
- var ret = false;
- if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) {
- ret = false;
- } else if (element[CONTAINS]) {
- if (Y.UA.opera || needle[NODE_TYPE] === 1) { // IE & SAF contains fail if needle not an ELEMENT_NODE
- ret = element[CONTAINS](needle);
- } else {
- ret = Y.DOM._bruteContains(element, needle);
- }
- } else if (element[COMPARE_DOCUMENT_POSITION]) { // gecko
- if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) {
- ret = true;
- }
- }
- return ret;
- },
- /**
- * Determines whether or not the HTMLElement is part of the document.
- * @method inDoc
- * @param {HTMLElement} element The containing html element.
- * @param {HTMLElement} doc optional The document to check.
- * @return {Boolean} Whether or not the element is attached to the document.
- */
- inDoc: function(element, doc) {
- doc = doc || element[OWNER_DOCUMENT];
- var id = element.id;
- if (!id) { // TODO: remove when done?
- id = element.id = Y.guid();
- }
- return !! (doc.getElementById(id));
- },
- /**
- * Inserts the new node as the previous sibling of the reference node
- * @method insertBefore
- * @param {String | HTMLElement} newNode The node to be inserted
- * @param {String | HTMLElement} referenceNode The node to insert the new node before
- * @return {HTMLElement} The node that was inserted (or null if insert fails)
- */
- insertBefore: function(newNode, referenceNode) {
- var ret = null,
- parent;
- if (newNode && referenceNode && (parent = referenceNode.parentNode)) { // NOTE: assignment
- if (typeof newNode === 'string') {
- newNode = Y.DOM.create(newNode);
- }
- ret = parent.insertBefore(newNode, referenceNode);
- } else {
- }
- return ret;
- },
- /**
- * Inserts the new node as the next sibling of the reference node
- * @method insertAfter
- * @param {String | HTMLElement} newNode The node to be inserted
- * @param {String | HTMLElement} referenceNode The node to insert the new node after
- * @return {HTMLElement} The node that was inserted (or null if insert fails)
- */
- insertAfter: function(newNode, referenceNode) {
- if (!newNode || !referenceNode || !referenceNode[PARENT_NODE]) {
- return null;
- }
- if (typeof newNode === 'string') {
- newNode = Y.DOM.create(newNode);
- }
- if (referenceNode[NEXT_SIBLING]) {
- return referenceNode[PARENT_NODE].insertBefore(newNode, referenceNode[NEXT_SIBLING]);
- } else {
- return referenceNode[PARENT_NODE].appendChild(newNode);
- }
- },
- /**
- * Creates a new dom node using the provided markup string.
- * @method create
- * @param {String} html The markup used to create the element
- * @param {HTMLDocument} doc An optional document context
- */
- create: function(html, doc) {
- html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
- if (!doc && Y.DOM._cloneCache[html]) {
- return Y.DOM._cloneCache[html].cloneNode(true); // NOTE: return
- }
- doc = doc || Y.config.doc;
- var m = re_tag.exec(html),
- create = Y.DOM._create,
- custom = Y.DOM.creators,
- ret = null,
- tag, nodes;
- if (m && custom[m[1]]) {
- if (typeof custom[m[1]] === 'function') {
- create = custom[m[1]];
- } else {
- tag = custom[m[1]];
- }
- }
- nodes = create(html, doc, tag).childNodes;
- if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
- ret = nodes[0].parentNode.removeChild(nodes[0]);
- } else { // return multiple nodes as a fragment
- ret = doc.createDocumentFragment();
- while (nodes.length) {
- ret.appendChild(nodes[0]);
- }
- }
- Y.DOM._cloneCache[html] = ret.cloneNode(true);
- return ret;
- },
- CUSTOM_ATTRIBUTES: (!document.documentElement.hasAttribute) ? { // IE < 8
- 'for': 'htmlFor',
- 'class': 'className'
- } : { // w3c
- 'htmlFor': 'for',
- 'className': 'class'
- },
- /**
- * Provides a normalized attribute interface.
- * @method setAttibute
- * @param {String | HTMLElement} el The target element for the attribute.
- * @param {String} attr The attribute to set.
- * @param {String} val The value of the attribute.
- */
- setAttribute: function(el, attr, val) {
- if (el && el.setAttribute) {
- attr = Y.DOM.CUSTOM_ATTRIBUTES[attr] || attr;
- el.setAttribute(attr, val);
- }
- },
- /**
- * Provides a normalized attribute interface.
- * @method getAttibute
- * @param {String | HTMLElement} el The target element for the attribute.
- * @param {String} attr The attribute to get.
- * @return {String} The current value of the attribute.
- */
- getAttribute: function(el, attr) {
- var ret = '';
- if (el && el.getAttribute) {
- attr = Y.DOM.CUSTOM_ATTRIBUTES[attr] || attr;
- ret = el.getAttribute(attr, 2);
- if (ret === null) {
- ret = ''; // per DOM spec
- }
- }
- return ret;
- },
- // @deprecated
- srcIndex: (document.documentElement.sourceIndex) ?
- function(node) {
- return (node && node.sourceIndex) ? node.sourceIndex : null;
- } :
- function(node) {
- return (node && node[OWNER_DOCUMENT]) ?
- [].indexOf.call(node[OWNER_DOCUMENT].
- getElementsByTagName('*'), node) : null;
- },
- isWindow: function(obj) {
- return obj.alert && obj.document;
- },
- _fragClones: {
- div: document.createElement('div')
- },
- _create: function(html, doc, tag) {
- tag = tag || 'div';
- var frag = Y.DOM._fragClones[tag];
- if (frag) {
- frag = frag.cloneNode(false);
- } else {
- frag = Y.DOM._fragClones[tag] = doc.createElement(tag);
- }
- frag.innerHTML = html;
- return frag;
- },
- _removeChildNodes: function(node) {
- while (node.firstChild) {
- node.removeChild(node.firstChild);
- }
- },
- _cloneCache: {},
- /**
- * Inserts content in a node at the given location
- * @method addHTML
- * @param {HTMLElement} node The node to insert into
- * @param {String} content The content to be inserted
- * @param {String} where Where to insert the content; default is after lastChild
- */
- addHTML: function(node, content, where) {
- if (typeof content === 'string') {
- content = Y.Lang.trim(content); // match IE which trims whitespace from innerHTML
- }
- var newNode = Y.DOM._cloneCache[content];
-
- if (newNode) {
- newNode = newNode.cloneNode(true);
- } else {
- if (content.nodeType) { // domNode
- newNode = content;
- } else { // create from string and cache
- newNode = Y.DOM.create(content);
- }
- }
- if (where) {
- if (where.nodeType) { // insert regardless of relationship to node
- // TODO: check if node.contains(where)?
- where.parentNode.insertBefore(newNode, where);
- } else {
- switch (where) {
- case 'replace':
- while (node.firstChild) {
- node.removeChild(node.firstChild);
- }
- node.appendChild(newNode);
- break;
- case 'before':
- node.parentNode.insertBefore(newNode, node);
- break;
- case 'after':
- if (node.nextSibling) { // IE errors if refNode is null
- node.parentNode.insertBefore(newNode, node.nextSibling);
- } else {
- node.parentNode.appendChild(newNode);
- }
- break;
- default:
- node.appendChild(newNode);
- }
- }
- } else {
- node.appendChild(newNode);
- }
- return newNode;
- },
- VALUE_SETTERS: {},
- VALUE_GETTERS: {},
- getValue: function(node) {
- var ret = '', // TODO: return null?
- getter;
- if (node && node[TAG_NAME]) {
- getter = Y.DOM.VALUE_GETTERS[node[TAG_NAME].toLowerCase()];
- if (getter) {
- ret = getter(node);
- } else {
- ret = node.value;
- }
- }
- return (typeof ret === 'string') ? ret : '';
- },
- setValue: function(node, val) {
- var setter;
- if (node && node[TAG_NAME]) {
- setter = Y.DOM.VALUE_SETTERS[node[TAG_NAME].toLowerCase()];
- if (setter) {
- setter(node, val);
- } else {
- node.value = val;
- }
- }
- },
- _stripScripts: function(node) {
- var scripts = node.getElementsByTagName('script'),
- i, script;
- for (i = 0, script; script = scripts[i++];) {
- script.parentNode.removeChild(script);
- }
- },
- _execScripts: function(scripts, startIndex) {
- var newScript,
- i, script;
- startIndex = startIndex || 0;
- for (i = startIndex, script; script = scripts[i++];) {
- newScript = script.ownerDocument.createElement('script');
- script.parentNode.replaceChild(newScript, script);
- if (script.text) {
- newScript.text = script.text;
- } else if (script.src) {
- newScript.src = script.src;
- // "pause" while loading to ensure exec order
- // FF reports typeof onload as "undefined", so try IE first
- if (typeof newScript.onreadystatechange !== 'undefined') {
- newScript.onreadystatechange = function() {
- if (/loaded|complete/.test(script.readyState)) {
- event.srcElement.onreadystatechange = null;
- // timer to help ensure exec order
- setTimeout(function() {
- Y.DOM._execScripts(scripts, i++);
- }, 0);
- }
- };
- } else {
- newScript.onload = function(e) {
- e.target.onload = null;
- Y.DOM._execScripts(scripts, i++);
- };
- }
- return; // NOTE: early return to chain async loading
- }
- }
- },
- /**
- * Brute force version of contains.
- * Used for browsers without contains support for non-HTMLElement Nodes (textNodes, etc).
- * @method _bruteContains
- * @private
- * @param {HTMLElement} element The containing html element.
- * @param {HTMLElement} needle The html element that may be contained.
- * @return {Boolean} Whether or not the element is or contains the needle.
- */
- _bruteContains: function(element, needle) {
- while (needle) {
- if (element === needle) {
- return true;
- }
- needle = needle.parentNode;
- }
- return false;
- },
- // TODO: move to Lang?
- /**
- * Memoizes dynamic regular expressions to boost runtime performance.
- * @method _getRegExp
- * @private
- * @param {String} str The string to convert to a regular expression.
- * @param {String} flags optional An optinal string of flags.
- * @return {RegExp} An instance of RegExp
- */
- _getRegExp: function(str, flags) {
- flags = flags || '';
- Y.DOM._regexCache = Y.DOM._regexCache || {};
- if (!Y.DOM._regexCache[str + flags]) {
- Y.DOM._regexCache[str + flags] = new RegExp(str, flags);
- }
- return Y.DOM._regexCache[str + flags];
- },
- // TODO: make getDoc/Win true privates?
- /**
- * returns the appropriate document.
- * @method _getDoc
- * @private
- * @param {HTMLElement} element optional Target element.
- * @return {Object} The document for the given element or the default document.
- */
- _getDoc: function(element) {
- element = element || {};
- return (element[NODE_TYPE] === 9) ? element : // element === document
- element[OWNER_DOCUMENT] || // element === DOM node
- element.document || // element === window
- Y.config.doc; // default
- },
- /**
- * returns the appropriate window.
- * @method _getWin
- * @private
- * @param {HTMLElement} element optional Target element.
- * @return {Object} The window for the given element or the default window.
- */
- _getWin: function(element) {
- var doc = Y.DOM._getDoc(element);
- return doc[DEFAULT_VIEW] || doc[PARENT_WINDOW] || Y.config.win;
- },
- // @deprecated, use Selector
- _childBy: function(element, tag, fn, rev) {
- var ret = null,
- root, axis;
- if (element) {
- if (rev) {
- root = element[LAST_CHILD];
- axis = PREVIOUS_SIBLING;
- } else {
- root = element[FIRST_CHILD];
- axis = NEXT_SIBLING;
- }
- if (Y.DOM._testElement(root, tag, fn)) { // is the matching element
- ret = root;
- } else { // need to scan nextSibling axis of firstChild to find matching element
- ret = Y.DOM.elementByAxis(root, axis, fn);
- }
- }
- return ret;
- },
- _batch: function(nodes, fn, arg1, arg2, arg3, etc) {
- fn = (typeof name === 'string') ? Y.DOM[fn] : fn;
- var result,
- ret = [];
- if (fn && nodes) {
- Y.each(nodes, function(node) {
- if ((result = fn.call(Y.DOM, node, arg1, arg2, arg3, etc)) !== undefined) {
- ret[ret.length] = result;
- }
- });
- }
- return ret.length ? ret : nodes;
- },
- _testElement: function(element, tag, fn) {
- tag = (tag && tag !== '*') ? tag.toUpperCase() : null;
- return (element && element[TAG_NAME] &&
- (!tag || element[TAG_NAME].toUpperCase() === tag) &&
- (!fn || fn(element)));
- },
- creators: {},
- _IESimpleCreate: function(html, doc) {
- doc = doc || Y.config.doc;
- return doc.createElement(html);
- }
- };
- (function(Y) {
- var creators = Y.DOM.creators,
- create = Y.DOM.create,
- re_tbody = /(?:\/(?:thead|tfoot|tbody|caption|col|colgroup)>)+\s*<tbody/,
- TABLE_OPEN = '<table>',
- TABLE_CLOSE = '</table>';
- if (Y.UA.gecko || Y.UA.ie) { // require custom creation code for certain element types
- Y.mix(creators, {
- option: function(html, doc) {
- return create('<select>' + html + '</select>', doc);
- },
- tr: function(html, doc) {
- return create('<tbody>' + html + '</tbody>', doc);
- },
- td: function(html, doc) {
- return create('<tr>' + html + '</tr>', doc);
- },
- tbody: function(html, doc) {
- return create(TABLE_OPEN + html + TABLE_CLOSE, doc);
- },
- legend: 'fieldset'
- });
- creators.col = creators.tbody; // IE wraps in colgroup
- }
- if (Y.UA.ie) {
- Y.mix(creators, {
- // TODO: thead/tfoot with nested tbody
- // IE adds TBODY when creating TABLE elements (which may share this impl)
- tbody: function(html, doc) {
- var frag = create(TABLE_OPEN + html + TABLE_CLOSE, doc),
- tb = frag.children.tags('tbody')[0];
- if (frag.children.length > 1 && tb && !re_tbody.test(html)) {
- tb[PARENT_NODE].removeChild(tb); // strip extraneous tbody
- }
- return frag;
- },
- script: function(html, doc) {
- var frag = doc.createElement('div');
- frag.innerHTML = '-' + html;
- frag.removeChild(frag[FIRST_CHILD]);
- return frag;
- }
- }, true);
- Y.mix(Y.DOM.VALUE_GETTERS, {
- button: function(node) {
- return (node.attributes && node.attributes.value) ? node.attributes.value.value : '';
- }
- });
- Y.mix(Y.DOM.VALUE_SETTERS, {
- // IE: node.value changes the button text, which should be handled via innerHTML
- button: function(node, val) {
- var attr = node.attributes.value;
- if (!attr) {
- attr = node[OWNER_DOCUMENT].createAttribute('value');
- node.setAttributeNode(attr);
- }
- attr.value = val;
- }
- });
- }
- if (Y.UA.gecko || Y.UA.ie) {
- Y.mix(creators, {
- th: creators.td,
- thead: creators.tbody,
- tfoot: creators.tbody,
- caption: creators.tbody,
- colgroup: creators.tbody,
- col: creators.tbody,
- optgroup: creators.option
- });
- }
- Y.mix(Y.DOM.VALUE_GETTERS, {
- option: function(node) {
- var attrs = node.attributes;
- return (attrs.value && attrs.value.specified) ? node.value : node.text;
- },
- select: function(node) {
- var val = node.value,
- options = node.options;
- if (options && val === '') {
- if (node.multiple) {
- } else {
- val = Y.DOM.getValue(options[node.selectedIndex], 'value');
- }
- }
- return val;
- }
- });
- })(Y);
- })(Y);
- Y.mix(Y.DOM, {
- /**
- * Determines whether a DOM element has the given className.
- * @method hasClass
- * @param {HTMLElement} element The DOM element.
- * @param {String} className the class name to search for
- * @return {Boolean} Whether or not the element has the given class.
- */
- hasClass: function(node, className) {
- var re = Y.DOM._getRegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
- return re.test(node.className);
- },
- /**
- * Adds a class name to a given DOM element.
- * @method addClass
- * @param {HTMLElement} element The DOM element.
- * @param {String} className the class name to add to the class attribute
- */
- addClass: function(node, className) {
- if (!Y.DOM.hasClass(node, className)) { // skip if already present
- node.className = Y.Lang.trim([node.className, className].join(' '));
- }
- },
- /**
- * Removes a class name from a given element.
- * @method removeClass
- * @param {HTMLElement} element The DOM element.
- * @param {String} className the class name to remove from the class attribute
- */
- removeClass: function(node, className) {
- if (className && Y.DOM.hasClass(node, className)) {
- node.className = Y.Lang.trim(node.className.replace(Y.DOM._getRegExp('(?:^|\\s+)' +
- className + '(?:\\s+|$)'), ' '));
- if ( Y.DOM.hasClass(node, className) ) { // in case of multiple adjacent
- Y.DOM.removeClass(node, className);
- }
- }
- },
- /**
- * Replace a class with another class for a given element.
- * If no oldClassName is present, the newClassName is simply added.
- * @method replaceClass
- * @param {HTMLElement} element The DOM element.
- * @param {String} oldClassName the class name to be replaced
- * @param {String} newClassName the class name that will be replacing the old class name
- */
- replaceClass: function(node, oldC, newC) {
- Y.DOM.addClass(node, newC);
- Y.DOM.removeClass(node, oldC);
- },
- /**
- * If the className exists on the node it is removed, if it doesn't exist it is added.
- * @method toggleClass
- * @param {HTMLElement} element The DOM element.
- * @param {String} className the class name to be toggled
- */
- toggleClass: function(node, className) {
- if (Y.DOM.hasClass(node, className)) {
- Y.DOM.removeClass(node, className);
- } else {
- Y.DOM.addClass(node, className);
- }
- }
- });
- }, '@VERSION@' ,{requires:['event'], skinnable:false});
- YUI.add('dom-style', function(Y) {
- (function(Y) {
- /**
- * Add style management functionality to DOM.
- * @module dom
- * @submodule dom-style
- * @for DOM
- */
- var DOCUMENT_ELEMENT = 'documentElement',
- DEFAULT_VIEW = 'defaultView',
- OWNER_DOCUMENT = 'ownerDocument',
- STYLE = 'style',
- FLOAT = 'float',
- CSS_FLOAT = 'cssFloat',
- STYLE_FLOAT = 'styleFloat',
- TRANSPARENT = 'transparent',
- GET_COMPUTED_STYLE = 'getComputedStyle',
- DOCUMENT = Y.config.doc,
- UNDEFINED = undefined,
- re_color = /color$/i;
- Y.mix(Y.DOM, {
- CUSTOM_STYLES: {
- },
- /**
- * Sets a style property for a given element.
- * @method setStyle
- * @param {HTMLElement} An HTMLElement to apply the style to.
- * @param {String} att The style property to set.
- * @param {String|Number} val The value.
- */
- setStyle: function(node, att, val, style) {
- style = style || node.style;
- var CUSTOM_STYLES = Y.DOM.CUSTOM_STYLES;
- if (style) {
- if (val === null) {
- val = ''; // normalize for unsetting
- }
- if (att in CUSTOM_STYLES) {
- if (CUSTOM_STYLES[att].set) {
- CUSTOM_STYLES[att].set(node, val, style);
- return; // NOTE: return
- } else if (typeof CUSTOM_STYLES[att] === 'string') {
- att = CUSTOM_STYLES[att];
- }
- }
- style[att] = val;
- }
- },
- /**
- * Returns the current style value for the given property.
- * @method getStyle
- * @param {HTMLElement} An HTMLElement to get the style from.
- * @param {String} att The style property to get.
- */
- getStyle: function(node, att) {
- var style = node[STYLE],
- CUSTOM_STYLES = Y.DOM.CUSTOM_STYLES,
- val = '';
- if (style) {
- if (att in CUSTOM_STYLES) {
- if (CUSTOM_STYLES[att].get) {
- return CUSTOM_STYLES[att].get(node, att, style); // NOTE: return
- } else if (typeof CUSTOM_STYLES[att] === 'string') {
- att = CUSTOM_STYLES[att];
- }
- }
- val = style[att];
- if (val === '') { // TODO: is empty string sufficient?
- val = Y.DOM[GET_COMPUTED_STYLE](node, att);
- }
- }
- return val;
- },
- /**
- * Sets multiple style properties.
- * @method setStyles
- * @param {HTMLElement} node An HTMLElement to apply the styles to.
- * @param {Object} hash An object literal of property:value pairs.
- */
- setStyles: function(node, hash) {
- var style = node.style;
- Y.each(hash, function(v, n) {
- Y.DOM.setStyle(node, n, v, style);
- }, Y.DOM);
- },
- /**
- * Returns the computed style for the given node.
- * @method getComputedStyle
- * @param {HTMLElement} An HTMLElement to get the style from.
- * @param {String} att The style property to get.
- * @return {String} The computed value of the style property.
- */
- getComputedStyle: function(node, att) {
- var val = '',
- doc = node[OWNER_DOCUMENT];
- if (node[STYLE]) {
- val = doc[DEFAULT_VIEW][GET_COMPUTED_STYLE](node, null)[att];
- }
- return val;
- }
- });
- // normalize reserved word float alternatives ("cssFloat" or "styleFloat")
- if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][CSS_FLOAT] !== UNDEFINED) {
- Y.DOM.CUSTOM_STYLES[FLOAT] = CSS_FLOAT;
- } else if (DOCUMENT[DOCUMENT_ELEMENT][STYLE][STYLE_FLOAT] !== UNDEFINED) {
- Y.DOM.CUSTOM_STYLES[FLOAT] = STYLE_FLOAT;
- }
- // fix opera computedStyle default color unit (convert to rgb)
- if (Y.UA.opera) {
- Y.DOM[GET_COMPUTED_STYLE] = function(node, att) {
- var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
- val = view[GET_COMPUTED_STYLE](node, '')[att];
- if (re_color.test(att)) {
- val = Y.Color.toRGB(val);
- }
- return val;
- };
- }
- // safari converts transparent to rgba(), others use "transparent"
- if (Y.UA.webkit) {
- Y.DOM[GET_COMPUTED_STYLE] = function(node, att) {
- var view = node[OWNER_DOCUMENT][DEFAULT_VIEW],
- val = view[GET_COMPUTED_STYLE](node, '')[att];
- if (val === 'rgba(0, 0, 0, 0)') {
- val = TRANSPARENT;
- }
- return val;
- };
- }
- })(Y);
- (function(Y) {
- var TO_STRING = 'toString',
- PARSE_INT = parseInt,
- RE = RegExp;
- Y.Color = {
- KEYWORDS: {
- black: '000',
- silver: 'c0c0c0',
- gray: '808080',
- white: 'fff',
- maroon: '800000',
- red: 'f00',
- purple: '800080',
- fuchsia: 'f0f',
- green: '008000',
- lime: '0f0',
- olive: '808000',
- yellow: 'ff0',
- navy: '000080',
- blue: '00f',
- teal: '008080',
- aqua: '0ff'
- },
- re_RGB: /^rgb\(([0-9]+)\s*,\s*([0-9]+)\s*,\s*([0-9]+)\)$/i,
- re_hex: /^#?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i,
- re_hex3: /([0-9A-F])/gi,
- toRGB: function(val) {
- if (!Y.Color.re_RGB.test(val)) {
- val = Y.Color.toHex(val);
- }
- if(Y.Color.re_hex.exec(val)) {
- val = 'rgb(' + [
- PARSE_INT(RE.$1, 16),
- PARSE_INT(RE.$2, 16),
- PARSE_INT(RE.$3, 16)
- ].join(', ') + ')';
- }
- return val;
- },
- toHex: function(val) {
- val = Y.Color.KEYWORDS[val] || val;
- if (Y.Color.re_RGB.exec(val)) {
- var r = (RE.$1.length === 1) ? '0' + RE.$1 : Number(RE.$1),
- g = (RE.$2.length === 1) ? '0' + RE.$2 : Number(RE.$2),
- b = (RE.$3.length === 1) ? '0' + RE.$3 : Number(RE.$3);
- val = [
- r[TO_STRING](16),
- g[TO_STRING](16),
- b[TO_STRING](16)
- ].join('');
- }
- if (val.length < 6) {
- val = val.replace(Y.Color.re_hex3, '$1$1');
- }
- if (val !== 'transparent' && val.indexOf('#') < 0) {
- val = '#' + val;
- }
- return val.toLowerCase();
- }
- };
- })(Y);
- (function(Y) {
- var CLIENT_TOP = 'clientTop',
- CLIENT_LEFT = 'clientLeft',
- HAS_LAYOUT = 'hasLayout',
- PX = 'px',
- FILTER = 'filter',
- FILTERS = 'filters',
- OPACITY = 'opacity',
- AUTO = 'auto',
- BORDER_TOP_WIDTH = 'borderTopWidth',
- BORDER_RIGHT_WIDTH = 'borderRightWidth',
- BORDER_BOTTOM_WIDTH = 'borderBottomWidth',
- BORDER_LEFT_WIDTH = 'borderLeftWidth',
- WIDTH = 'width',
- HEIGHT = 'height',
- TRANSPARENT = 'transparent',
- VISIBLE = 'visible',
- GET_COMPUTED_STYLE = 'getComputedStyle',
- UNDEFINED = undefined,
- documentElement = document.documentElement,
- // TODO: unit-less lineHeight (e.g. 1.22)
- re_size = /^width|height$/,
- re_unit = /^(\d[.\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz|%){1}?/i,
- _getStyleObj = function(node) {
- return node.currentStyle || node.style;
- },
- ComputedStyle = {
- CUSTOM_STYLES: {},
- get: function(el, property) {
- var value = '',
- current;
- if (el) {
- current = _getStyleObj(el)[property];
- if (property === OPACITY) {
- value = Y.DOM.CUSTOM_STYLES[OPACITY].get(el);
- } else if (!current || (current.indexOf && current.indexOf(PX) > -1)) { // no need to convert
- value = current;
- } else if (Y.DOM.IE.COMPUTED[property]) { // use compute function
- value = Y.DOM.IE.COMPUTED[property](el, property);
- } else if (re_unit.test(current)) { // convert to pixel
- value = ComputedStyle.getPixel(el, property) + PX;
- } else {
- value = current;
- }
- }
- return value;
- },
- getOffset: function(el, prop) {
- var current = _getStyleObj(el)[prop], // value of "width", "top", etc.
- capped = prop.charAt(0).toUpperCase() + prop.substr(1), // "Width", "Top", etc.
- offset = 'offset' + capped, // "offsetWidth", "offsetTop", etc.
- pixel = 'pixel' + capped, // "pixelWidth", "pixelTop", etc.
- actual,
- value = '';
- if (current === AUTO) {
- actual = el[offset]; // offsetHeight/Top etc.
- if (actual === UNDEFINED) { // likely "right" or "bottom"
- value = 0;
- }
- value = actual;
- if (re_size.test(prop)) { // account for box model diff
- el.style[prop] = actual;
- if (el[offset] > actual) {
- // the difference is padding + border (works in Standards & Quirks modes)
- value = actual - (el[offset] - actual);
- }
- el.style[prop] = AUTO; // revert to auto
- }
- } else { // convert units to px
- if (current.indexOf('%') > -1) { // IE pixelWidth incorrect for percent; manually compute
- current = el.clientWidth - // offsetWidth - borderWidth
- ComputedStyle.getPixel(el, 'paddingRight') -
- ComputedStyle.getPixel(el, 'paddingLeft');
- }
- if (!el.style[pixel] && !el.style[prop]) { // need to map style.width to currentStyle (no currentStyle.pixelWidth)
- el.style[prop] = current; // no style.pixelWidth if no style.width
- }
- value = el.style[pixel];
- }
- return value + PX;
- },
- getBorderWidth: function(el, property) {
- // clientHeight/Width = paddingBox (e.g. offsetWidth - borderWidth)
- // clientTop/Left = borderWidth
- var value = null;
- if (!el.currentStyle || !el.currentStyle[HAS_LAYOUT]) { // TODO: unset layout?
- el.style.zoom = 1; // need layout to measure client
- }
- switch(property) {
- case BORDER_TOP_WIDTH:
- value = el[CLIENT_TOP];
- break;
- case BORDER_BOTTOM_WIDTH:
- value = el.offsetHeight - el.clientHeight - el[CLIENT_TOP];
- break;
- case BORDER_LEFT_WIDTH:
- value = el[CLIENT_LEFT];
- break;
- case BORDER_RIGHT_WIDTH:
- value = el.offsetWidth - el.clientWidth - el[CLIENT_LEFT];
- break;
- }
- return value + PX;
- },
- getPixel: function(node, att) {
- // use pixelRight to convert to px
- var val = null,
- style = _getStyleObj(node),
- styleRight = style.right,
- current = style[att];
- node.style.right = current;
- val = node.style.pixelRight;
- node.style.right = styleRight; // revert
- return val;
- },
- getMargin: function(node, att) {
- var val,
- style = _getStyleObj(node);
- if (style[att] == AUTO) {
- val = 0;
- } else {
- val = ComputedStyle.getPixel(node, att);
- }
- return val + PX;
- },
- getVisibility: function(node, att) {
- var current;
- while ( (current = node.currentStyle) && current[att] == 'inherit') { // NOTE: assignment in test
- node = node.parentNode;
- }
- return (current) ? current[att] : VISIBLE;
- },
- getColor: function(node, att) {
- var current = _getStyleObj(node)[att];
- if (!current || current === TRANSPARENT) {
- Y.DOM.elementByAxis(node, 'parentNode', null, function(parent) {
- current = _getStyleObj(parent)[att];
- if (current && current !== TRANSPARENT) {
- node = parent;
- return true;
- }
- });
- }
- return Y.Color.toRGB(current);
- },
- getBorderColor: function(node, att) {
- var current = _getStyleObj(node),
- val = current[att] || current.color;
- return Y.Color.toRGB(Y.Color.toHex(val));
- }
- },
- //fontSize: getPixelFont,
- IEComputed = {};
- // use alpha filter for IE opacity
- if (documentElement.style[OPACITY] === UNDEFINED &&
- documentElement[FILTERS]) {
- Y.DOM.CUSTOM_STYLES[OPACITY] = {
- get: function(node) {
- var val = 100;
- try { // will error if no DXImageTransform
- val = node[FILTERS]['DXImageTransform.Microsoft.Alpha'][OPACITY];
- } catch(e) {
- try { // make sure its in the document
- val = node[FILTERS]('alpha')[OPACITY];
- } catch(err) {
- }
- }
- return val / 100;
- },
- set: function(node, val, style) {
- var current,
- styleObj;
- if (val === '') { // normalize inline style behavior
- styleObj = _getStyleObj(node);
- current = (OPACITY in styleObj) ? styleObj[OPACITY] : 1; // revert to original opacity
- val = current;
- }
- if (typeof style[FILTER] == 'string') { // in case not appended
- style[FILTER] = 'alpha(' + OPACITY + '=' + val * 100 + ')';
-
- if (!node.currentStyle || !node.currentStyle[HAS_LAYOUT]) {
- style.zoom = 1; // needs layout
- }
- }
- }
- };
- }
- try {
- document.createElement('div').style.height = '-1px';
- } catch(e) { // IE throws error on invalid style set; trap common cases
- Y.DOM.CUSTOM_STYLES.height = {
- set: function(node, val, style) {
- if (parseInt(val, 10) >= 0) {
- style.height = val;
- } else {
- }
- }
- };
- Y.DOM.CUSTOM_STYLES.width = {
- set: function(node, val, style) {
- if (parseInt(val, 10) >= 0) {
- style.width = val;
- } else {
- }
- }
- };
- }
- // TODO: top, right, bottom, left
- IEComputed[WIDTH] = IEComputed[HEIGHT] = ComputedStyle.getOffset;
- IEComputed.color = IEComputed.backgroundColor = ComputedStyle.getColor;
- IEComputed[BORDER_TOP_WIDTH] = IEComputed[BORDER_RIGHT_WIDTH] =
- IEComputed[BORDER_BOTTOM_WIDTH] = IEComputed[BORDER_LEFT_WIDTH] =
- ComputedStyle.getBorderWidth;
- IEComputed.marginTop = IEComputed.marginRight = IEComputed.marginBottom =
- IEComputed.marginLeft = ComputedStyle.getMargin;
- IEComputed.visibility = ComputedStyle.getVisibility;
- IEComputed.borderColor = IEComputed.borderTopColor =
- IEComputed.borderRightColor = IEComputed.borderBottomColor =
- IEComputed.borderLeftColor = ComputedStyle.getBorderColor;
- if (!Y.config.win[GET_COMPUTED_STYLE]) {
- Y.DOM[GET_COMPUTED_STYLE] = ComputedStyle.get;
- }
- Y.namespace('DOM.IE');
- Y.DOM.IE.COMPUTED = IEComputed;
- Y.DOM.IE.ComputedStyle = ComputedStyle;
- })(Y);
- }, '@VERSION@' ,{skinnable:false, requires:['dom-base']});
- YUI.add('dom-screen', function(Y) {
- (fun