node.js revision 45f27cabd6196774234000850bbe9a5f70c64f9b
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * The Node Utility provides a DOM-like interface for interacting with DOM nodes.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @module node
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @submodule node-base
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * The Node class provides a wrapper for manipulating DOM Nodes.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Node properties can be accessed via the set/get methods.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Use Y.get() to retrieve Node instances.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * <strong>NOTE:</strong> Node properties are accessed using
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * the <code>set</code> and <code>get</code> methods.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @class Node
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @constructor
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @for Node
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix// "globals"
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix node[UID] = null; // unset existing uid to prevent collision (via clone or hack)
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (!uid) { // stamp failed; likely IE non-HTMLElement
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // used with previous/next/ancestor tests
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix var ret = null;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix function(n) {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix function(n) {
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel// end "globals"
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel// Add custom event adaptors to this list. This will make it so
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert// that delegate, key, available, contentready, etc all will
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert// be available through Node.on
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Registers plugins to be instantiated at the class level (plugins
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * which should be plugged into every instance of Node by default).
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method Node.plug
f4dbc5a10ebf95900d1ef56d74aad0474e159370Markus Engel * @param {Function | Array} plugin Either the plugin class, an array of plugin classes or an array of objects (with fn and cfg properties defined)
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {Object} config (Optional) If plugin is the plugin class, the configuration for the plugin
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Unregisters any class level plugins which have been registered by the Node
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method Node.unplug
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {Function | Array} plugin The plugin class, or an array of plugin classes
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Retrieves the DOM node bound to a Node instance
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method Node.getDOMNode
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {Y.Node || HTMLNode} node The Node instance or an HTMLNode
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {HTMLNode} The DOM node bound to the Node instance. If a DOM node is passed
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * as the node argument, it is simply returned.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix } else if (!node[NODE_NAME] || Y.DOM.isWindow(node)) { // must already be a DOMNode
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return node || null;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (typeof val === 'object' || typeof val === 'function') { // safari nodeList === function
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (NODE_TYPE in val || Y.DOM.isWindow(val)) {// node || window
ab026a45b1869d884ee3f0af690c3879b76425e8JucaBlues } else if (val.item || // dom collection or Node instance
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix (val[0] && val[0][NODE_TYPE])) { // array of DOM Nodes
51dc158adbe2c9d1df3c941cbf78b90944d1afc2Markus Engel for (var i in val) { // TODO: test this and pull hasOwnProperty check if safe?
2b635337710b879262acf4906dd85ee99b69f474Abhishek Sharma PublicNode.addMethod = function(name, fn, context) {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (name && fn && typeof fn === 'function') {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert ret = Node.scrubVal(fn.apply(context, args), this);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert Y.log('unable to add method: ' + name, 'warn', 'Node');
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz * Returns a single Node instance bound to the node or the
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * first element matching the given selector.
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * @method Y.get
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * @param {String | HTMLElement} node a node or Selector
793350428bfc8e69ecfe65fa638afe4acb1acdd9cilix * @param {Y.Node || HTMLElement} doc an optional document to scan. Defaults to Y.config.doc.
850cbc29823aa92a03e97caba1e3102b53d7c833cilix } else if (node.indexOf('win') === 0) { // win OR window
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix instance = Node._instances[uid]; // reuse exising instances
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert if (!instance || (cachedNode && node !== cachedNode)) { // new Node when nodes don't match
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Creates a new dom node using the provided markup string.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method create
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {String} html The markup used to create the element
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {HTMLDocument} doc An optional document context
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Node.get(Y.DOM.create.apply(Y.DOM, arguments));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Allows for getting and setting the text of an element.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Formatting is preserved and special characters are treated literally.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @config text
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @type String
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Returns a NodeList instance of all HTMLElement children.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @readOnly
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @config children
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @type NodeList
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix 'children': {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return Y.DOM.getValue(g_nodes[this[UID]]);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix getter: function() {
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return this._data;
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz// call with instance context
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // only allow when defined on node
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else if (node[name] !== undefined) { // pass thru DOM properties
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix// call with instance context
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert val = Y.Object.getValue(node, name.split(DOT));
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert } else if (node[name] !== undefined) { // pass thru from DOM
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return val ? Y.Node.scrubVal(val, this) : val;
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix toString: function() {
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert errorMsg = this[UID] + ': not bound to a node',
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // TODO: add yuid?
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert val = Y.Node.getDOMNode(this).getAttribute(attr, 2);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert Y.Node.getDOMNode(this).setAttribute(attr, val);
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return this;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Creates a new Node using the provided markup string.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @method create
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {String} html The markup used to create the element
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {HTMLDocument} doc An optional document context
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Compares nodes to determine if they match.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Node instances can be compared to each other and/or HTMLElements.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method compareTo
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {HTMLElement | Node} refNode The reference node to compare to the node.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Boolean} True if the nodes match, false if they do not.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Determines whether the node is appended to the document.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method inDoc
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {Node|HTMLElement} doc optional An optional document to check against.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Defaults to current document.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Boolean} Whether or not this node is appended to the document.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix doc = (doc) ? Node.getDOMNode(doc) : node[OWNER_DOCUMENT];
67f112a66b477fe7fb28c644a4deaf0793533838joncruz * Returns the nearest ancestor that passes the test applied by supplied boolean method.
67f112a66b477fe7fb28c644a4deaf0793533838joncruz * @method ancestor
67f112a66b477fe7fb28c644a4deaf0793533838joncruz * @param {String | Function} fn A selector string or boolean method for testing elements.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * If a function is used, it receives the current node being tested as the only argument.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Node} The matching Node instance or null if not found
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Node.get(Y.DOM.elementByAxis(g_nodes[this[UID]], 'parentNode', _wrapFn(fn)));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Returns the previous matching sibling.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * Returns the nearest element node sibling if no method provided.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * @method previous
e711b02fbbe0b7d07102ebdd63b05027d6f8af47Maximilian Albert * @param {String | Function} fn A selector or boolean method for testing elements.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * If a function is used, it receives the current node being tested as the only argument.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @return {Node} Node instance or null if not found
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert return Node.get(Y.DOM.elementByAxis(g_nodes[this[UID]], 'previousSibling', _wrapFn(fn), all));
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * Returns the next matching sibling.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * Returns the nearest element node sibling if no method provided.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * @method next
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * @param {String | Function} fn A selector or boolean method for testing elements.
fa90912de6e92199e5fa5957d1d47fd485abc011cilix * If a function is used, it receives the current node being tested as the only argument.
3ca2560f1103677939f8b6e8de30865c3aef7fe0cilix * @return {Node} Node instance or null if not found
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Node.get(Y.DOM.elementByAxis(g_nodes[this[UID]], 'nextSibling', _wrapFn(fn), all));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Retrieves a Node instance of nodes based on the given CSS selector.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method query
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {string} selector The CSS selector to test against.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {Node} A Node instance for the matching HTMLElement.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix return Y.get(Y.Selector.query(selector, g_nodes[this[UID]], true));
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Retrieves a nodeList based on the given CSS selector.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @method queryAll
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {string} selector The CSS selector to test against.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
9dc68827cbd515262ecb8d5ae8547d9e82c72e00Jon A. Cruz return Y.all(Y.Selector.query(selector, g_nodes[this[UID]]));
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix // TODO: allow fn test
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * Test if the supplied node matches the supplied selector.
13223d251a0eca100512280a15dc9b2213a28809cilix * @method test
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * @param {string} selector The CSS selector to test against.
13223d251a0eca100512280a15dc9b2213a28809cilix * @return {boolean} Whether or not the node matches the selector.
71dea9c6fbd2fd6d73cce6f1ed96151d51ada58fcilix * Removes the node from its parent.
13223d251a0eca100512280a15dc9b2213a28809cilix * Shortcut for myNode.get('parentNode').removeChild(myNode);
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @method remove
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz * @chainable
13223d251a0eca100512280a15dc9b2213a28809cilix return this;
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * Invokes a method on the Node instance
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @method invoke
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @param {String} method The name of the method to invoke
60282e8335d7b6ae7020613bb22c7c69a6909fbbJon A. Cruz * @param {Any} a, b, c, etc. Arguments to invoke the method with.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * @return Whatever the underly method returns.
fce046713c4cb905f38bf489cc4a73af425f3037Maximilian Albert * DOM Nodes and Collections return values
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix * are converted to Node/NodeList instances.
4358ff6156766a315e38e72a5c3c83d6d5f7486bcilix if (a && a instanceof Y.Node) {
if (b && b instanceof Y.Node) {
destructor: function() {
size: function() {
if (content) {