dom-debug.js revision 81ba27a21e393896f8d167f996e7d8af8221e307
99e8cdc499b7d0fc96f88d0a6a3ccc0624d46854Eric Luce(function(Y) {
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * The DOM utility provides a cross-browser abtraction layer
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * normalizing DOM tasks, and adds extra helper functionality
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * for other common tasks.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @module dom
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @submodule dom-base
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * Provides DOM helper methods.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @class DOM
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce COMPARE_DOCUMENT_POSITION = 'compareDocumentPosition',
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce re_tag = /<([a-z]+)/i;
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * Returns the HTMLElement with the given ID (Wrapper for document.getElementById).
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @method byId
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {String} id the id attribute
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {Object} doc optional The document to search. Defaults to current document
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @return {HTMLElement | null} The HTMLElement with the id, or null if none found.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce // TODO: IE Name
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce // @deprecated
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce // @deprecated
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce return ret || null;
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * Returns the text content of the HTMLElement.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @method getText
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {HTMLElement} element The html element.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @return {String} The text content of the element (includes text of any descending elements).
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce getText: (documentElement.textContent !== undefined) ?
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce } : function(element) {
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce * Sets the text content of the HTMLElement.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce * @method setText
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce * @param {HTMLElement} element The html element.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce * @param {String} content The content to add.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce setText: (documentElement.textContent !== undefined) ?
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * Finds the previous sibling of the element.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @method previous
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @deprecated Use elementByAxis
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @param {HTMLElement} element The html element.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @param {Function} fn optional An optional boolean test to apply.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * The optional function is passed the current DOM node being tested as its only argument.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * If no function is given, the first sibling is returned.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @return {HTMLElement | null} The matching DOM node or null if none found.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce return Y.DOM.elementByAxis(element, PREVIOUS_SIBLING, fn, all);
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * Finds the next sibling of the element.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @method next
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @deprecated Use elementByAxis
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @param {HTMLElement} element The html element.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @param {Function} fn optional An optional boolean test to apply.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * The optional function is passed the current DOM node being tested as its only argument.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * If no function is given, the first sibling is returned.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
fafd1d771905532e8dc3efa2ce90ce4c9e74af61Eric Luce * @return {HTMLElement | null} The matching DOM node or null if none found.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce return Y.DOM.elementByAxis(element, NEXT_SIBLING, fn, all);
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * Finds the ancestor of the element.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @method ancestor
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @deprecated Use elementByAxis
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {HTMLElement} element The html element.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {Function} fn optional An optional boolean test to apply.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * The optional function is passed the current DOM node being tested as its only argument.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce * If no function is given, the parentNode is returned.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce * @param {Boolean} all optional Whether all node types should be scanned, or just element nodes.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce * @return {HTMLElement | null} The matching DOM node or null if none found.
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce // TODO: optional stopAt node?
c71787bd6356c92e9c7d0a174cd63ab17fcf34c6Eric Luce return Y.DOM.elementByAxis(element, PARENT_NODE, fn, all);
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * Searches the element by the given axis for the first matching element.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @method elementByAxis
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {HTMLElement} element The html element.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @param {String} axis The axis to search (parentNode, nextSibling, previousSibling).
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {Function} fn optional An optional boolean test to apply.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @param {Boolean} all optional Whether all node types should be returned, or just element nodes.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * The optional function is passed the current HTMLElement being tested as its only argument.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * If no function is given, the first element is returned.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @return {HTMLElement | null} The matching element or null if none found.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce while (element && (element = element[axis])) { // NOTE: assignment
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce if ( (all || element[TAG_NAME]) && (!fn || fn(element)) ) {
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce return null;
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * Determines whether or not one HTMLElement is or contains another HTMLElement.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @method contains
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @param {HTMLElement} element The containing html element.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @param {HTMLElement} needle The html element that may be contained.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @return {Boolean} Whether or not the element is or contains the needle.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce var ret = false;
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce if ( !needle || !element || !needle[NODE_TYPE] || !element[NODE_TYPE]) {
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce if (Y.UA.opera || needle[NODE_TYPE] === 1) { // IE & SAF contains fail if needle not an ELEMENT_NODE
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce } else if (element[COMPARE_DOCUMENT_POSITION]) { // gecko
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce if (element === needle || !!(element[COMPARE_DOCUMENT_POSITION](needle) & 16)) {
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * Determines whether or not the HTMLElement is part of the document.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @method inDoc
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @param {HTMLElement} element The containing html element.
f3cdacd7645772686420f7eadcc85b4c18301adeEric Luce * @param {HTMLElement} doc optional The document to check.
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce * @return {Boolean} Whether or not the element is attached to the document.
7d7c5eee345bf4a62764cbce55868a6c09568543Eric Luce * Creates a new dom node using the provided markup string.
7d7c5eee345bf4a62764cbce55868a6c09568543Eric Luce * @method create
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @param {String} html The markup used to create the element
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @param {HTMLDocument} doc An optional document context
9b26804b581d11dc845e96073bda32f739581aeeEric Luce html = Y.Lang.trim(html); // match IE which trims whitespace from innerHTML
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce return Y.DOM._cloneCache[html].cloneNode(true); // NOTE: return
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce if (nodes.length === 1) { // return single node, breaking parentNode ref from "fragment"
55c73d07349b0be7d800f39fcc30eba6ab760129Eric Luce } else { // return multiple nodes as a fragment
9b26804b581d11dc845e96073bda32f739581aeeEric Luce var ret = null,
9b26804b581d11dc845e96073bda32f739581aeeEric Luce if (nodes && (nodes.push || nodes.item) && nodes[0]) {
9b26804b581d11dc845e96073bda32f739581aeeEric Luce if (nodes.item) { // convert live list to static array
9b26804b581d11dc845e96073bda32f739581aeeEric Luce } // else inline with log for minification
9b26804b581d11dc845e96073bda32f739581aeeEric Luce else { Y.log('unable to convert ' + nodes + ' to fragment', 'warn', 'dom'); }
9b26804b581d11dc845e96073bda32f739581aeeEric Luce CUSTOM_ATTRIBUTES: (!documentElement.hasAttribute) ? { // IE < 8
9b26804b581d11dc845e96073bda32f739581aeeEric Luce } : { // w3c
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * Provides a normalized attribute interface.
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @method setAttibute
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @param {String | HTMLElement} el The target element for the attribute.
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @param {String} attr The attribute to set.
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @param {String} val The value of the attribute.
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * Provides a normalized attribute interface.
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @method getAttibute
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @param {String | HTMLElement} el The target element for the attribute.
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @param {String} attr The attribute to get.
9b26804b581d11dc845e96073bda32f739581aeeEric Luce * @return {String} The current value of the attribute.
if (ret === null) {
return ret;
_fragClones: {
if (frag) {
return frag;
_cloneCache: {},
if (newNode) {
if (where) {
switch (where) {
return newNode;
VALUE_SETTERS: {},
VALUE_GETTERS: {},
if (getter) {
var setter;
if (setter) {
while (needle) {
var result,
ret = [];
creators: {},
return frag;
return frag;
if (!attr) {
return val;
if (style) {
if (val === null) {
if (style) {
return val;
}, Y.DOM);
return val;
return val;
return val;
RE = RegExp;
Y.Color = {
KEYWORDS: {
return val;
val = [
ComputedStyle = {
CUSTOM_STYLES: {},
if (el) {
return value;
sizeOffsets: {
// NOTE: clientWidth/Height (size minus border) is 0 when current === AUTO so offsetHeight is used
borderMap: {
var val = null,
return val;
var val,
var current;
IEComputed = {};
} catch(err) {
var current,
TODO: test inDocument/display?
getXY: function() {
return function(node) {
var xy = null,
box,
mode,
doc;
if (node) {
return xy;
var xy = null,
if (node) {
if (bCheck) {
return xy;
var pos,
xy = null;
if (node) {
xy = [
return xy;
* The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
pos,
if (!noRetry) {
* Set the X position of an html element in page coordinates, regardless of how the element is positioned.
* The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
* Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
* The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
return xy2;
ret = {};
return ret;
@return {Object} Object literal containing the following about this element: (top, right, bottom, left)
ret = false;
return ret;
* @param {Object} altRegion An object literal containing the region for the first element if we already have the data (for performance i.e. DragDrop)
@return {Object} Object literal containing the following intersection data: (top, right, bottom, left, area, yoff, xoff, inRegion)
n = node2,
off;
if (n.tagName) {
* @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance i.e. DragDrop)
var region = {},
n = node2,
off;
if (n.tagName) {
if (all) {
* @param {Object} altRegion An object literal containing the region for this node if we already have the data (for performance i.e. DragDrop)
_getRegion: function(t, r, b, l) {
var region = {};
return region;
* Returns an Object literal containing the following about the visible region of viewport: (top, right, bottom, left)
@return {Object} Object literal containing the following about the visible region of the viewport: (top, right, bottom, left)
var ret = false,
if (node) {
return ret;
var Selector = {
_foundCache: [],
useNative: true,
return compare;
if (nodes) {
return nodes;
var ret = [],
i, node;
return ret;
* @param {HTMLElement} root optional An HTMLElement to start the query from. Defaults to Y.config.doc
var ret = [],
queries = [],
i, len;
if (node) {
return queries;
var ret = [],
i, node;
return ret;
var ret = false,
item,
i, group;
if (ret) {
return ret;
SelectorCSS2 = {
SORT_RESULTS: true,
children = [],
ret = [];
return ret || [];
_regexCache: {},
_re: {
attr: /(\[.*\])/g,
'': function(node, attr) { return Y.DOM.getAttribute(node, attr) !== ''; }, // Just test for existence of attribute
tagName: null,
id: null,
className: null,
attributes: {},
combinator: null,
tests: []
test,
i, parser;
found = false;
break outer;
} else if (test) {
found = true;
tokens = [];
return tokens;
pseudos = selector.match(Selector._re.pseudos), // pull attributes to avoid false pos on "." and "#"
if (pseudos) {
if (attrs) {
if (attrs) {
if (pseudos) {
return selector;
_attrFilters: {
getters: {