src/cm/media/js/lib/yui/yui3.0.0/build/node/node-base-debug.js
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 /*
       
     2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
       
     3 Code licensed under the BSD License:
       
     4 http://developer.yahoo.net/yui/license.txt
       
     5 version: 3.0.0
       
     6 build: 1549
       
     7 */
       
     8 YUI.add('node-base', function(Y) {
       
     9 
       
    10 /**
       
    11  * The Node Utility provides a DOM-like interface for interacting with DOM nodes.
       
    12  * @module node
       
    13  * @submodule node-base
       
    14  */    
       
    15 
       
    16 /**
       
    17  * The Node class provides a wrapper for manipulating DOM Nodes.
       
    18  * Node properties can be accessed via the set/get methods.
       
    19  * Use Y.get() to retrieve Node instances.
       
    20  *
       
    21  * <strong>NOTE:</strong> Node properties are accessed using
       
    22  * the <code>set</code> and <code>get</code> methods.
       
    23  *
       
    24  * @class Node
       
    25  * @constructor
       
    26  * @for Node
       
    27  */
       
    28 
       
    29 // "globals"
       
    30 var DOT = '.',
       
    31     NODE_NAME = 'nodeName',
       
    32     NODE_TYPE = 'nodeType',
       
    33     OWNER_DOCUMENT = 'ownerDocument',
       
    34     TAG_NAME = 'tagName',
       
    35     UID = '_yuid',
       
    36 
       
    37     Node = function(node) {
       
    38         var uid = node[UID];
       
    39 
       
    40         if (uid && Node._instances[uid] && Node._instances[uid]._node !== node) {
       
    41             node[UID] = null; // unset existing uid to prevent collision (via clone or hack)
       
    42         }
       
    43 
       
    44         uid = Y.stamp(node);
       
    45         if (!uid) { // stamp failed; likely IE non-HTMLElement
       
    46             uid = Y.guid();
       
    47         }
       
    48 
       
    49         this[UID] = uid;
       
    50 
       
    51         this._node = node;
       
    52         Node._instances[uid] = this;
       
    53 
       
    54         this._stateProxy = node; // when augmented with Attribute
       
    55 
       
    56         if (this._initPlugins) { // when augmented with Plugin.Host
       
    57             this._initPlugins();
       
    58         }
       
    59     },
       
    60 
       
    61     // used with previous/next/ancestor tests
       
    62     _wrapFn = function(fn) {
       
    63         var ret = null;
       
    64         if (fn) {
       
    65             ret = (typeof fn === 'string') ?
       
    66             function(n) {
       
    67                 return Y.Selector.test(n, fn);
       
    68             } : 
       
    69             function(n) {
       
    70                 return fn(Node.get(n));
       
    71             };
       
    72         }
       
    73 
       
    74         return ret;
       
    75     };
       
    76 // end "globals"
       
    77 
       
    78 Node.NAME = 'Node';
       
    79 
       
    80 Node.re_aria = /^(?:role$|aria-)/;
       
    81 
       
    82 Node.DOM_EVENTS = {
       
    83     abort: true,
       
    84     beforeunload: true,
       
    85     blur: true,
       
    86     change: true,
       
    87     click: true,
       
    88     close: true,
       
    89     command: true,
       
    90     contextmenu: true,
       
    91     drag: true,
       
    92     dragstart: true,
       
    93     dragenter: true,
       
    94     dragover: true,
       
    95     dragleave: true,
       
    96     dragend: true,
       
    97     drop: true,
       
    98     dblclick: true,
       
    99     error: true,
       
   100     focus: true,
       
   101     keydown: true,
       
   102     keypress: true,
       
   103     keyup: true,
       
   104     load: true,
       
   105     message: true,
       
   106     mousedown: true,
       
   107     mousemove: true,
       
   108     mouseout: true, 
       
   109     mouseover: true, 
       
   110     mouseup: true,
       
   111     mousemultiwheel: true,
       
   112     mousewheel: true,
       
   113     submit: true,
       
   114     mouseenter: true,
       
   115     mouseleave: true,
       
   116     scroll: true,
       
   117     reset: true,
       
   118     resize: true,
       
   119     select: true,
       
   120     textInput: true,
       
   121     unload: true
       
   122 };
       
   123 
       
   124 // Add custom event adaptors to this list.  This will make it so
       
   125 // that delegate, key, available, contentready, etc all will
       
   126 // be available through Node.on
       
   127 Y.mix(Node.DOM_EVENTS, Y.Env.evt.plugins);
       
   128 
       
   129 Node._instances = {};
       
   130 
       
   131 /**
       
   132  * Retrieves the DOM node bound to a Node instance
       
   133  * @method Node.getDOMNode
       
   134  * @static
       
   135  *
       
   136  * @param {Y.Node || HTMLNode} node The Node instance or an HTMLNode
       
   137  * @return {HTMLNode} The DOM node bound to the Node instance.  If a DOM node is passed
       
   138  * as the node argument, it is simply returned.
       
   139  */
       
   140 Node.getDOMNode = function(node) {
       
   141     if (node) {
       
   142         return (node.nodeType) ? node : node._node || null;
       
   143     }
       
   144     return null;
       
   145 };
       
   146  
       
   147 Node.scrubVal = function(val, node) {
       
   148     if (node && val) { // only truthy values are risky
       
   149         if (typeof val === 'object' || typeof val === 'function') { // safari nodeList === function
       
   150             if (NODE_TYPE in val || Y.DOM.isWindow(val)) {// node || window
       
   151                 val = Node.get(val);
       
   152             } else if ((val.item && !val._nodes) || // dom collection or Node instance
       
   153                     (val[0] && val[0][NODE_TYPE])) { // array of DOM Nodes
       
   154                 val = Y.all(val);
       
   155             }
       
   156         }
       
   157     } else if (val === undefined) {
       
   158         val = node; // for chaining
       
   159     }
       
   160 
       
   161     return val;
       
   162 };
       
   163 
       
   164 Node.addMethod = function(name, fn, context) {
       
   165     if (name && fn && typeof fn === 'function') {
       
   166         Node.prototype[name] = function() {
       
   167             context = context || this;
       
   168             var args = Y.Array(arguments),
       
   169                 ret;
       
   170 
       
   171             if (args[0] && args[0] instanceof Node) {
       
   172                 args[0] = args[0]._node;
       
   173             }
       
   174 
       
   175             if (args[1] && args[1] instanceof Node) {
       
   176                 args[1] = args[1]._node;
       
   177             }
       
   178             args.unshift(this._node);
       
   179             ret = Node.scrubVal(fn.apply(context, args), this);
       
   180             return ret;
       
   181         };
       
   182     } else {
       
   183         Y.log('unable to add method: ' + name, 'warn', 'Node');
       
   184     }
       
   185 };
       
   186 
       
   187 Node.importMethod = function(host, name, altName) {
       
   188     if (typeof name === 'string') {
       
   189         altName = altName || name;
       
   190         Node.addMethod(altName, host[name], host);
       
   191     } else {
       
   192         Y.each(name, function(n) {
       
   193             Node.importMethod(host, n);
       
   194         });
       
   195     }
       
   196 };
       
   197 
       
   198 /**
       
   199  * Returns a single Node instance bound to the node or the
       
   200  * first element matching the given selector.
       
   201  * @method Y.one
       
   202  * @static
       
   203  * @param {String | HTMLElement} node a node or Selector 
       
   204  * @param {Y.Node || HTMLElement} doc an optional document to scan. Defaults to Y.config.doc. 
       
   205  */
       
   206 Node.one = function(node) {
       
   207     var instance = null,
       
   208         cachedNode,
       
   209         uid;
       
   210 
       
   211     if (node) {
       
   212         if (typeof node === 'string') {
       
   213             if (node.indexOf('doc') === 0) { // doc OR document
       
   214                 node = Y.config.doc;
       
   215             } else if (node.indexOf('win') === 0) { // win OR window
       
   216                 node = Y.config.win;
       
   217             } else {
       
   218                 node = Y.Selector.query(node, null, true);
       
   219             }
       
   220             if (!node) {
       
   221                 return null;
       
   222             }
       
   223         } else if (node instanceof Node) {
       
   224             return node; // NOTE: return
       
   225         }
       
   226 
       
   227         uid = node._yuid;
       
   228         instance = Node._instances[uid]; // reuse exising instances
       
   229         cachedNode = instance ? instance._node : null;
       
   230         if (!instance || (cachedNode && node !== cachedNode)) { // new Node when nodes don't match
       
   231             instance = new Node(node);
       
   232         }
       
   233     }
       
   234     return instance;
       
   235 };
       
   236 
       
   237 /**
       
   238  * Returns a single Node instance bound to the node or the
       
   239  * first element matching the given selector.
       
   240  * @method Y.get
       
   241  * @deprecated Use Y.one
       
   242  * @static
       
   243  * @param {String | HTMLElement} node a node or Selector 
       
   244  * @param {Y.Node || HTMLElement} doc an optional document to scan. Defaults to Y.config.doc. 
       
   245  */
       
   246 Node.get = function() {
       
   247     Y.log('Y.get is deprecated, use Y.one', 'warn', 'deprecated');
       
   248     return Node.one.apply(Node, arguments);
       
   249 };
       
   250 
       
   251 /**
       
   252  * Creates a new dom node using the provided markup string. 
       
   253  * @method create
       
   254  * @static
       
   255  * @param {String} html The markup used to create the element
       
   256  * @param {HTMLDocument} doc An optional document context 
       
   257  * @return {Node} A Node instance bound to a DOM node or fragment 
       
   258  */
       
   259 Node.create = function() {
       
   260     return Node.get(Y.DOM.create.apply(Y.DOM, arguments));
       
   261 };
       
   262 
       
   263 Node.ATTRS = {
       
   264     /**
       
   265      * Allows for getting and setting the text of an element.
       
   266      * Formatting is preserved and special characters are treated literally.
       
   267      * @config text
       
   268      * @type String
       
   269      */
       
   270     text: {
       
   271         getter: function() {
       
   272             return Y.DOM.getText(this._node);
       
   273         },
       
   274 
       
   275         setter: function(content) {
       
   276             Y.DOM.setText(this._node, content);
       
   277             return content;
       
   278         }
       
   279     },
       
   280 
       
   281     'options': {
       
   282         getter: function() {
       
   283             return this._node.getElementsByTagName('option');
       
   284         }
       
   285     },
       
   286 
       
   287      // IE: elements collection is also FORM node which trips up scrubVal.
       
   288      // preconverting to NodeList
       
   289      // TODO: break out for IE only
       
   290     'elements': {
       
   291         getter: function() {
       
   292             return Y.all(this._node.elements);
       
   293         }
       
   294     },
       
   295 
       
   296     /**
       
   297      * Returns a NodeList instance of all HTMLElement children.
       
   298      * @readOnly
       
   299      * @config children
       
   300      * @type NodeList
       
   301      */
       
   302     'children': {
       
   303         getter: function() {
       
   304             var node = this._node,
       
   305                 children = node.children,
       
   306                 childNodes, i, len;
       
   307 
       
   308             if (!children) {
       
   309                 childNodes = node.childNodes;
       
   310                 children = [];
       
   311 
       
   312                 for (i = 0, len = childNodes.length; i < len; ++i) {
       
   313                     if (childNodes[i][TAG_NAME]) {
       
   314                         children[children.length] = childNodes[i];
       
   315                     }
       
   316                 }
       
   317             }
       
   318             return Y.all(children);
       
   319         }
       
   320     },
       
   321 
       
   322     value: {
       
   323         getter: function() {
       
   324             return Y.DOM.getValue(this._node);
       
   325         },
       
   326 
       
   327         setter: function(val) {
       
   328             Y.DOM.setValue(this._node, val);
       
   329             return val;
       
   330         }
       
   331     },
       
   332 
       
   333     data: {
       
   334         getter: function() {
       
   335             return this._data;
       
   336         },
       
   337 
       
   338         setter: function(val) {
       
   339             this._data = val;
       
   340             return val;
       
   341         }
       
   342     }
       
   343 };
       
   344 
       
   345 // call with instance context
       
   346 Node.DEFAULT_SETTER = function(name, val) {
       
   347     var node = this._stateProxy,
       
   348         strPath;
       
   349 
       
   350     if (name.indexOf(DOT) > -1) {
       
   351         strPath = name;
       
   352         name = name.split(DOT);
       
   353         // only allow when defined on node
       
   354         Y.Object.setValue(node, name, val);
       
   355     } else if (node[name] !== undefined) { // pass thru DOM properties 
       
   356         node[name] = val;
       
   357     }
       
   358 
       
   359     return val;
       
   360 };
       
   361 
       
   362 // call with instance context
       
   363 Node.DEFAULT_GETTER = function(name) {
       
   364     var node = this._stateProxy,
       
   365         val;
       
   366 
       
   367     if (name.indexOf && name.indexOf(DOT) > -1) {
       
   368         val = Y.Object.getValue(node, name.split(DOT));
       
   369     } else if (node[name] !== undefined) { // pass thru from DOM
       
   370         val = node[name];
       
   371     }
       
   372 
       
   373     return val;
       
   374 };
       
   375 
       
   376 Y.augment(Node, Y.Event.Target);
       
   377 
       
   378 Y.mix(Node.prototype, {
       
   379     toString: function() {
       
   380         var str = '',
       
   381             errorMsg = this[UID] + ': not bound to a node',
       
   382             node = this._node;
       
   383 
       
   384         if (node) {
       
   385             str += node[NODE_NAME];
       
   386             if (node.id) {
       
   387                 str += '#' + node.id; 
       
   388             }
       
   389 
       
   390             if (node.className) {
       
   391                 str += '.' + node.className.replace(' ', '.'); 
       
   392             }
       
   393 
       
   394             // TODO: add yuid?
       
   395             str += ' ' + this[UID];
       
   396         }
       
   397         return str || errorMsg;
       
   398     },
       
   399 
       
   400     /**
       
   401      * Returns an attribute value on the Node instance
       
   402      * @method get
       
   403      * @param {String} attr The attribute to be set
       
   404      * @return {any} The current value of the attribute
       
   405      */
       
   406     get: function(attr) {
       
   407         var val;
       
   408 
       
   409         if (this._getAttr) { // use Attribute imple
       
   410             val = this._getAttr(attr);
       
   411         } else {
       
   412             val = this._get(attr);
       
   413         }
       
   414 
       
   415         if (val) {
       
   416             val = Y.Node.scrubVal(val, this);
       
   417         }
       
   418         return val;
       
   419     },
       
   420 
       
   421     _get: function(attr) {
       
   422         var attrConfig = Node.ATTRS[attr],
       
   423             val;
       
   424 
       
   425         if (attrConfig && attrConfig.getter) {
       
   426             val = attrConfig.getter.call(this);
       
   427         } else if (Node.re_aria.test(attr)) {
       
   428             val = this._node.getAttribute(attr, 2); 
       
   429         } else {
       
   430             val = Node.DEFAULT_GETTER.apply(this, arguments);
       
   431         }
       
   432 
       
   433         return val;
       
   434     },
       
   435 
       
   436     /**
       
   437      * Sets an attribute on the Node instance.
       
   438      * @method set
       
   439      * @param {String} attr The attribute to be set.  
       
   440      * @param {any} val The value to set the attribute to.  
       
   441      * @chainable
       
   442      */
       
   443     set: function(attr, val) {
       
   444         var attrConfig = Node.ATTRS[attr];
       
   445 
       
   446         if (this._setAttr) { // use Attribute imple
       
   447             this._setAttr.apply(this, arguments);
       
   448         } else { // use setters inline
       
   449             if (attrConfig && attrConfig.setter) {
       
   450                 attrConfig.setter.call(this, val);
       
   451             } else if (Node.re_aria.test(attr)) { // special case Aria
       
   452                 this._node.setAttribute(attr, val);
       
   453             } else {
       
   454                 Node.DEFAULT_SETTER.apply(this, arguments);
       
   455             }
       
   456         }
       
   457 
       
   458         return this;
       
   459     },
       
   460 
       
   461     /**
       
   462      * Sets multiple attributes. 
       
   463      * @method setAttrs
       
   464      * @param {Object} attrMap an object of name/value pairs to set  
       
   465      * @chainable
       
   466      */
       
   467     setAttrs: function(attrMap) {
       
   468         if (this._setAttrs) { // use Attribute imple
       
   469             this._setAttrs(attrMap);
       
   470         } else { // use setters inline
       
   471             Y.Object.each(attrMap, function(v, n) {
       
   472                 this.set(n, v); 
       
   473             }, this);
       
   474         }
       
   475 
       
   476         return this;
       
   477     },
       
   478 
       
   479     /**
       
   480      * Returns an object containing the values for the requested attributes. 
       
   481      * @method getAttrs
       
   482      * @param {Array} attrs an array of attributes to get values  
       
   483      * @return {Object} An object with attribute name/value pairs.
       
   484      */
       
   485     getAttrs: function(attrs) {
       
   486         var ret = {};
       
   487         if (this._getAttrs) { // use Attribute imple
       
   488             this._getAttrs(attrs);
       
   489         } else { // use setters inline
       
   490             Y.Array.each(attrs, function(v, n) {
       
   491                 ret[v] = this.get(v); 
       
   492             }, this);
       
   493         }
       
   494 
       
   495         return ret;
       
   496     },
       
   497 
       
   498     /**
       
   499      * Creates a new Node using the provided markup string. 
       
   500      * @method create
       
   501      * @param {String} html The markup used to create the element
       
   502      * @param {HTMLDocument} doc An optional document context 
       
   503      * @return {Node} A Node instance bound to a DOM node or fragment 
       
   504      */
       
   505     create: Node.create,
       
   506 
       
   507     /**
       
   508      * Compares nodes to determine if they match.
       
   509      * Node instances can be compared to each other and/or HTMLElements.
       
   510      * @method compareTo
       
   511      * @param {HTMLElement | Node} refNode The reference node to compare to the node.
       
   512      * @return {Boolean} True if the nodes match, false if they do not. 
       
   513      */
       
   514     compareTo: function(refNode) {
       
   515         var node = this._node;
       
   516         if (refNode instanceof Y.Node) { 
       
   517             refNode = refNode._node;
       
   518         }
       
   519         return node === refNode;
       
   520     },
       
   521 
       
   522     /**
       
   523      * Determines whether the node is appended to the document.
       
   524      * @method inDoc
       
   525      * @param {Node|HTMLElement} doc optional An optional document to check against.
       
   526      * Defaults to current document. 
       
   527      * @return {Boolean} Whether or not this node is appended to the document. 
       
   528      */
       
   529     inDoc: function(doc) {
       
   530         var node = this._node;
       
   531         doc = (doc) ? doc._node || doc : node[OWNER_DOCUMENT];
       
   532         if (doc.documentElement) {
       
   533             return Y.DOM.contains(doc.documentElement, node);
       
   534         }
       
   535     },
       
   536 
       
   537     getById: function(id) {
       
   538         var node = this._node,
       
   539             ret = Y.DOM.byId(id, node[OWNER_DOCUMENT]);
       
   540         if (ret && Y.DOM.contains(node, ret)) {
       
   541             ret = Y.one(ret);
       
   542         } else {
       
   543             ret = null;
       
   544         }
       
   545         return ret;
       
   546     },
       
   547 
       
   548    /**
       
   549      * Returns the nearest ancestor that passes the test applied by supplied boolean method.
       
   550      * @method ancestor
       
   551      * @param {String | Function} fn A selector string or boolean method for testing elements.
       
   552      * If a function is used, it receives the current node being tested as the only argument.
       
   553      * @return {Node} The matching Node instance or null if not found
       
   554      */
       
   555     ancestor: function(fn) {
       
   556         return Node.get(Y.DOM.elementByAxis(this._node, 'parentNode', _wrapFn(fn)));
       
   557     },
       
   558 
       
   559     /**
       
   560      * Returns the previous matching sibling. 
       
   561      * Returns the nearest element node sibling if no method provided.
       
   562      * @method previous
       
   563      * @param {String | Function} fn A selector or boolean method for testing elements.
       
   564      * If a function is used, it receives the current node being tested as the only argument.
       
   565      * @return {Node} Node instance or null if not found
       
   566      */
       
   567     previous: function(fn, all) {
       
   568         return Node.get(Y.DOM.elementByAxis(this._node, 'previousSibling', _wrapFn(fn), all));
       
   569     }, 
       
   570 
       
   571     /**
       
   572      * Returns the next matching sibling. 
       
   573      * Returns the nearest element node sibling if no method provided.
       
   574      * @method next
       
   575      * @param {String | Function} fn A selector or boolean method for testing elements.
       
   576      * If a function is used, it receives the current node being tested as the only argument.
       
   577      * @return {Node} Node instance or null if not found
       
   578      */
       
   579     next: function(node, fn, all) {
       
   580         return Node.get(Y.DOM.elementByAxis(this._node, 'nextSibling', _wrapFn(fn), all));
       
   581     },
       
   582         
       
   583     /**
       
   584      * Retrieves a Node instance of nodes based on the given CSS selector. 
       
   585      * @method one
       
   586      *
       
   587      * @param {string} selector The CSS selector to test against.
       
   588      * @return {Node} A Node instance for the matching HTMLElement.
       
   589      */
       
   590     one: function(selector) {
       
   591         return Y.one(Y.Selector.query(selector, this._node, true));
       
   592     },
       
   593 
       
   594     /**
       
   595      * Retrieves a Node instance of nodes based on the given CSS selector. 
       
   596      * @method query
       
   597      * @deprecated Use one()
       
   598      * @param {string} selector The CSS selector to test against.
       
   599      * @return {Node} A Node instance for the matching HTMLElement.
       
   600      */
       
   601     query: function(selector) {
       
   602         Y.log('query() is deprecated, use one()', 'warn', 'deprecated');
       
   603         return this.one(selector);
       
   604     },
       
   605 
       
   606     /**
       
   607      * Retrieves a nodeList based on the given CSS selector. 
       
   608      * @method all
       
   609      *
       
   610      * @param {string} selector The CSS selector to test against.
       
   611      * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
       
   612      */
       
   613     all: function(selector) {
       
   614         var nodelist = Y.all(Y.Selector.query(selector, this._node));
       
   615         nodelist._query = selector;
       
   616         return nodelist;
       
   617     },
       
   618 
       
   619     /**
       
   620      * Retrieves a nodeList based on the given CSS selector. 
       
   621      * @method queryAll
       
   622      * @deprecated Use all()
       
   623      * @param {string} selector The CSS selector to test against.
       
   624      * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
       
   625      */
       
   626     queryAll: function(selector) {
       
   627         Y.log('queryAll() is deprecated, use all()', 'warn', 'deprecated');
       
   628         return this.all(selector);
       
   629     },
       
   630 
       
   631     // TODO: allow fn test
       
   632     /**
       
   633      * Test if the supplied node matches the supplied selector.
       
   634      * @method test
       
   635      *
       
   636      * @param {string} selector The CSS selector to test against.
       
   637      * @return {boolean} Whether or not the node matches the selector.
       
   638      */
       
   639     test: function(selector) {
       
   640         return Y.Selector.test(this._node, selector);
       
   641     },
       
   642 
       
   643     /**
       
   644      * Removes the node from its parent.
       
   645      * Shortcut for myNode.get('parentNode').removeChild(myNode);
       
   646      * @method remove
       
   647      * @chainable
       
   648      *
       
   649      */
       
   650     remove: function(destroy) {
       
   651         var node = this._node;
       
   652         node.parentNode.removeChild(node);
       
   653         if (destroy) {
       
   654             this.destroy(true);
       
   655         }
       
   656         return this;
       
   657     },
       
   658 
       
   659     /**
       
   660      * Replace the node with the other node. This is a DOM update only
       
   661      * and does not change the node bound to the Node instance.
       
   662      * Shortcut for myNode.get('parentNode').replaceChild(newNode, myNode);
       
   663      * @method replace
       
   664      * @chainable
       
   665      *
       
   666      */
       
   667     replace: function(newNode) {
       
   668         var node = this._node;
       
   669         node.parentNode.replaceChild(newNode, node);
       
   670         return this;
       
   671     },
       
   672 
       
   673     purge: function(recurse, type) {
       
   674         Y.Event.purgeElement(this._node, recurse, type);
       
   675     },
       
   676 
       
   677     destroy: function(purge) {
       
   678         delete Node._instances[this[UID]];
       
   679         if (purge) {
       
   680             this.purge(true);
       
   681         }
       
   682 
       
   683         if (this.unplug) {
       
   684             this.unplug();
       
   685         }
       
   686 
       
   687         this._node._yuid = null;
       
   688         this._node = null;
       
   689         this._stateProxy = null;
       
   690     },
       
   691 
       
   692     /**
       
   693      * Invokes a method on the Node instance 
       
   694      * @method invoke
       
   695      * @param {String} method The name of the method to invoke
       
   696      * @param {Any}  a, b, c, etc. Arguments to invoke the method with. 
       
   697      * @return Whatever the underly method returns. 
       
   698      * DOM Nodes and Collections return values
       
   699      * are converted to Node/NodeList instances.
       
   700      *
       
   701      */
       
   702     invoke: function(method, a, b, c, d, e) {
       
   703         var node = this._node,
       
   704             ret;
       
   705 
       
   706         if (a && a instanceof Y.Node) {
       
   707             a = a._node;
       
   708         }
       
   709 
       
   710         if (b && b instanceof Y.Node) {
       
   711             b = b._node;
       
   712         }
       
   713 
       
   714         ret = node[method](a, b, c, d, e);    
       
   715         return Y.Node.scrubVal(ret, this);
       
   716     },
       
   717 
       
   718     /**
       
   719      * Applies the given function to each Node in the NodeList.
       
   720      * @method each
       
   721      * @deprecated Use NodeList
       
   722      * @param {Function} fn The function to apply 
       
   723      * @param {Object} context optional An optional context to apply the function with
       
   724      * Default context is the NodeList instance
       
   725      * @chainable
       
   726      */
       
   727     each: function(fn, context) {
       
   728         context = context || this;
       
   729         Y.log('each is deprecated on Node', 'warn', 'deprecated');
       
   730         return fn.call(context, this);
       
   731     },
       
   732 
       
   733     /**
       
   734      * Retrieves the Node instance at the given index. 
       
   735      * @method item
       
   736      * @deprecated Use NodeList
       
   737      *
       
   738      * @param {Number} index The index of the target Node.
       
   739      * @return {Node} The Node instance at the given index.
       
   740      */
       
   741     item: function(index) {
       
   742         Y.log('item is deprecated on Node', 'warn', 'deprecated');
       
   743         return this;
       
   744     },
       
   745 
       
   746     /**
       
   747      * Returns the current number of items in the Node.
       
   748      * @method size
       
   749      * @deprecated Use NodeList
       
   750      * @return {Int} The number of items in the Node. 
       
   751      */
       
   752     size: function() {
       
   753         Y.log('size is deprecated on Node', 'warn', 'deprecated');
       
   754         return this._node ? 1 : 0;
       
   755     },
       
   756 
       
   757     /**
       
   758      * Inserts the content before the reference node. 
       
   759      * @method insert
       
   760      * @param {String | Y.Node | HTMLElement} content The content to insert 
       
   761      * @param {Int | Y.Node | HTMLElement | String} where The position to insert at.
       
   762      * @chainable
       
   763      */
       
   764     insert: function(content, where) {
       
   765         var node = this._node;
       
   766 
       
   767         if (content) {
       
   768             if (typeof where === 'number') { // allow index
       
   769                 where = this._node.childNodes[where];
       
   770             }
       
   771 
       
   772             if (typeof content !== 'string') { // allow Node or NodeList/Array instances
       
   773                 if (content._node) { // Node
       
   774                     content = content._node;
       
   775                 } else if (content._nodes || (!content.nodeType && content.length)) { // NodeList or Array
       
   776                     Y.each(content._nodes, function(n) {
       
   777                         Y.DOM.addHTML(node, n, where);
       
   778                     });
       
   779 
       
   780                     return this; // NOTE: early return
       
   781                 }
       
   782             }
       
   783             Y.DOM.addHTML(node, content, where);
       
   784         }
       
   785         return this;
       
   786     },
       
   787 
       
   788     /**
       
   789      * Inserts the content as the firstChild of the node. 
       
   790      * @method prepend
       
   791      * @param {String | Y.Node | HTMLElement} content The content to insert 
       
   792      * @chainable
       
   793      */
       
   794     prepend: function(content) {
       
   795         return this.insert(content, 0);
       
   796     },
       
   797 
       
   798     /**
       
   799      * Inserts the content as the lastChild of the node. 
       
   800      * @method append
       
   801      * @param {String | Y.Node | HTMLElement} content The content to insert 
       
   802      * @chainable
       
   803      */
       
   804     append: function(content) {
       
   805         return this.insert(content, null);
       
   806     },
       
   807 
       
   808     /**
       
   809      * Replaces the node's current content with the content.
       
   810      * @method setContent
       
   811      * @param {String | Y.Node | HTMLElement} content The content to insert 
       
   812      * @chainable
       
   813      */
       
   814     setContent: function(content) {
       
   815         Y.DOM.addHTML(this._node, content, 'replace');
       
   816         return this;
       
   817     },
       
   818 
       
   819     // TODO: need this?
       
   820     hasMethod: function(method) {
       
   821         var node = this._node;
       
   822         return (node && (typeof node === 'function'));
       
   823     }
       
   824 }, true);
       
   825 
       
   826 Y.Node = Node;
       
   827 Y.get = Y.Node.get;
       
   828 Y.one = Y.Node.one;
       
   829 /**
       
   830  * The NodeList module provides support for managing collections of Nodes.
       
   831  * @module node
       
   832  * @submodule nodelist
       
   833  */    
       
   834 
       
   835 /**
       
   836  * The NodeList class provides a wrapper for manipulating DOM NodeLists.
       
   837  * NodeList properties can be accessed via the set/get methods.
       
   838  * Use Y.all() to retrieve NodeList instances.
       
   839  *
       
   840  * @class NodeList
       
   841  * @constructor
       
   842  */
       
   843 
       
   844 var NodeList = function(nodes) {
       
   845     if (typeof nodes === 'string') {
       
   846         this._query = nodes;
       
   847         nodes = Y.Selector.query(nodes);
       
   848     } else {
       
   849         nodes = Y.Array(nodes, 0, true);
       
   850     }
       
   851 
       
   852     NodeList._instances[Y.stamp(this)] = this;
       
   853     this._nodes = nodes;
       
   854 };
       
   855 // end "globals"
       
   856 
       
   857 NodeList.NAME = 'NodeList';
       
   858 
       
   859 /**
       
   860  * Retrieves the DOM nodes bound to a NodeList instance
       
   861  * @method NodeList.getDOMNodes
       
   862  * @static
       
   863  *
       
   864  * @param {Y.NodeList} node The NodeList instance
       
   865  * @return {Array} The array of DOM nodes bound to the NodeList
       
   866  */
       
   867 NodeList.getDOMNodes = function(nodeList) {
       
   868     return nodeList._nodes;
       
   869 };
       
   870 
       
   871 NodeList._instances = [];
       
   872 
       
   873 NodeList.each = function(instance, fn, context) {
       
   874     var nodes = instance._nodes;
       
   875     if (nodes && nodes.length) {
       
   876         Y.Array.each(nodes, fn, context || instance);
       
   877     } else {
       
   878         Y.log('no nodes bound to ' + this, 'warn', 'NodeList');
       
   879     }
       
   880 };
       
   881 
       
   882 NodeList.addMethod = function(name, fn, context) {
       
   883     if (name && fn) {
       
   884         NodeList.prototype[name] = function() {
       
   885             var ret = [],
       
   886                 args = arguments;
       
   887 
       
   888             Y.Array.each(this._nodes, function(node) {
       
   889                 var UID = '_yuid',
       
   890                     instance = Y.Node._instances[node[UID]],
       
   891                     ctx,
       
   892                     result;
       
   893 
       
   894                 if (!instance) {
       
   895                     instance = NodeList._getTempNode(node);
       
   896                 }
       
   897                 ctx = context || instance;
       
   898                 result = fn.apply(ctx, args);
       
   899                 if (result !== undefined && result !== instance) {
       
   900                     ret[ret.length] = result;
       
   901                 }
       
   902             });
       
   903 
       
   904             // TODO: remove tmp pointer
       
   905             return ret.length ? ret : this;
       
   906         };
       
   907     } else {
       
   908         Y.log('unable to add method: ' + name, 'warn', 'Node');
       
   909     }
       
   910 };
       
   911 
       
   912 NodeList.importMethod = function(host, name, altName) {
       
   913     if (typeof name === 'string') {
       
   914         altName = altName || name;
       
   915         NodeList.addMethod(name, host[name]);
       
   916     } else {
       
   917         Y.each(name, function(n) {
       
   918             NodeList.importMethod(host, n);
       
   919         });
       
   920     }
       
   921 };
       
   922 
       
   923 NodeList._getTempNode = function(node) {
       
   924     var tmp = NodeList._tempNode;
       
   925     if (!tmp) {
       
   926         tmp = Y.Node.create('<div></div>');
       
   927         NodeList._tempNode = tmp;
       
   928     }
       
   929 
       
   930     tmp._node = node;
       
   931     tmp._stateProxy = node;
       
   932     return tmp;
       
   933 };
       
   934 
       
   935 Y.mix(NodeList.prototype, {
       
   936     /**
       
   937      * Retrieves the Node instance at the given index. 
       
   938      * @method item
       
   939      *
       
   940      * @param {Number} index The index of the target Node.
       
   941      * @return {Node} The Node instance at the given index.
       
   942      */
       
   943     item: function(index) {
       
   944         return Y.one((this._nodes || [])[index]);
       
   945     },
       
   946 
       
   947     /**
       
   948      * Applies the given function to each Node in the NodeList.
       
   949      * @method each
       
   950      * @param {Function} fn The function to apply. It receives 3 arguments:
       
   951      * the current node instance, the node's index, and the NodeList instance
       
   952      * @param {Object} context optional An optional context to apply the function with
       
   953      * Default context is the current Node instance
       
   954      * @chainable
       
   955      */
       
   956     each: function(fn, context) {
       
   957         var instance = this;
       
   958         Y.Array.each(this._nodes, function(node, index) {
       
   959             node = Y.one(node);
       
   960             return fn.call(context || node, node, index, instance);
       
   961         });
       
   962         return instance;
       
   963     },
       
   964 
       
   965     batch: function(fn, context) {
       
   966         var nodelist = this;
       
   967 
       
   968         Y.Array.each(this._nodes, function(node, index) {
       
   969             var instance = Y.Node._instances[node[UID]];
       
   970             if (!instance) {
       
   971                 instance = NodeList._getTempNode(node);
       
   972             }
       
   973 
       
   974             return fn.call(context || instance, instance, index, nodelist);
       
   975         });
       
   976         return nodelist;
       
   977     },
       
   978 
       
   979     /**
       
   980      * Executes the function once for each node until a true value is returned.
       
   981      * @method some
       
   982      * @param {Function} fn The function to apply. It receives 3 arguments:
       
   983      * the current node instance, the node's index, and the NodeList instance
       
   984      * @param {Object} context optional An optional context to execute the function from.
       
   985      * Default context is the current Node instance
       
   986      * @return {Boolean} Whether or not the function returned true for any node.
       
   987      */
       
   988     some: function(fn, context) {
       
   989         var instance = this;
       
   990         return Y.Array.some(this._nodes, function(node, index) {
       
   991             node = Y.one(node);
       
   992             context = context || node;
       
   993             return fn.call(context, node, index, instance);
       
   994         });
       
   995     },
       
   996 
       
   997     /**
       
   998      * Creates a documenFragment from the nodes bound to the NodeList instance 
       
   999      * @method toDocFrag
       
  1000      * @return Node a Node instance bound to the documentFragment
       
  1001      */
       
  1002     toFrag: function() {
       
  1003         return Y.one(Y.DOM._nl2frag(this._nodes));
       
  1004     },
       
  1005 
       
  1006     /**
       
  1007      * Returns the index of the node in the NodeList instance
       
  1008      * or -1 if the node isn't found.
       
  1009      * @method indexOf
       
  1010      * @param {Y.Node || DOMNode} node the node to search for
       
  1011      * @return {Int} the index of the node value or -1 if not found
       
  1012      */
       
  1013     indexOf: function(node) {
       
  1014         return Y.Array.indexOf(this._nodes, Y.Node.getDOMNode(node));
       
  1015     },
       
  1016 
       
  1017     /**
       
  1018      * Filters the NodeList instance down to only nodes matching the given selector.
       
  1019      * @method filter
       
  1020      * @param {String} selector The selector to filter against
       
  1021      * @return {NodeList} NodeList containing the updated collection 
       
  1022      * @see Selector
       
  1023      */
       
  1024     filter: function(selector) {
       
  1025         return Y.all(Y.Selector.filter(this._nodes, selector));
       
  1026     },
       
  1027 
       
  1028 
       
  1029     /**
       
  1030      * Creates a new NodeList containing all nodes at every n indices, where 
       
  1031      * remainder n % index equals r.
       
  1032      * (zero-based index).
       
  1033      * @method modulus
       
  1034      * @param {Int} n The offset to use (return every nth node)
       
  1035      * @param {Int} r An optional remainder to use with the modulus operation (defaults to zero) 
       
  1036      * @return {NodeList} NodeList containing the updated collection 
       
  1037      */
       
  1038     modulus: function(n, r) {
       
  1039         r = r || 0;
       
  1040         var nodes = [];
       
  1041         NodeList.each(this, function(node, i) {
       
  1042             if (i % n === r) {
       
  1043                 nodes.push(node);
       
  1044             }
       
  1045         });
       
  1046 
       
  1047         return Y.all(nodes);
       
  1048     },
       
  1049 
       
  1050     /**
       
  1051      * Creates a new NodeList containing all nodes at odd indices
       
  1052      * (zero-based index).
       
  1053      * @method odd
       
  1054      * @return {NodeList} NodeList containing the updated collection 
       
  1055      */
       
  1056     odd: function() {
       
  1057         return this.modulus(2, 1);
       
  1058     },
       
  1059 
       
  1060     /**
       
  1061      * Creates a new NodeList containing all nodes at even indices
       
  1062      * (zero-based index), including zero. 
       
  1063      * @method even
       
  1064      * @return {NodeList} NodeList containing the updated collection 
       
  1065      */
       
  1066     even: function() {
       
  1067         return this.modulus(2);
       
  1068     },
       
  1069 
       
  1070     destructor: function() {
       
  1071         delete NodeList._instances[this[UID]];
       
  1072     },
       
  1073 
       
  1074     /**
       
  1075      * Reruns the initial query, when created using a selector query 
       
  1076      * @method refresh
       
  1077      * @chainable
       
  1078      */
       
  1079     refresh: function() {
       
  1080         var doc,
       
  1081             nodes = this._nodes;
       
  1082         if (this._query) {
       
  1083             if (nodes && nodes[0] && nodes[0].ownerDocument) {
       
  1084                 doc = nodes[0].ownerDocument;
       
  1085             }
       
  1086 
       
  1087             this._nodes = Y.Selector.query(this._query, doc || Y.config.doc);        
       
  1088         }
       
  1089 
       
  1090         return this;
       
  1091     },
       
  1092 
       
  1093     /**
       
  1094      * Applies an event listener to each Node bound to the NodeList. 
       
  1095      * @method on
       
  1096      * @param {String} type The event being listened for
       
  1097      * @param {Function} fn The handler to call when the event fires
       
  1098      * @param {Object} context The context to call the handler with.
       
  1099      * Default is the NodeList instance. 
       
  1100      * @return {Object} Returns an event handle that can later be use to detach(). 
       
  1101      * @see Event.on
       
  1102      */
       
  1103     on: function(type, fn, context) {
       
  1104         var args = Y.Array(arguments, 0, true);
       
  1105         args.splice(2, 0, this._nodes);
       
  1106         args[3] = context || this;
       
  1107         return Y.on.apply(Y, args);
       
  1108     },
       
  1109 
       
  1110     /**
       
  1111      * Applies an event listener to each Node bound to the NodeList. 
       
  1112      * The handler is called only after all on() handlers are called
       
  1113      * and the event is not prevented.
       
  1114      * @method after
       
  1115      * @param {String} type The event being listened for
       
  1116      * @param {Function} fn The handler to call when the event fires
       
  1117      * @param {Object} context The context to call the handler with.
       
  1118      * Default is the NodeList instance. 
       
  1119      * @return {Object} Returns an event handle that can later be use to detach(). 
       
  1120      * @see Event.on
       
  1121      */
       
  1122     after: function(type, fn, context) {
       
  1123         var args = Y.Array(arguments, 0, true);
       
  1124         args.splice(2, 0, this._nodes);
       
  1125         args[3] = context || this;
       
  1126         return Y.after.apply(Y, args);
       
  1127     },
       
  1128 
       
  1129     /**
       
  1130      * Returns the current number of items in the NodeList.
       
  1131      * @method size
       
  1132      * @return {Int} The number of items in the NodeList. 
       
  1133      */
       
  1134     size: function() {
       
  1135         return this._nodes.length;
       
  1136     },
       
  1137 
       
  1138     toString: function() {
       
  1139         var str = '',
       
  1140             errorMsg = this[UID] + ': not bound to any nodes',
       
  1141             nodes = this._nodes,
       
  1142             node;
       
  1143 
       
  1144         if (nodes && nodes[0]) {
       
  1145             node = nodes[0];
       
  1146             str += node[NODE_NAME];
       
  1147             if (node.id) {
       
  1148                 str += '#' + node.id; 
       
  1149             }
       
  1150 
       
  1151             if (node.className) {
       
  1152                 str += '.' + node.className.replace(' ', '.'); 
       
  1153             }
       
  1154 
       
  1155             if (nodes.length > 1) {
       
  1156                 str += '...[' + nodes.length + ' items]';
       
  1157             }
       
  1158         }
       
  1159         return str || errorMsg;
       
  1160     }
       
  1161 
       
  1162 }, true);
       
  1163 
       
  1164 NodeList.importMethod(Y.Node.prototype, [
       
  1165     /**
       
  1166      * Called on each Node instance
       
  1167      * @for NodeList
       
  1168      * @method append
       
  1169      * @see Node.append
       
  1170      */
       
  1171     'append',
       
  1172 
       
  1173     /**
       
  1174       * Called on each Node instance
       
  1175       * @method detach
       
  1176       * @see Node.detach
       
  1177       */
       
  1178     'detach',
       
  1179     
       
  1180     /** Called on each Node instance
       
  1181       * @method detachAll
       
  1182       * @see Node.detachAll
       
  1183       */
       
  1184     'detachAll',
       
  1185 
       
  1186     /** Called on each Node instance
       
  1187       * @method insert
       
  1188       * @see NodeInsert
       
  1189       */
       
  1190     'insert',
       
  1191 
       
  1192     /** Called on each Node instance
       
  1193       * @method prepend
       
  1194       * @see Node.prepend
       
  1195       */
       
  1196     'prepend',
       
  1197 
       
  1198     /** Called on each Node instance
       
  1199       * @method remove
       
  1200       * @see Node.remove
       
  1201       */
       
  1202     'remove',
       
  1203 
       
  1204     /** Called on each Node instance
       
  1205       * @method set
       
  1206       * @see Node.set
       
  1207       */
       
  1208     'set',
       
  1209 
       
  1210     /** Called on each Node instance
       
  1211       * @method setContent
       
  1212       * @see Node.setContent
       
  1213       */
       
  1214     'setContent'
       
  1215 ]);
       
  1216 
       
  1217 // one-off implementation to convert array of Nodes to NodeList
       
  1218 // e.g. Y.all('input').get('parentNode');
       
  1219 
       
  1220 /** Called on each Node instance
       
  1221   * @method get
       
  1222   * @see Node
       
  1223   */
       
  1224 NodeList.prototype.get = function(attr) {
       
  1225     var ret = [],
       
  1226         nodes = this._nodes,
       
  1227         isNodeList = false,
       
  1228         getTemp = NodeList._getTempNode,
       
  1229         instance,
       
  1230         val;
       
  1231 
       
  1232     if (nodes[0]) {
       
  1233         instance = Y.Node._instances[nodes[0]._yuid] || getTemp(nodes[0]);
       
  1234         val = instance._get(attr);
       
  1235         if (val && val.nodeType) {
       
  1236             isNodeList = true;
       
  1237         }
       
  1238     }
       
  1239 
       
  1240     Y.Array.each(nodes, function(node) {
       
  1241         instance = Y.Node._instances[node._yuid];
       
  1242 
       
  1243         if (!instance) {
       
  1244             instance = getTemp(node);
       
  1245         }
       
  1246 
       
  1247         val = instance._get(attr);
       
  1248         if (!isNodeList) { // convert array of Nodes to NodeList
       
  1249             val = Y.Node.scrubVal(val, instance);
       
  1250         }
       
  1251 
       
  1252         ret.push(val);
       
  1253     });
       
  1254 
       
  1255     return (isNodeList) ? Y.all(ret) : ret;
       
  1256 };
       
  1257 
       
  1258 Y.NodeList = NodeList;
       
  1259 
       
  1260 Y.all = function(nodes) {
       
  1261     return new NodeList(nodes);
       
  1262 };
       
  1263 
       
  1264 Y.Node.all = Y.all;
       
  1265 Y.Array.each([
       
  1266     /**
       
  1267      * Passes through to DOM method.
       
  1268      * @method replaceChild
       
  1269      * @for Node
       
  1270      * @param {HTMLElement | Node} node Node to be inserted 
       
  1271      * @param {HTMLElement | Node} refNode Node to be replaced 
       
  1272      * @return {Node} The replaced node 
       
  1273      */
       
  1274     'replaceChild',
       
  1275 
       
  1276     /**
       
  1277      * Passes through to DOM method.
       
  1278      * @method appendChild
       
  1279      * @param {HTMLElement | Node} node Node to be appended 
       
  1280      * @return {Node} The appended node 
       
  1281      */
       
  1282     'appendChild',
       
  1283 
       
  1284     /**
       
  1285      * Passes through to DOM method.
       
  1286      * @method insertBefore
       
  1287      * @param {HTMLElement | Node} newNode Node to be appended 
       
  1288      * @param {HTMLElement | Node} refNode Node to be inserted before 
       
  1289      * @return {Node} The inserted node 
       
  1290      */
       
  1291     'insertBefore',
       
  1292 
       
  1293     /**
       
  1294      * Passes through to DOM method.
       
  1295      * @method removeChild
       
  1296      * @param {HTMLElement | Node} node Node to be removed 
       
  1297      * @return {Node} The removed node 
       
  1298      */
       
  1299     'removeChild',
       
  1300 
       
  1301     /**
       
  1302      * Passes through to DOM method.
       
  1303      * @method hasChildNodes
       
  1304      * @return {Boolean} Whether or not the node has any childNodes 
       
  1305      */
       
  1306     'hasChildNodes',
       
  1307 
       
  1308     /**
       
  1309      * Passes through to DOM method.
       
  1310      * @method cloneNode
       
  1311      * @param {Boolean} deep Whether or not to perform a deep clone, which includes
       
  1312      * subtree and attributes
       
  1313      * @return {Node} The clone 
       
  1314      */
       
  1315     'cloneNode',
       
  1316 
       
  1317     /**
       
  1318      * Passes through to DOM method.
       
  1319      * @method hasAttribute
       
  1320      * @param {String} attribute The attribute to test for 
       
  1321      * @return {Boolean} Whether or not the attribute is present 
       
  1322      */
       
  1323     'hasAttribute',
       
  1324 
       
  1325     /**
       
  1326      * Passes through to DOM method.
       
  1327      * @method removeAttribute
       
  1328      * @param {String} attribute The attribute to be removed 
       
  1329      * @chainable
       
  1330      */
       
  1331     'removeAttribute',
       
  1332 
       
  1333     /**
       
  1334      * Passes through to DOM method.
       
  1335      * @method scrollIntoView
       
  1336      * @chainable
       
  1337      */
       
  1338     'scrollIntoView',
       
  1339 
       
  1340     /**
       
  1341      * Passes through to DOM method.
       
  1342      * @method getElementsByTagName
       
  1343      * @param {String} tagName The tagName to collect 
       
  1344      * @return {NodeList} A NodeList representing the HTMLCollection
       
  1345      */
       
  1346     'getElementsByTagName',
       
  1347 
       
  1348     /**
       
  1349      * Passes through to DOM method.
       
  1350      * @method focus
       
  1351      * @chainable
       
  1352      */
       
  1353     'focus',
       
  1354 
       
  1355     /**
       
  1356      * Passes through to DOM method.
       
  1357      * @method blur
       
  1358      * @chainable
       
  1359      */
       
  1360     'blur',
       
  1361 
       
  1362     /**
       
  1363      * Passes through to DOM method.
       
  1364      * Only valid on FORM elements
       
  1365      * @method submit
       
  1366      * @chainable
       
  1367      */
       
  1368     'submit',
       
  1369 
       
  1370     /**
       
  1371      * Passes through to DOM method.
       
  1372      * Only valid on FORM elements
       
  1373      * @method reset
       
  1374      * @chainable
       
  1375      */
       
  1376     'reset',
       
  1377 
       
  1378     /**
       
  1379      * Passes through to DOM method.
       
  1380      * @method select
       
  1381      * @chainable
       
  1382      */
       
  1383      'select'
       
  1384 ], function(method) {
       
  1385     Y.Node.prototype[method] = function(arg1, arg2, arg3) {
       
  1386         var ret = this.invoke(method, arg1, arg2, arg3);
       
  1387         return ret;
       
  1388     };
       
  1389 });
       
  1390 
       
  1391 Node.importMethod(Y.DOM, [
       
  1392     /**
       
  1393      * Determines whether the ndoe is an ancestor of another HTML element in the DOM hierarchy.
       
  1394      * @method contains
       
  1395      * @param {Node | HTMLElement} needle The possible node or descendent
       
  1396      * @return {Boolean} Whether or not this node is the needle its ancestor
       
  1397      */
       
  1398     'contains',
       
  1399     /**
       
  1400      * Allows setting attributes on DOM nodes, normalizing in some cases.
       
  1401      * This passes through to the DOM node, allowing for custom attributes.
       
  1402      * @method setAttribute
       
  1403      * @for Node
       
  1404      * @for NodeList
       
  1405      * @chainable
       
  1406      * @param {string} name The attribute name 
       
  1407      * @param {string} value The value to set
       
  1408      */
       
  1409     'setAttribute',
       
  1410     /**
       
  1411      * Allows getting attributes on DOM nodes, normalizing in some cases.
       
  1412      * This passes through to the DOM node, allowing for custom attributes.
       
  1413      * @method getAttribute
       
  1414      * @for Node
       
  1415      * @for NodeList
       
  1416      * @param {string} name The attribute name 
       
  1417      * @return {string} The attribute value 
       
  1418      */
       
  1419     'getAttribute'
       
  1420 ]);
       
  1421 
       
  1422 /**
       
  1423  * Allows setting attributes on DOM nodes, normalizing in some cases.
       
  1424  * This passes through to the DOM node, allowing for custom attributes.
       
  1425  * @method setAttribute
       
  1426  * @see Node
       
  1427  * @for NodeList
       
  1428  * @chainable
       
  1429  * @param {string} name The attribute name 
       
  1430  * @param {string} value The value to set
       
  1431  */
       
  1432 
       
  1433 /**
       
  1434  * Allows getting attributes on DOM nodes, normalizing in some cases.
       
  1435  * This passes through to the DOM node, allowing for custom attributes.
       
  1436  * @method getAttribute
       
  1437  * @see Node
       
  1438  * @for NodeList
       
  1439  * @param {string} name The attribute name 
       
  1440  * @return {string} The attribute value 
       
  1441  */
       
  1442 Y.NodeList.importMethod(Y.Node.prototype, ['getAttribute', 'setAttribute']);
       
  1443 (function(Y) {
       
  1444     var methods = [
       
  1445     /**
       
  1446      * Determines whether each node has the given className.
       
  1447      * @method hasClass
       
  1448      * @for Node
       
  1449      * @param {String} className the class name to search for
       
  1450      * @return {Array} An array of booleans for each node bound to the NodeList. 
       
  1451      */
       
  1452      'hasClass',
       
  1453 
       
  1454     /**
       
  1455      * Adds a class name to each node.
       
  1456      * @method addClass         
       
  1457      * @param {String} className the class name to add to the node's class attribute
       
  1458      * @chainable
       
  1459      */
       
  1460      'addClass',
       
  1461 
       
  1462     /**
       
  1463      * Removes a class name from each node.
       
  1464      * @method removeClass         
       
  1465      * @param {String} className the class name to remove from the node's class attribute
       
  1466      * @chainable
       
  1467      */
       
  1468      'removeClass',
       
  1469 
       
  1470     /**
       
  1471      * Replace a class with another class for each node.
       
  1472      * If no oldClassName is present, the newClassName is simply added.
       
  1473      * @method replaceClass  
       
  1474      * @param {String} oldClassName the class name to be replaced
       
  1475      * @param {String} newClassName the class name that will be replacing the old class name
       
  1476      * @chainable
       
  1477      */
       
  1478      'replaceClass',
       
  1479 
       
  1480     /**
       
  1481      * If the className exists on the node it is removed, if it doesn't exist it is added.
       
  1482      * @method toggleClass  
       
  1483      * @param {String} className the class name to be toggled
       
  1484      * @chainable
       
  1485      */
       
  1486      'toggleClass'
       
  1487     ];
       
  1488 
       
  1489     Y.Node.importMethod(Y.DOM, methods);
       
  1490     /**
       
  1491      * Determines whether each node has the given className.
       
  1492      * @method hasClass
       
  1493      * @see Node.hasClass
       
  1494      * @for NodeList
       
  1495      * @param {String} className the class name to search for
       
  1496      * @return {Array} An array of booleans for each node bound to the NodeList. 
       
  1497      */
       
  1498 
       
  1499     /**
       
  1500      * Adds a class name to each node.
       
  1501      * @method addClass         
       
  1502      * @see Node.addClass
       
  1503      * @param {String} className the class name to add to the node's class attribute
       
  1504      * @chainable
       
  1505      */
       
  1506 
       
  1507     /**
       
  1508      * Removes a class name from each node.
       
  1509      * @method removeClass         
       
  1510      * @see Node.removeClass
       
  1511      * @param {String} className the class name to remove from the node's class attribute
       
  1512      * @chainable
       
  1513      */
       
  1514 
       
  1515     /**
       
  1516      * Replace a class with another class for each node.
       
  1517      * If no oldClassName is present, the newClassName is simply added.
       
  1518      * @method replaceClass  
       
  1519      * @see Node.replaceClass
       
  1520      * @param {String} oldClassName the class name to be replaced
       
  1521      * @param {String} newClassName the class name that will be replacing the old class name
       
  1522      * @chainable
       
  1523      */
       
  1524 
       
  1525     /**
       
  1526      * If the className exists on the node it is removed, if it doesn't exist it is added.
       
  1527      * @method toggleClass  
       
  1528      * @see Node.toggleClass
       
  1529      * @param {String} className the class name to be toggled
       
  1530      * @chainable
       
  1531      */
       
  1532     Y.NodeList.importMethod(Y.Node.prototype, methods);
       
  1533 })(Y);
       
  1534 
       
  1535 if (!document.documentElement.hasAttribute) { // IE < 8
       
  1536     Y.Node.prototype.hasAttribute = function(attr) {
       
  1537         return Y.DOM.getAttribute(this._node, attr) !== '';
       
  1538     };
       
  1539 }
       
  1540 
       
  1541 // IE throws error when setting input.type = 'hidden',
       
  1542 // input.setAttribute('type', 'hidden') and input.attributes.type.value = 'hidden'
       
  1543 Y.Node.ATTRS.type = {
       
  1544     setter: function(val) {
       
  1545         if (val === 'hidden') {
       
  1546             try {
       
  1547                 this._node.type = 'hidden';
       
  1548             } catch(e) {
       
  1549                 this.setStyle('display', 'none');
       
  1550                 this._inputType = 'hidden';
       
  1551             }
       
  1552         } else {
       
  1553             try { // IE errors when changing the type from "hidden'
       
  1554                 this._node.type = val;
       
  1555             } catch (e) {
       
  1556                 Y.log('error setting type: ' + val, 'info', 'node');
       
  1557             }
       
  1558         }
       
  1559         return val;
       
  1560     },
       
  1561 
       
  1562     getter: function() {
       
  1563         return this._inputType || this._node.type;
       
  1564     },
       
  1565 
       
  1566     _bypassProxy: true // don't update DOM when using with Attribute
       
  1567 };
       
  1568 
       
  1569 
       
  1570 }, '3.0.0' ,{requires:['dom-base', 'selector-css2', 'event-base']});