]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - jssource/src_files/include/javascript/yui3/build/node/node.js
Release 6.2.0beta4
[Github/sugarcrm.git] / jssource / src_files / include / javascript / yui3 / build / node / node.js
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     }
184 };
185
186 Node.importMethod = function(host, name, altName) {
187     if (typeof name === 'string') {
188         altName = altName || name;
189         Node.addMethod(altName, host[name], host);
190     } else {
191         Y.each(name, function(n) {
192             Node.importMethod(host, n);
193         });
194     }
195 };
196
197 /**
198  * Returns a single Node instance bound to the node or the
199  * first element matching the given selector.
200  * @method Y.one
201  * @static
202  * @param {String | HTMLElement} node a node or Selector 
203  * @param {Y.Node || HTMLElement} doc an optional document to scan. Defaults to Y.config.doc. 
204  */
205 Node.one = function(node) {
206     var instance = null,
207         cachedNode,
208         uid;
209
210     if (node) {
211         if (typeof node === 'string') {
212             if (node.indexOf('doc') === 0) { // doc OR document
213                 node = Y.config.doc;
214             } else if (node.indexOf('win') === 0) { // win OR window
215                 node = Y.config.win;
216             } else {
217                 node = Y.Selector.query(node, null, true);
218             }
219             if (!node) {
220                 return null;
221             }
222         } else if (node instanceof Node) {
223             return node; // NOTE: return
224         }
225
226         uid = node._yuid;
227         instance = Node._instances[uid]; // reuse exising instances
228         cachedNode = instance ? instance._node : null;
229         if (!instance || (cachedNode && node !== cachedNode)) { // new Node when nodes don't match
230             instance = new Node(node);
231         }
232     }
233     return instance;
234 };
235
236 /**
237  * Returns a single Node instance bound to the node or the
238  * first element matching the given selector.
239  * @method Y.get
240  * @deprecated Use Y.one
241  * @static
242  * @param {String | HTMLElement} node a node or Selector 
243  * @param {Y.Node || HTMLElement} doc an optional document to scan. Defaults to Y.config.doc. 
244  */
245 Node.get = function() {
246     return Node.one.apply(Node, arguments);
247 };
248
249 /**
250  * Creates a new dom node using the provided markup string. 
251  * @method create
252  * @static
253  * @param {String} html The markup used to create the element
254  * @param {HTMLDocument} doc An optional document context 
255  * @return {Node} A Node instance bound to a DOM node or fragment 
256  */
257 Node.create = function() {
258     return Node.get(Y.DOM.create.apply(Y.DOM, arguments));
259 };
260
261 Node.ATTRS = {
262     /**
263      * Allows for getting and setting the text of an element.
264      * Formatting is preserved and special characters are treated literally.
265      * @config text
266      * @type String
267      */
268     text: {
269         getter: function() {
270             return Y.DOM.getText(this._node);
271         },
272
273         setter: function(content) {
274             Y.DOM.setText(this._node, content);
275             return content;
276         }
277     },
278
279     'options': {
280         getter: function() {
281             return this._node.getElementsByTagName('option');
282         }
283     },
284
285      // IE: elements collection is also FORM node which trips up scrubVal.
286      // preconverting to NodeList
287      // TODO: break out for IE only
288     'elements': {
289         getter: function() {
290             return Y.all(this._node.elements);
291         }
292     },
293
294     /**
295      * Returns a NodeList instance of all HTMLElement children.
296      * @readOnly
297      * @config children
298      * @type NodeList
299      */
300     'children': {
301         getter: function() {
302             var node = this._node,
303                 children = node.children,
304                 childNodes, i, len;
305
306             if (!children) {
307                 childNodes = node.childNodes;
308                 children = [];
309
310                 for (i = 0, len = childNodes.length; i < len; ++i) {
311                     if (childNodes[i][TAG_NAME]) {
312                         children[children.length] = childNodes[i];
313                     }
314                 }
315             }
316             return Y.all(children);
317         }
318     },
319
320     value: {
321         getter: function() {
322             return Y.DOM.getValue(this._node);
323         },
324
325         setter: function(val) {
326             Y.DOM.setValue(this._node, val);
327             return val;
328         }
329     },
330
331     data: {
332         getter: function() {
333             return this._data;
334         },
335
336         setter: function(val) {
337             this._data = val;
338             return val;
339         }
340     }
341 };
342
343 // call with instance context
344 Node.DEFAULT_SETTER = function(name, val) {
345     var node = this._stateProxy,
346         strPath;
347
348     if (name.indexOf(DOT) > -1) {
349         strPath = name;
350         name = name.split(DOT);
351         // only allow when defined on node
352         Y.Object.setValue(node, name, val);
353     } else if (node[name] !== undefined) { // pass thru DOM properties 
354         node[name] = val;
355     }
356
357     return val;
358 };
359
360 // call with instance context
361 Node.DEFAULT_GETTER = function(name) {
362     var node = this._stateProxy,
363         val;
364
365     if (name.indexOf && name.indexOf(DOT) > -1) {
366         val = Y.Object.getValue(node, name.split(DOT));
367     } else if (node[name] !== undefined) { // pass thru from DOM
368         val = node[name];
369     }
370
371     return val;
372 };
373
374 Y.augment(Node, Y.Event.Target);
375
376 Y.mix(Node.prototype, {
377     toString: function() {
378         var str = '',
379             errorMsg = this[UID] + ': not bound to a node',
380             node = this._node;
381
382         if (node) {
383             str += node[NODE_NAME];
384             if (node.id) {
385                 str += '#' + node.id; 
386             }
387
388             if (node.className) {
389                 str += '.' + node.className.replace(' ', '.'); 
390             }
391
392             // TODO: add yuid?
393             str += ' ' + this[UID];
394         }
395         return str || errorMsg;
396     },
397
398     /**
399      * Returns an attribute value on the Node instance
400      * @method get
401      * @param {String} attr The attribute to be set
402      * @return {any} The current value of the attribute
403      */
404     get: function(attr) {
405         var val;
406
407         if (this._getAttr) { // use Attribute imple
408             val = this._getAttr(attr);
409         } else {
410             val = this._get(attr);
411         }
412
413         if (val) {
414             val = Y.Node.scrubVal(val, this);
415         }
416         return val;
417     },
418
419     _get: function(attr) {
420         var attrConfig = Node.ATTRS[attr],
421             val;
422
423         if (attrConfig && attrConfig.getter) {
424             val = attrConfig.getter.call(this);
425         } else if (Node.re_aria.test(attr)) {
426             val = this._node.getAttribute(attr, 2); 
427         } else {
428             val = Node.DEFAULT_GETTER.apply(this, arguments);
429         }
430
431         return val;
432     },
433
434     /**
435      * Sets an attribute on the Node instance.
436      * @method set
437      * @param {String} attr The attribute to be set.  
438      * @param {any} val The value to set the attribute to.  
439      * @chainable
440      */
441     set: function(attr, val) {
442         var attrConfig = Node.ATTRS[attr];
443
444         if (this._setAttr) { // use Attribute imple
445             this._setAttr.apply(this, arguments);
446         } else { // use setters inline
447             if (attrConfig && attrConfig.setter) {
448                 attrConfig.setter.call(this, val);
449             } else if (Node.re_aria.test(attr)) { // special case Aria
450                 this._node.setAttribute(attr, val);
451             } else {
452                 Node.DEFAULT_SETTER.apply(this, arguments);
453             }
454         }
455
456         return this;
457     },
458
459     /**
460      * Sets multiple attributes. 
461      * @method setAttrs
462      * @param {Object} attrMap an object of name/value pairs to set  
463      * @chainable
464      */
465     setAttrs: function(attrMap) {
466         if (this._setAttrs) { // use Attribute imple
467             this._setAttrs(attrMap);
468         } else { // use setters inline
469             Y.Object.each(attrMap, function(v, n) {
470                 this.set(n, v); 
471             }, this);
472         }
473
474         return this;
475     },
476
477     /**
478      * Returns an object containing the values for the requested attributes. 
479      * @method getAttrs
480      * @param {Array} attrs an array of attributes to get values  
481      * @return {Object} An object with attribute name/value pairs.
482      */
483     getAttrs: function(attrs) {
484         var ret = {};
485         if (this._getAttrs) { // use Attribute imple
486             this._getAttrs(attrs);
487         } else { // use setters inline
488             Y.Array.each(attrs, function(v, n) {
489                 ret[v] = this.get(v); 
490             }, this);
491         }
492
493         return ret;
494     },
495
496     /**
497      * Creates a new Node using the provided markup string. 
498      * @method create
499      * @param {String} html The markup used to create the element
500      * @param {HTMLDocument} doc An optional document context 
501      * @return {Node} A Node instance bound to a DOM node or fragment 
502      */
503     create: Node.create,
504
505     /**
506      * Compares nodes to determine if they match.
507      * Node instances can be compared to each other and/or HTMLElements.
508      * @method compareTo
509      * @param {HTMLElement | Node} refNode The reference node to compare to the node.
510      * @return {Boolean} True if the nodes match, false if they do not. 
511      */
512     compareTo: function(refNode) {
513         var node = this._node;
514         if (refNode instanceof Y.Node) { 
515             refNode = refNode._node;
516         }
517         return node === refNode;
518     },
519
520     /**
521      * Determines whether the node is appended to the document.
522      * @method inDoc
523      * @param {Node|HTMLElement} doc optional An optional document to check against.
524      * Defaults to current document. 
525      * @return {Boolean} Whether or not this node is appended to the document. 
526      */
527     inDoc: function(doc) {
528         var node = this._node;
529         doc = (doc) ? doc._node || doc : node[OWNER_DOCUMENT];
530         if (doc.documentElement) {
531             return Y.DOM.contains(doc.documentElement, node);
532         }
533     },
534
535     getById: function(id) {
536         var node = this._node,
537             ret = Y.DOM.byId(id, node[OWNER_DOCUMENT]);
538         if (ret && Y.DOM.contains(node, ret)) {
539             ret = Y.one(ret);
540         } else {
541             ret = null;
542         }
543         return ret;
544     },
545
546    /**
547      * Returns the nearest ancestor that passes the test applied by supplied boolean method.
548      * @method ancestor
549      * @param {String | Function} fn A selector string or boolean method for testing elements.
550      * If a function is used, it receives the current node being tested as the only argument.
551      * @return {Node} The matching Node instance or null if not found
552      */
553     ancestor: function(fn) {
554         return Node.get(Y.DOM.elementByAxis(this._node, 'parentNode', _wrapFn(fn)));
555     },
556
557     /**
558      * Returns the previous matching sibling. 
559      * Returns the nearest element node sibling if no method provided.
560      * @method previous
561      * @param {String | Function} fn A selector or boolean method for testing elements.
562      * If a function is used, it receives the current node being tested as the only argument.
563      * @return {Node} Node instance or null if not found
564      */
565     previous: function(fn, all) {
566         return Node.get(Y.DOM.elementByAxis(this._node, 'previousSibling', _wrapFn(fn), all));
567     }, 
568
569     /**
570      * Returns the next matching sibling. 
571      * Returns the nearest element node sibling if no method provided.
572      * @method next
573      * @param {String | Function} fn A selector or boolean method for testing elements.
574      * If a function is used, it receives the current node being tested as the only argument.
575      * @return {Node} Node instance or null if not found
576      */
577     next: function(node, fn, all) {
578         return Node.get(Y.DOM.elementByAxis(this._node, 'nextSibling', _wrapFn(fn), all));
579     },
580         
581     /**
582      * Retrieves a Node instance of nodes based on the given CSS selector. 
583      * @method one
584      *
585      * @param {string} selector The CSS selector to test against.
586      * @return {Node} A Node instance for the matching HTMLElement.
587      */
588     one: function(selector) {
589         return Y.one(Y.Selector.query(selector, this._node, true));
590     },
591
592     /**
593      * Retrieves a Node instance of nodes based on the given CSS selector. 
594      * @method query
595      * @deprecated Use one()
596      * @param {string} selector The CSS selector to test against.
597      * @return {Node} A Node instance for the matching HTMLElement.
598      */
599     query: function(selector) {
600         return this.one(selector);
601     },
602
603     /**
604      * Retrieves a nodeList based on the given CSS selector. 
605      * @method all
606      *
607      * @param {string} selector The CSS selector to test against.
608      * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
609      */
610     all: function(selector) {
611         var nodelist = Y.all(Y.Selector.query(selector, this._node));
612         nodelist._query = selector;
613         return nodelist;
614     },
615
616     /**
617      * Retrieves a nodeList based on the given CSS selector. 
618      * @method queryAll
619      * @deprecated Use all()
620      * @param {string} selector The CSS selector to test against.
621      * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
622      */
623     queryAll: function(selector) {
624         return this.all(selector);
625     },
626
627     // TODO: allow fn test
628     /**
629      * Test if the supplied node matches the supplied selector.
630      * @method test
631      *
632      * @param {string} selector The CSS selector to test against.
633      * @return {boolean} Whether or not the node matches the selector.
634      */
635     test: function(selector) {
636         return Y.Selector.test(this._node, selector);
637     },
638
639     /**
640      * Removes the node from its parent.
641      * Shortcut for myNode.get('parentNode').removeChild(myNode);
642      * @method remove
643      * @chainable
644      *
645      */
646     remove: function(destroy) {
647         var node = this._node;
648         node.parentNode.removeChild(node);
649         if (destroy) {
650             this.destroy(true);
651         }
652         return this;
653     },
654
655     /**
656      * Replace the node with the other node. This is a DOM update only
657      * and does not change the node bound to the Node instance.
658      * Shortcut for myNode.get('parentNode').replaceChild(newNode, myNode);
659      * @method replace
660      * @chainable
661      *
662      */
663     replace: function(newNode) {
664         var node = this._node;
665         node.parentNode.replaceChild(newNode, node);
666         return this;
667     },
668
669     purge: function(recurse, type) {
670         Y.Event.purgeElement(this._node, recurse, type);
671     },
672
673     destroy: function(purge) {
674         delete Node._instances[this[UID]];
675         if (purge) {
676             this.purge(true);
677         }
678
679         if (this.unplug) {
680             this.unplug();
681         }
682
683         this._node._yuid = null;
684         this._node = null;
685         this._stateProxy = null;
686     },
687
688     /**
689      * Invokes a method on the Node instance 
690      * @method invoke
691      * @param {String} method The name of the method to invoke
692      * @param {Any}  a, b, c, etc. Arguments to invoke the method with. 
693      * @return Whatever the underly method returns. 
694      * DOM Nodes and Collections return values
695      * are converted to Node/NodeList instances.
696      *
697      */
698     invoke: function(method, a, b, c, d, e) {
699         var node = this._node,
700             ret;
701
702         if (a && a instanceof Y.Node) {
703             a = a._node;
704         }
705
706         if (b && b instanceof Y.Node) {
707             b = b._node;
708         }
709
710         ret = node[method](a, b, c, d, e);    
711         return Y.Node.scrubVal(ret, this);
712     },
713
714     /**
715      * Applies the given function to each Node in the NodeList.
716      * @method each
717      * @deprecated Use NodeList
718      * @param {Function} fn The function to apply 
719      * @param {Object} context optional An optional context to apply the function with
720      * Default context is the NodeList instance
721      * @chainable
722      */
723     each: function(fn, context) {
724         context = context || this;
725         return fn.call(context, this);
726     },
727
728     /**
729      * Retrieves the Node instance at the given index. 
730      * @method item
731      * @deprecated Use NodeList
732      *
733      * @param {Number} index The index of the target Node.
734      * @return {Node} The Node instance at the given index.
735      */
736     item: function(index) {
737         return this;
738     },
739
740     /**
741      * Returns the current number of items in the Node.
742      * @method size
743      * @deprecated Use NodeList
744      * @return {Int} The number of items in the Node. 
745      */
746     size: function() {
747         return this._node ? 1 : 0;
748     },
749
750     /**
751      * Inserts the content before the reference node. 
752      * @method insert
753      * @param {String | Y.Node | HTMLElement} content The content to insert 
754      * @param {Int | Y.Node | HTMLElement | String} where The position to insert at.
755      * @chainable
756      */
757     insert: function(content, where) {
758         var node = this._node;
759
760         if (content) {
761             if (typeof where === 'number') { // allow index
762                 where = this._node.childNodes[where];
763             }
764
765             if (typeof content !== 'string') { // allow Node or NodeList/Array instances
766                 if (content._node) { // Node
767                     content = content._node;
768                 } else if (content._nodes || (!content.nodeType && content.length)) { // NodeList or Array
769                     Y.each(content._nodes, function(n) {
770                         Y.DOM.addHTML(node, n, where);
771                     });
772
773                     return this; // NOTE: early return
774                 }
775             }
776             Y.DOM.addHTML(node, content, where);
777         }
778         return this;
779     },
780
781     /**
782      * Inserts the content as the firstChild of the node. 
783      * @method prepend
784      * @param {String | Y.Node | HTMLElement} content The content to insert 
785      * @chainable
786      */
787     prepend: function(content) {
788         return this.insert(content, 0);
789     },
790
791     /**
792      * Inserts the content as the lastChild of the node. 
793      * @method append
794      * @param {String | Y.Node | HTMLElement} content The content to insert 
795      * @chainable
796      */
797     append: function(content) {
798         return this.insert(content, null);
799     },
800
801     /**
802      * Replaces the node's current content with the content.
803      * @method setContent
804      * @param {String | Y.Node | HTMLElement} content The content to insert 
805      * @chainable
806      */
807     setContent: function(content) {
808         Y.DOM.addHTML(this._node, content, 'replace');
809         return this;
810     },
811
812     // TODO: need this?
813     hasMethod: function(method) {
814         var node = this._node;
815         return (node && (typeof node === 'function'));
816     }
817 }, true);
818
819 Y.Node = Node;
820 Y.get = Y.Node.get;
821 Y.one = Y.Node.one;
822 /**
823  * The NodeList module provides support for managing collections of Nodes.
824  * @module node
825  * @submodule nodelist
826  */    
827
828 /**
829  * The NodeList class provides a wrapper for manipulating DOM NodeLists.
830  * NodeList properties can be accessed via the set/get methods.
831  * Use Y.all() to retrieve NodeList instances.
832  *
833  * @class NodeList
834  * @constructor
835  */
836
837 var NodeList = function(nodes) {
838     if (typeof nodes === 'string') {
839         this._query = nodes;
840         nodes = Y.Selector.query(nodes);
841     } else {
842         nodes = Y.Array(nodes, 0, true);
843     }
844
845     NodeList._instances[Y.stamp(this)] = this;
846     this._nodes = nodes;
847 };
848 // end "globals"
849
850 NodeList.NAME = 'NodeList';
851
852 /**
853  * Retrieves the DOM nodes bound to a NodeList instance
854  * @method NodeList.getDOMNodes
855  * @static
856  *
857  * @param {Y.NodeList} node The NodeList instance
858  * @return {Array} The array of DOM nodes bound to the NodeList
859  */
860 NodeList.getDOMNodes = function(nodeList) {
861     return nodeList._nodes;
862 };
863
864 NodeList._instances = [];
865
866 NodeList.each = function(instance, fn, context) {
867     var nodes = instance._nodes;
868     if (nodes && nodes.length) {
869         Y.Array.each(nodes, fn, context || instance);
870     } else {
871     }
872 };
873
874 NodeList.addMethod = function(name, fn, context) {
875     if (name && fn) {
876         NodeList.prototype[name] = function() {
877             var ret = [],
878                 args = arguments;
879
880             Y.Array.each(this._nodes, function(node) {
881                 var UID = '_yuid',
882                     instance = Y.Node._instances[node[UID]],
883                     ctx,
884                     result;
885
886                 if (!instance) {
887                     instance = NodeList._getTempNode(node);
888                 }
889                 ctx = context || instance;
890                 result = fn.apply(ctx, args);
891                 if (result !== undefined && result !== instance) {
892                     ret[ret.length] = result;
893                 }
894             });
895
896             // TODO: remove tmp pointer
897             return ret.length ? ret : this;
898         };
899     } else {
900     }
901 };
902
903 NodeList.importMethod = function(host, name, altName) {
904     if (typeof name === 'string') {
905         altName = altName || name;
906         NodeList.addMethod(name, host[name]);
907     } else {
908         Y.each(name, function(n) {
909             NodeList.importMethod(host, n);
910         });
911     }
912 };
913
914 NodeList._getTempNode = function(node) {
915     var tmp = NodeList._tempNode;
916     if (!tmp) {
917         tmp = Y.Node.create('<div></div>');
918         NodeList._tempNode = tmp;
919     }
920
921     tmp._node = node;
922     tmp._stateProxy = node;
923     return tmp;
924 };
925
926 Y.mix(NodeList.prototype, {
927     /**
928      * Retrieves the Node instance at the given index. 
929      * @method item
930      *
931      * @param {Number} index The index of the target Node.
932      * @return {Node} The Node instance at the given index.
933      */
934     item: function(index) {
935         return Y.one((this._nodes || [])[index]);
936     },
937
938     /**
939      * Applies the given function to each Node in the NodeList.
940      * @method each
941      * @param {Function} fn The function to apply. It receives 3 arguments:
942      * the current node instance, the node's index, and the NodeList instance
943      * @param {Object} context optional An optional context to apply the function with
944      * Default context is the current Node instance
945      * @chainable
946      */
947     each: function(fn, context) {
948         var instance = this;
949         Y.Array.each(this._nodes, function(node, index) {
950             node = Y.one(node);
951             return fn.call(context || node, node, index, instance);
952         });
953         return instance;
954     },
955
956     batch: function(fn, context) {
957         var nodelist = this;
958
959         Y.Array.each(this._nodes, function(node, index) {
960             var instance = Y.Node._instances[node[UID]];
961             if (!instance) {
962                 instance = NodeList._getTempNode(node);
963             }
964
965             return fn.call(context || instance, instance, index, nodelist);
966         });
967         return nodelist;
968     },
969
970     /**
971      * Executes the function once for each node until a true value is returned.
972      * @method some
973      * @param {Function} fn The function to apply. It receives 3 arguments:
974      * the current node instance, the node's index, and the NodeList instance
975      * @param {Object} context optional An optional context to execute the function from.
976      * Default context is the current Node instance
977      * @return {Boolean} Whether or not the function returned true for any node.
978      */
979     some: function(fn, context) {
980         var instance = this;
981         return Y.Array.some(this._nodes, function(node, index) {
982             node = Y.one(node);
983             context = context || node;
984             return fn.call(context, node, index, instance);
985         });
986     },
987
988     /**
989      * Creates a documenFragment from the nodes bound to the NodeList instance 
990      * @method toDocFrag
991      * @return Node a Node instance bound to the documentFragment
992      */
993     toFrag: function() {
994         return Y.one(Y.DOM._nl2frag(this._nodes));
995     },
996
997     /**
998      * Returns the index of the node in the NodeList instance
999      * or -1 if the node isn't found.
1000      * @method indexOf
1001      * @param {Y.Node || DOMNode} node the node to search for
1002      * @return {Int} the index of the node value or -1 if not found
1003      */
1004     indexOf: function(node) {
1005         return Y.Array.indexOf(this._nodes, Y.Node.getDOMNode(node));
1006     },
1007
1008     /**
1009      * Filters the NodeList instance down to only nodes matching the given selector.
1010      * @method filter
1011      * @param {String} selector The selector to filter against
1012      * @return {NodeList} NodeList containing the updated collection 
1013      * @see Selector
1014      */
1015     filter: function(selector) {
1016         return Y.all(Y.Selector.filter(this._nodes, selector));
1017     },
1018
1019
1020     /**
1021      * Creates a new NodeList containing all nodes at every n indices, where 
1022      * remainder n % index equals r.
1023      * (zero-based index).
1024      * @method modulus
1025      * @param {Int} n The offset to use (return every nth node)
1026      * @param {Int} r An optional remainder to use with the modulus operation (defaults to zero) 
1027      * @return {NodeList} NodeList containing the updated collection 
1028      */
1029     modulus: function(n, r) {
1030         r = r || 0;
1031         var nodes = [];
1032         NodeList.each(this, function(node, i) {
1033             if (i % n === r) {
1034                 nodes.push(node);
1035             }
1036         });
1037
1038         return Y.all(nodes);
1039     },
1040
1041     /**
1042      * Creates a new NodeList containing all nodes at odd indices
1043      * (zero-based index).
1044      * @method odd
1045      * @return {NodeList} NodeList containing the updated collection 
1046      */
1047     odd: function() {
1048         return this.modulus(2, 1);
1049     },
1050
1051     /**
1052      * Creates a new NodeList containing all nodes at even indices
1053      * (zero-based index), including zero. 
1054      * @method even
1055      * @return {NodeList} NodeList containing the updated collection 
1056      */
1057     even: function() {
1058         return this.modulus(2);
1059     },
1060
1061     destructor: function() {
1062         delete NodeList._instances[this[UID]];
1063     },
1064
1065     /**
1066      * Reruns the initial query, when created using a selector query 
1067      * @method refresh
1068      * @chainable
1069      */
1070     refresh: function() {
1071         var doc,
1072             nodes = this._nodes;
1073         if (this._query) {
1074             if (nodes && nodes[0] && nodes[0].ownerDocument) {
1075                 doc = nodes[0].ownerDocument;
1076             }
1077
1078             this._nodes = Y.Selector.query(this._query, doc || Y.config.doc);        
1079         }
1080
1081         return this;
1082     },
1083
1084     /**
1085      * Applies an event listener to each Node bound to the NodeList. 
1086      * @method on
1087      * @param {String} type The event being listened for
1088      * @param {Function} fn The handler to call when the event fires
1089      * @param {Object} context The context to call the handler with.
1090      * Default is the NodeList instance. 
1091      * @return {Object} Returns an event handle that can later be use to detach(). 
1092      * @see Event.on
1093      */
1094     on: function(type, fn, context) {
1095         var args = Y.Array(arguments, 0, true);
1096         args.splice(2, 0, this._nodes);
1097         args[3] = context || this;
1098         return Y.on.apply(Y, args);
1099     },
1100
1101     /**
1102      * Applies an event listener to each Node bound to the NodeList. 
1103      * The handler is called only after all on() handlers are called
1104      * and the event is not prevented.
1105      * @method after
1106      * @param {String} type The event being listened for
1107      * @param {Function} fn The handler to call when the event fires
1108      * @param {Object} context The context to call the handler with.
1109      * Default is the NodeList instance. 
1110      * @return {Object} Returns an event handle that can later be use to detach(). 
1111      * @see Event.on
1112      */
1113     after: function(type, fn, context) {
1114         var args = Y.Array(arguments, 0, true);
1115         args.splice(2, 0, this._nodes);
1116         args[3] = context || this;
1117         return Y.after.apply(Y, args);
1118     },
1119
1120     /**
1121      * Returns the current number of items in the NodeList.
1122      * @method size
1123      * @return {Int} The number of items in the NodeList. 
1124      */
1125     size: function() {
1126         return this._nodes.length;
1127     },
1128
1129     toString: function() {
1130         var str = '',
1131             errorMsg = this[UID] + ': not bound to any nodes',
1132             nodes = this._nodes,
1133             node;
1134
1135         if (nodes && nodes[0]) {
1136             node = nodes[0];
1137             str += node[NODE_NAME];
1138             if (node.id) {
1139                 str += '#' + node.id; 
1140             }
1141
1142             if (node.className) {
1143                 str += '.' + node.className.replace(' ', '.'); 
1144             }
1145
1146             if (nodes.length > 1) {
1147                 str += '...[' + nodes.length + ' items]';
1148             }
1149         }
1150         return str || errorMsg;
1151     }
1152
1153 }, true);
1154
1155 NodeList.importMethod(Y.Node.prototype, [
1156     /**
1157      * Called on each Node instance
1158      * @for NodeList
1159      * @method append
1160      * @see Node.append
1161      */
1162     'append',
1163
1164     /**
1165       * Called on each Node instance
1166       * @method detach
1167       * @see Node.detach
1168       */
1169     'detach',
1170     
1171     /** Called on each Node instance
1172       * @method detachAll
1173       * @see Node.detachAll
1174       */
1175     'detachAll',
1176
1177     /** Called on each Node instance
1178       * @method insert
1179       * @see NodeInsert
1180       */
1181     'insert',
1182
1183     /** Called on each Node instance
1184       * @method prepend
1185       * @see Node.prepend
1186       */
1187     'prepend',
1188
1189     /** Called on each Node instance
1190       * @method remove
1191       * @see Node.remove
1192       */
1193     'remove',
1194
1195     /** Called on each Node instance
1196       * @method set
1197       * @see Node.set
1198       */
1199     'set',
1200
1201     /** Called on each Node instance
1202       * @method setContent
1203       * @see Node.setContent
1204       */
1205     'setContent'
1206 ]);
1207
1208 // one-off implementation to convert array of Nodes to NodeList
1209 // e.g. Y.all('input').get('parentNode');
1210
1211 /** Called on each Node instance
1212   * @method get
1213   * @see Node
1214   */
1215 NodeList.prototype.get = function(attr) {
1216     var ret = [],
1217         nodes = this._nodes,
1218         isNodeList = false,
1219         getTemp = NodeList._getTempNode,
1220         instance,
1221         val;
1222
1223     if (nodes[0]) {
1224         instance = Y.Node._instances[nodes[0]._yuid] || getTemp(nodes[0]);
1225         val = instance._get(attr);
1226         if (val && val.nodeType) {
1227             isNodeList = true;
1228         }
1229     }
1230
1231     Y.Array.each(nodes, function(node) {
1232         instance = Y.Node._instances[node._yuid];
1233
1234         if (!instance) {
1235             instance = getTemp(node);
1236         }
1237
1238         val = instance._get(attr);
1239         if (!isNodeList) { // convert array of Nodes to NodeList
1240             val = Y.Node.scrubVal(val, instance);
1241         }
1242
1243         ret.push(val);
1244     });
1245
1246     return (isNodeList) ? Y.all(ret) : ret;
1247 };
1248
1249 Y.NodeList = NodeList;
1250
1251 Y.all = function(nodes) {
1252     return new NodeList(nodes);
1253 };
1254
1255 Y.Node.all = Y.all;
1256 Y.Array.each([
1257     /**
1258      * Passes through to DOM method.
1259      * @method replaceChild
1260      * @for Node
1261      * @param {HTMLElement | Node} node Node to be inserted 
1262      * @param {HTMLElement | Node} refNode Node to be replaced 
1263      * @return {Node} The replaced node 
1264      */
1265     'replaceChild',
1266
1267     /**
1268      * Passes through to DOM method.
1269      * @method appendChild
1270      * @param {HTMLElement | Node} node Node to be appended 
1271      * @return {Node} The appended node 
1272      */
1273     'appendChild',
1274
1275     /**
1276      * Passes through to DOM method.
1277      * @method insertBefore
1278      * @param {HTMLElement | Node} newNode Node to be appended 
1279      * @param {HTMLElement | Node} refNode Node to be inserted before 
1280      * @return {Node} The inserted node 
1281      */
1282     'insertBefore',
1283
1284     /**
1285      * Passes through to DOM method.
1286      * @method removeChild
1287      * @param {HTMLElement | Node} node Node to be removed 
1288      * @return {Node} The removed node 
1289      */
1290     'removeChild',
1291
1292     /**
1293      * Passes through to DOM method.
1294      * @method hasChildNodes
1295      * @return {Boolean} Whether or not the node has any childNodes 
1296      */
1297     'hasChildNodes',
1298
1299     /**
1300      * Passes through to DOM method.
1301      * @method cloneNode
1302      * @param {Boolean} deep Whether or not to perform a deep clone, which includes
1303      * subtree and attributes
1304      * @return {Node} The clone 
1305      */
1306     'cloneNode',
1307
1308     /**
1309      * Passes through to DOM method.
1310      * @method hasAttribute
1311      * @param {String} attribute The attribute to test for 
1312      * @return {Boolean} Whether or not the attribute is present 
1313      */
1314     'hasAttribute',
1315
1316     /**
1317      * Passes through to DOM method.
1318      * @method removeAttribute
1319      * @param {String} attribute The attribute to be removed 
1320      * @chainable
1321      */
1322     'removeAttribute',
1323
1324     /**
1325      * Passes through to DOM method.
1326      * @method scrollIntoView
1327      * @chainable
1328      */
1329     'scrollIntoView',
1330
1331     /**
1332      * Passes through to DOM method.
1333      * @method getElementsByTagName
1334      * @param {String} tagName The tagName to collect 
1335      * @return {NodeList} A NodeList representing the HTMLCollection
1336      */
1337     'getElementsByTagName',
1338
1339     /**
1340      * Passes through to DOM method.
1341      * @method focus
1342      * @chainable
1343      */
1344     'focus',
1345
1346     /**
1347      * Passes through to DOM method.
1348      * @method blur
1349      * @chainable
1350      */
1351     'blur',
1352
1353     /**
1354      * Passes through to DOM method.
1355      * Only valid on FORM elements
1356      * @method submit
1357      * @chainable
1358      */
1359     'submit',
1360
1361     /**
1362      * Passes through to DOM method.
1363      * Only valid on FORM elements
1364      * @method reset
1365      * @chainable
1366      */
1367     'reset',
1368
1369     /**
1370      * Passes through to DOM method.
1371      * @method select
1372      * @chainable
1373      */
1374      'select'
1375 ], function(method) {
1376     Y.Node.prototype[method] = function(arg1, arg2, arg3) {
1377         var ret = this.invoke(method, arg1, arg2, arg3);
1378         return ret;
1379     };
1380 });
1381
1382 Node.importMethod(Y.DOM, [
1383     /**
1384      * Determines whether the ndoe is an ancestor of another HTML element in the DOM hierarchy.
1385      * @method contains
1386      * @param {Node | HTMLElement} needle The possible node or descendent
1387      * @return {Boolean} Whether or not this node is the needle its ancestor
1388      */
1389     'contains',
1390     /**
1391      * Allows setting attributes on DOM nodes, normalizing in some cases.
1392      * This passes through to the DOM node, allowing for custom attributes.
1393      * @method setAttribute
1394      * @for Node
1395      * @for NodeList
1396      * @chainable
1397      * @param {string} name The attribute name 
1398      * @param {string} value The value to set
1399      */
1400     'setAttribute',
1401     /**
1402      * Allows getting attributes on DOM nodes, normalizing in some cases.
1403      * This passes through to the DOM node, allowing for custom attributes.
1404      * @method getAttribute
1405      * @for Node
1406      * @for NodeList
1407      * @param {string} name The attribute name 
1408      * @return {string} The attribute value 
1409      */
1410     'getAttribute'
1411 ]);
1412
1413 /**
1414  * Allows setting attributes on DOM nodes, normalizing in some cases.
1415  * This passes through to the DOM node, allowing for custom attributes.
1416  * @method setAttribute
1417  * @see Node
1418  * @for NodeList
1419  * @chainable
1420  * @param {string} name The attribute name 
1421  * @param {string} value The value to set
1422  */
1423
1424 /**
1425  * Allows getting attributes on DOM nodes, normalizing in some cases.
1426  * This passes through to the DOM node, allowing for custom attributes.
1427  * @method getAttribute
1428  * @see Node
1429  * @for NodeList
1430  * @param {string} name The attribute name 
1431  * @return {string} The attribute value 
1432  */
1433 Y.NodeList.importMethod(Y.Node.prototype, ['getAttribute', 'setAttribute']);
1434 (function(Y) {
1435     var methods = [
1436     /**
1437      * Determines whether each node has the given className.
1438      * @method hasClass
1439      * @for Node
1440      * @param {String} className the class name to search for
1441      * @return {Array} An array of booleans for each node bound to the NodeList. 
1442      */
1443      'hasClass',
1444
1445     /**
1446      * Adds a class name to each node.
1447      * @method addClass         
1448      * @param {String} className the class name to add to the node's class attribute
1449      * @chainable
1450      */
1451      'addClass',
1452
1453     /**
1454      * Removes a class name from each node.
1455      * @method removeClass         
1456      * @param {String} className the class name to remove from the node's class attribute
1457      * @chainable
1458      */
1459      'removeClass',
1460
1461     /**
1462      * Replace a class with another class for each node.
1463      * If no oldClassName is present, the newClassName is simply added.
1464      * @method replaceClass  
1465      * @param {String} oldClassName the class name to be replaced
1466      * @param {String} newClassName the class name that will be replacing the old class name
1467      * @chainable
1468      */
1469      'replaceClass',
1470
1471     /**
1472      * If the className exists on the node it is removed, if it doesn't exist it is added.
1473      * @method toggleClass  
1474      * @param {String} className the class name to be toggled
1475      * @chainable
1476      */
1477      'toggleClass'
1478     ];
1479
1480     Y.Node.importMethod(Y.DOM, methods);
1481     /**
1482      * Determines whether each node has the given className.
1483      * @method hasClass
1484      * @see Node.hasClass
1485      * @for NodeList
1486      * @param {String} className the class name to search for
1487      * @return {Array} An array of booleans for each node bound to the NodeList. 
1488      */
1489
1490     /**
1491      * Adds a class name to each node.
1492      * @method addClass         
1493      * @see Node.addClass
1494      * @param {String} className the class name to add to the node's class attribute
1495      * @chainable
1496      */
1497
1498     /**
1499      * Removes a class name from each node.
1500      * @method removeClass         
1501      * @see Node.removeClass
1502      * @param {String} className the class name to remove from the node's class attribute
1503      * @chainable
1504      */
1505
1506     /**
1507      * Replace a class with another class for each node.
1508      * If no oldClassName is present, the newClassName is simply added.
1509      * @method replaceClass  
1510      * @see Node.replaceClass
1511      * @param {String} oldClassName the class name to be replaced
1512      * @param {String} newClassName the class name that will be replacing the old class name
1513      * @chainable
1514      */
1515
1516     /**
1517      * If the className exists on the node it is removed, if it doesn't exist it is added.
1518      * @method toggleClass  
1519      * @see Node.toggleClass
1520      * @param {String} className the class name to be toggled
1521      * @chainable
1522      */
1523     Y.NodeList.importMethod(Y.Node.prototype, methods);
1524 })(Y);
1525
1526 if (!document.documentElement.hasAttribute) { // IE < 8
1527     Y.Node.prototype.hasAttribute = function(attr) {
1528         return Y.DOM.getAttribute(this._node, attr) !== '';
1529     };
1530 }
1531
1532 // IE throws error when setting input.type = 'hidden',
1533 // input.setAttribute('type', 'hidden') and input.attributes.type.value = 'hidden'
1534 Y.Node.ATTRS.type = {
1535     setter: function(val) {
1536         if (val === 'hidden') {
1537             try {
1538                 this._node.type = 'hidden';
1539             } catch(e) {
1540                 this.setStyle('display', 'none');
1541                 this._inputType = 'hidden';
1542             }
1543         } else {
1544             try { // IE errors when changing the type from "hidden'
1545                 this._node.type = val;
1546             } catch (e) {
1547             }
1548         }
1549         return val;
1550     },
1551
1552     getter: function() {
1553         return this._inputType || this._node.type;
1554     },
1555
1556     _bypassProxy: true // don't update DOM when using with Attribute
1557 };
1558
1559
1560 }, '3.0.0' ,{requires:['dom-base', 'selector-css2', 'event-base']});
1561 YUI.add('node-style', function(Y) {
1562
1563 (function(Y) {
1564 /**
1565  * Extended Node interface for managing node styles.
1566  * @module node
1567  * @submodule node-style
1568  */
1569
1570 var methods = [
1571     /**
1572      * Returns the style's current value.
1573      * @method getStyle
1574      * @for Node
1575      * @param {String} attr The style attribute to retrieve. 
1576      * @return {String} The current value of the style property for the element.
1577      */
1578     'getStyle',
1579
1580     /**
1581      * Returns the computed value for the given style property.
1582      * @method getComputedStyle
1583      * @param {String} attr The style attribute to retrieve. 
1584      * @return {String} The computed value of the style property for the element.
1585      */
1586     'getComputedStyle',
1587
1588     /**
1589      * Sets a style property of the node.
1590      * @method setStyle
1591      * @param {String} attr The style attribute to set. 
1592      * @param {String|Number} val The value. 
1593      * @chainable
1594      */
1595     'setStyle',
1596
1597     /**
1598      * Sets multiple style properties on the node.
1599      * @method setStyles
1600      * @param {Object} hash An object literal of property:value pairs. 
1601      * @chainable
1602      */
1603     'setStyles'
1604 ];
1605 Y.Node.importMethod(Y.DOM, methods);
1606 /**
1607  * Returns an array of values for each node.
1608  * @method getStyle
1609  * @for NodeList
1610  * @see Node.getStyle
1611  * @param {String} attr The style attribute to retrieve. 
1612  * @return {Array} The current values of the style property for the element.
1613  */
1614
1615 /**
1616  * Returns an array of the computed value for each node.
1617  * @method getComputedStyle
1618  * @see Node.getComputedStyle
1619  * @param {String} attr The style attribute to retrieve. 
1620  * @return {Array} The computed values for each node.
1621  */
1622
1623 /**
1624  * Sets a style property on each node.
1625  * @method setStyle
1626  * @see Node.setStyle
1627  * @param {String} attr The style attribute to set. 
1628  * @param {String|Number} val The value. 
1629  * @chainable
1630  */
1631
1632 /**
1633  * Sets multiple style properties on each node.
1634  * @method setStyles
1635  * @see Node.setStyles
1636  * @param {Object} hash An object literal of property:value pairs. 
1637  * @chainable
1638  */
1639 Y.NodeList.importMethod(Y.Node.prototype, methods);
1640 })(Y);
1641
1642
1643 }, '3.0.0' ,{requires:['dom-style', 'node-base']});
1644 YUI.add('node-screen', function(Y) {
1645
1646 /**
1647  * Extended Node interface for managing regions and screen positioning.
1648  * Adds support for positioning elements and normalizes window size and scroll detection. 
1649  * @module node
1650  * @submodule node-screen
1651  */
1652
1653 // these are all "safe" returns, no wrapping required
1654 Y.each([
1655     /**
1656      * Returns the inner width of the viewport (exludes scrollbar). 
1657      * @config winWidth
1658      * @for Node
1659      * @type {Int}
1660      */
1661     'winWidth',
1662
1663     /**
1664      * Returns the inner height of the viewport (exludes scrollbar). 
1665      * @config winHeight
1666      * @type {Int}
1667      */
1668     'winHeight',
1669
1670     /**
1671      * Document width 
1672      * @config winHeight
1673      * @type {Int}
1674      */
1675     'docWidth',
1676
1677     /**
1678      * Document height 
1679      * @config docHeight
1680      * @type {Int}
1681      */
1682     'docHeight',
1683
1684     /**
1685      * Amount page has been scroll vertically 
1686      * @config docScrollX
1687      * @type {Int}
1688      */
1689     'docScrollX',
1690
1691     /**
1692      * Amount page has been scroll horizontally 
1693      * @config docScrollY
1694      * @type {Int}
1695      */
1696     'docScrollY'
1697     ],
1698     function(name) {
1699         Y.Node.ATTRS[name] = {
1700             getter: function() {
1701                 var args = Array.prototype.slice.call(arguments);
1702                 args.unshift(Y.Node.getDOMNode(this));
1703
1704                 return Y.DOM[name].apply(this, args);
1705             }
1706         };
1707     }
1708 );
1709
1710 Y.Node.ATTRS.scrollLeft = {
1711     getter: function() {
1712         var node = Y.Node.getDOMNode(this);
1713         return ('scrollLeft' in node) ? node.scrollLeft : Y.DOM.docScrollX(node);
1714     },
1715
1716     setter: function(val) {
1717         var node = Y.Node.getDOMNode(this);
1718         if (node) {
1719             if ('scrollLeft' in node) {
1720                 node.scrollLeft = val;
1721             } else if (node.document || node.nodeType === 9) {
1722                 Y.DOM._getWin(node).scrollTo(val, Y.DOM.docScrollY(node)); // scroll window if win or doc
1723             }
1724         } else {
1725         }
1726     }
1727 };
1728
1729 Y.Node.ATTRS.scrollTop = {
1730     getter: function() {
1731         var node = Y.Node.getDOMNode(this);
1732         return ('scrollTop' in node) ? node.scrollTop : Y.DOM.docScrollY(node);
1733     },
1734
1735     setter: function(val) {
1736         var node = Y.Node.getDOMNode(this);
1737         if (node) {
1738             if ('scrollTop' in node) {
1739                 node.scrollTop = val;
1740             } else if (node.document || node.nodeType === 9) {
1741                 Y.DOM._getWin(node).scrollTo(Y.DOM.docScrollX(node), val); // scroll window if win or doc
1742             }
1743         } else {
1744         }
1745     }
1746 };
1747
1748 Y.Node.importMethod(Y.DOM, [
1749 /**
1750  * Gets the current position of the node in page coordinates. 
1751  * @method getXY
1752  * @for Node
1753  * @return {Array} The XY position of the node
1754 */
1755     'getXY',
1756
1757 /**
1758  * Set the position of the node in page coordinates, regardless of how the node is positioned.
1759  * @method setXY
1760  * @param {Array} xy Contains X & Y values for new position (coordinates are page-based)
1761  * @chainable
1762  */
1763     'setXY',
1764
1765 /**
1766  * Gets the current position of the node in page coordinates. 
1767  * @method getX
1768  * @return {Int} The X position of the node
1769 */
1770     'getX',
1771
1772 /**
1773  * Set the position of the node in page coordinates, regardless of how the node is positioned.
1774  * @method setX
1775  * @param {Int} x X value for new position (coordinates are page-based)
1776  * @chainable
1777  */
1778     'setX',
1779
1780 /**
1781  * Gets the current position of the node in page coordinates. 
1782  * @method getY
1783  * @return {Int} The Y position of the node
1784 */
1785     'getY',
1786
1787 /**
1788  * Set the position of the node in page coordinates, regardless of how the node is positioned.
1789  * @method setY
1790  * @param {Int} y Y value for new position (coordinates are page-based)
1791  * @chainable
1792  */
1793     'setY'
1794 ]);
1795
1796 /**
1797  * Returns a region object for the node 
1798  * @config region
1799  * @for Node
1800  * @type Node
1801  */
1802 Y.Node.ATTRS.region = {
1803     getter: function() {
1804         var node = Y.Node.getDOMNode(this);
1805         if (node && !node.tagName) {
1806             if (node.nodeType === 9) { // document
1807                 node = node.documentElement;
1808             } else if (node.alert) { // window
1809                 node = node.document.documentElement;
1810             }
1811         }
1812         return Y.DOM.region(node);
1813     }
1814 };
1815     
1816 /**
1817  * Returns a region object for the node's viewport 
1818  * @config viewportRegion
1819  * @type Node
1820  */
1821 Y.Node.ATTRS.viewportRegion = {
1822     getter: function() {
1823         return Y.DOM.viewportRegion(Y.Node.getDOMNode(this));
1824     }
1825 };
1826
1827 Y.Node.importMethod(Y.DOM, 'inViewportRegion');
1828
1829 // these need special treatment to extract 2nd node arg
1830 /**
1831  * Compares the intersection of the node with another node or region 
1832  * @method intersect         
1833  * @for Node
1834  * @param {Node|Object} node2 The node or region to compare with.
1835  * @param {Object} altRegion An alternate region to use (rather than this node's). 
1836  * @return {Object} An object representing the intersection of the regions. 
1837  */
1838 Y.Node.prototype.intersect = function(node2, altRegion) {
1839     var node1 = Y.Node.getDOMNode(this);
1840     if (node2 instanceof Y.Node) { // might be a region object
1841         node2 = Y.Node.getDOMNode(node2);
1842     }
1843     return Y.DOM.intersect(node1, node2, altRegion); 
1844 };
1845
1846 /**
1847  * Determines whether or not the node is within the giving region.
1848  * @method inRegion         
1849  * @param {Node|Object} node2 The node or region to compare with.
1850  * @param {Boolean} all Whether or not all of the node must be in the region. 
1851  * @param {Object} altRegion An alternate region to use (rather than this node's). 
1852  * @return {Object} An object representing the intersection of the regions. 
1853  */
1854 Y.Node.prototype.inRegion = function(node2, all, altRegion) {
1855     var node1 = Y.Node.getDOMNode(this);
1856     if (node2 instanceof Y.Node) { // might be a region object
1857         node2 = Y.Node.getDOMNode(node2);
1858     }
1859     return Y.DOM.inRegion(node1, node2, all, altRegion); 
1860 };
1861
1862
1863 }, '3.0.0' ,{requires:['dom-screen']});
1864 YUI.add('node-pluginhost', function(Y) {
1865
1866 /**
1867  * Registers plugins to be instantiated at the class level (plugins 
1868  * which should be plugged into every instance of Node by default).
1869  *
1870  * @method Node.plug
1871  * @static
1872  *
1873  * @param {Function | Array} plugin Either the plugin class, an array of plugin classes or an array of objects (with fn and cfg properties defined)
1874  * @param {Object} config (Optional) If plugin is the plugin class, the configuration for the plugin
1875  */
1876 Y.Node.plug = function() {
1877     var args = Y.Array(arguments);
1878     args.unshift(Y.Node);
1879     Y.Plugin.Host.plug.apply(Y.Base, args);
1880     return Y.Node;
1881 };
1882
1883 /**
1884  * Unregisters any class level plugins which have been registered by the Node
1885  *
1886  * @method Node.unplug
1887  * @static
1888  *
1889  * @param {Function | Array} plugin The plugin class, or an array of plugin classes
1890  */
1891 Y.Node.unplug = function() {
1892     var args = Y.Array(arguments);
1893     args.unshift(Y.Node);
1894     Y.Plugin.Host.unplug.apply(Y.Base, args);
1895     return Y.Node;
1896 };
1897
1898 Y.mix(Y.Node, Y.Plugin.Host, false, null, 1);
1899
1900 // allow batching of plug/unplug via NodeList
1901 // doesn't use NodeList.importMethod because we need real Nodes (not tmpNode)
1902 Y.NodeList.prototype.plug = function() {
1903     var args = arguments;
1904     Y.NodeList.each(this, function(node) {
1905         Y.Node.prototype.plug.apply(Y.one(node), args);
1906     });
1907 };
1908
1909 Y.NodeList.prototype.unplug = function() {
1910     var args = arguments;
1911     Y.NodeList.each(this, function(node) {
1912         Y.Node.prototype.unplug.apply(Y.one(node), args);
1913     });
1914 };
1915
1916
1917 }, '3.0.0' ,{requires:['node-base', 'pluginhost']});
1918 YUI.add('node-event-delegate', function(Y) {
1919
1920 /**
1921  * Functionality to make the node a delegated event container
1922  * @module node
1923  * @submodule node-event-delegate
1924  */
1925
1926 /**
1927  * Functionality to make the node a delegated event container
1928  * @method delegate
1929  * @param type {String} the event type to delegate
1930  * @param fn {Function} the function to execute
1931  * @param selector {String} a selector that must match the target of the event.
1932  * @return {Event.Handle} the detach handle
1933  * @for Node
1934  */
1935 Y.Node.prototype.delegate = function(type, fn, selector) {
1936
1937     var args = Array.prototype.slice.call(arguments, 3),
1938         a = [type, fn, Y.Node.getDOMNode(this), selector];
1939     a = a.concat(args);
1940
1941     return Y.delegate.apply(Y, a);
1942 };
1943
1944
1945 }, '3.0.0' ,{requires:['node-base', 'event-delegate', 'pluginhost']});
1946
1947
1948 YUI.add('node', function(Y){}, '3.0.0' ,{skinnable:false, use:['node-base', 'node-style', 'node-screen', 'node-pluginhost', 'node-event-delegate'], requires:['dom', 'event-base', 'event-delegate', 'pluginhost']});
1949