~bjornt/lazr-js/prefetch-yui-3.5

« back to all changes in this revision

Viewing changes to src-js/lazrjs/yui/node/node.js

  • Committer: Launchpad Patch Queue Manager
  • Date: 2011-01-14 23:32:29 UTC
  • mfrom: (197.1.7 yui-3.3.0)
  • Revision ID: launchpad@pqm.canonical.com-20110114233229-r6i4cazdiiw18o7p
Upgrade to YUI 3.3.0 [r=mars]

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
Copyright (c) 2010, Yahoo! Inc. All rights reserved.
3
3
Code licensed under the BSD License:
4
4
http://developer.yahoo.com/yui/license.html
5
 
version: 3.2.0
6
 
build: 2676
 
5
version: 3.3.0
 
6
build: 3167
7
7
*/
8
8
YUI.add('node-base', function(Y) {
9
9
 
11
11
 * The Node Utility provides a DOM-like interface for interacting with DOM nodes.
12
12
 * @module node
13
13
 * @submodule node-base
14
 
 */    
 
14
 */
15
15
 
16
16
/**
17
17
 * The Node class provides a wrapper for manipulating DOM Nodes.
35
35
    TAG_NAME = 'tagName',
36
36
    UID = '_yuid',
37
37
 
 
38
    _slice = Array.prototype.slice,
 
39
 
38
40
    Y_DOM = Y.DOM,
39
41
 
40
42
    Y_Node = function(node) {
66
68
        if (this._initPlugins) { // when augmented with Plugin.Host
67
69
            this._initPlugins();
68
70
        }
 
71
 
 
72
        this.SHOW_TRANSITION = Y_Node.SHOW_TRANSITION;
 
73
        this.HIDE_TRANSITION = Y_Node.HIDE_TRANSITION;
69
74
    },
70
75
 
71
76
    // used with previous/next/ancestor tests
72
77
    _wrapFn = function(fn) {
73
78
        var ret = null;
74
79
        if (fn) {
75
 
            ret = (typeof fn === 'string') ?
 
80
            ret = (typeof fn == 'string') ?
76
81
            function(n) {
77
82
                return Y.Selector.test(n, fn);
78
 
            } : 
 
83
            } :
79
84
            function(n) {
80
85
                return fn(Y.one(n));
81
86
            };
86
91
// end "globals"
87
92
 
88
93
/**
89
 
 * The name of the component 
 
94
 * The name of the component
90
95
 * @static
91
96
 * @property NAME
92
 
 */    
 
97
 */
93
98
Y_Node.NAME = 'node';
94
99
 
95
100
/*
96
 
 * The pattern used to identify ARIA attributes 
97
 
 */    
 
101
 * The pattern used to identify ARIA attributes
 
102
 */
98
103
Y_Node.re_aria = /^(?:role$|aria-)/;
99
104
 
 
105
Y_Node.SHOW_TRANSITION = 'fadeIn';
 
106
Y_Node.HIDE_TRANSITION = 'fadeOut';
 
107
 
100
108
/**
101
 
 * List of events that route to DOM events 
 
109
 * List of events that route to DOM events
102
110
 * @static
103
111
 * @property DOM_EVENTS
104
 
 */    
 
112
 */
105
113
 
106
114
Y_Node.DOM_EVENTS = {
107
115
    abort: 1,
134
142
    mouseleave: 1,
135
143
    mousemove: 1,
136
144
    mousemultiwheel: 1,
137
 
    mouseout: 1, 
138
 
    mouseover: 1, 
 
145
    mouseout: 1,
 
146
    mouseover: 1,
139
147
    mouseup: 1,
140
148
    mousewheel: 1,
 
149
    orientationchange: 1,
141
150
    reset: 1,
142
151
    resize: 1,
143
152
    select: 1,
154
163
Y.mix(Y_Node.DOM_EVENTS, Y.Env.evt.plugins);
155
164
 
156
165
/**
157
 
 * A list of Node instances that have been created 
 
166
 * A list of Node instances that have been created
158
167
 * @private
159
168
 * @property _instances
160
169
 * @static
177
186
    }
178
187
    return null;
179
188
};
180
 
 
 
189
 
181
190
/**
182
191
 * Checks Node return values and wraps DOM Nodes as Y.Node instances
183
192
 * and DOM Collections / Arrays as Y.NodeList instances.
190
199
 * @return {Y.Node | Y.NodeList | any} Depends on what is returned from the DOM node.
191
200
 */
192
201
Y_Node.scrubVal = function(val, node) {
193
 
    if (node && val) { // only truthy values are risky
194
 
         if (typeof val === 'object' || typeof val === 'function') { // safari nodeList === function
 
202
    if (val) { // only truthy values are risky
 
203
         if (typeof val == 'object' || typeof val == 'function') { // safari nodeList === function
195
204
            if (NODE_TYPE in val || Y_DOM.isWindow(val)) {// node || window
196
205
                val = Y.one(val);
197
206
            } else if ((val.item && !val._nodes) || // dom collection or Node instance
199
208
                val = Y.all(val);
200
209
            }
201
210
        }
202
 
    } else if (val === undefined) {
 
211
    } else if (typeof val === 'undefined') {
203
212
        val = node; // for chaining
204
213
    } else if (val === null) {
205
214
        val = null; // IE: DOM null not the same as null
213
222
 * @method addMethod
214
223
 * @static
215
224
 *
216
 
 * @param {String} name The name of the method to add 
217
 
 * @param {Function} fn The function that becomes the method 
 
225
 * @param {String} name The name of the method to add
 
226
 * @param {Function} fn The function that becomes the method
218
227
 * @param {Object} context An optional context to call the method with
219
228
 * (defaults to the Node instance)
220
229
 * @return {any} Depends on what is returned from the DOM node.
221
230
 */
222
231
Y_Node.addMethod = function(name, fn, context) {
223
 
    if (name && fn && typeof fn === 'function') {
 
232
    if (name && fn && typeof fn == 'function') {
224
233
        Y_Node.prototype[name] = function() {
225
 
            context = context || this;
226
 
            var args = Y.Array(arguments, 0, true),
 
234
            var args = _slice.call(arguments),
 
235
                node = this,
227
236
                ret;
228
237
 
229
 
            if (args[0] && args[0] instanceof Y_Node) {
 
238
            if (args[0] && Y.instanceOf(args[0], Y_Node)) {
230
239
                args[0] = args[0]._node;
231
240
            }
232
241
 
233
 
            if (args[1] && args[1] instanceof Y_Node) {
 
242
            if (args[1] && Y.instanceOf(args[1], Y_Node)) {
234
243
                args[1] = args[1]._node;
235
244
            }
236
 
            args.unshift(this._node);
237
 
            ret = Y_Node.scrubVal(fn.apply(context, args), this);
 
245
            args.unshift(node._node);
 
246
 
 
247
            ret = fn.apply(node, args);
 
248
 
 
249
            if (ret) { // scrub truthy
 
250
                ret = Y_Node.scrubVal(ret, node);
 
251
            }
 
252
 
 
253
            (typeof ret != 'undefined') || (ret = node);
238
254
            return ret;
239
255
        };
240
256
    } else {
246
262
 * @method importMethod
247
263
 * @static
248
264
 *
249
 
 * @param {Object} host The object that contains the method to import. 
 
265
 * @param {Object} host The object that contains the method to import.
250
266
 * @param {String} name The name of the method to import
251
 
 * @param {String} altName An optional name to use in place of the host name 
 
267
 * @param {String} altName An optional name to use in place of the host name
252
268
 * @param {Object} context An optional context to call the method with
253
269
 */
254
270
Y_Node.importMethod = function(host, name, altName) {
255
 
    if (typeof name === 'string') {
 
271
    if (typeof name == 'string') {
256
272
        altName = altName || name;
257
273
        Y_Node.addMethod(altName, host[name], host);
258
274
    } else {
269
285
 * use <code>Y.all</code>, which returns a NodeList when no match is found.
270
286
 * @method Y.one
271
287
 * @static
272
 
 * @param {String | HTMLElement} node a node or Selector 
 
288
 * @param {String | HTMLElement} node a node or Selector
273
289
 * @return {Y.Node | null} a Node instance or null if no match found.
274
290
 */
275
291
Y_Node.one = function(node) {
278
294
        uid;
279
295
 
280
296
    if (node) {
281
 
        if (typeof node === 'string') {
 
297
        if (typeof node == 'string') {
282
298
            if (node.indexOf('doc') === 0) { // doc OR document
283
299
                node = Y.config.doc;
284
300
            } else if (node.indexOf('win') === 0) { // win OR window
289
305
            if (!node) {
290
306
                return null;
291
307
            }
292
 
        } else if (node instanceof Y_Node) {
 
308
        } else if (Y.instanceOf(node, Y_Node)) {
293
309
            return node; // NOTE: return
294
310
        }
295
311
 
306
322
};
307
323
 
308
324
/**
309
 
 * Returns a single Node instance bound to the node or the
310
 
 * first element matching the given selector.
311
 
 * @method Y.get
312
 
 * @deprecated Use Y.one
313
 
 * @static
314
 
 * @param {String | HTMLElement} node a node or Selector 
315
 
 * @param {Y.Node || HTMLElement} doc an optional document to scan. Defaults to Y.config.doc. 
316
 
 */
317
 
Y_Node.get = function() {
318
 
    return Y_Node.one.apply(Y_Node, arguments);
319
 
};
320
 
 
321
 
/**
322
 
 * Creates a new dom node using the provided markup string. 
 
325
 * Returns a new dom node using the provided markup string.
323
326
 * @method create
324
327
 * @static
325
328
 * @param {String} html The markup used to create the element
326
 
 * @param {HTMLDocument} doc An optional document context 
327
 
 * @return {Node} A Node instance bound to a DOM node or fragment 
 
329
 * @param {HTMLDocument} doc An optional document context
 
330
 * @return {Node} A Node instance bound to a DOM node or fragment
328
331
 */
329
 
Y_Node.create = function() {
330
 
    return Y.one(Y_DOM.create.apply(Y_DOM, arguments));
 
332
Y_Node.create = function(html, doc) {
 
333
    if (doc && doc._node) {
 
334
        doc = doc._node;
 
335
    }
 
336
    return Y.one(Y_DOM.create(html, doc));
331
337
};
332
338
 
333
339
/**
395
401
            Y_DOM.setValue(this._node, val);
396
402
            return val;
397
403
        }
398
 
    },
399
 
    
400
 
    
401
 
    /*
402
 
     * Flat data store for off-DOM usage 
403
 
     * @config data
404
 
     * @type any
405
 
     * @deprecated Use getData/setData
406
 
     */
407
 
    data: {
408
 
        getter: function() { 
409
 
            return this._dataVal; 
410
 
        },
411
 
        setter: function(val) { 
412
 
            this._dataVal = val;
413
 
            return val;
414
 
        },
415
 
        value: null
416
404
    }
417
405
};
418
406
 
419
407
/**
420
 
 * The default setter for DOM properties 
 
408
 * The default setter for DOM properties
421
409
 * Called with instance context (this === the Node instance)
422
410
 * @method DEFAULT_SETTER
423
411
 * @static
424
 
 * @param {String} name The attribute/property being set 
425
 
 * @param {any} val The value to be set 
 
412
 * @param {String} name The attribute/property being set
 
413
 * @param {any} val The value to be set
426
414
 * @return {any} The value
427
415
 */
428
416
Y_Node.DEFAULT_SETTER = function(name, val) {
434
422
        name = name.split(DOT);
435
423
        // only allow when defined on node
436
424
        Y.Object.setValue(node, name, val);
437
 
    } else if (node[name] !== undefined) { // pass thru DOM properties 
 
425
    } else if (typeof node[name] != 'undefined') { // pass thru DOM properties
438
426
        node[name] = val;
439
427
    }
440
428
 
442
430
};
443
431
 
444
432
/**
445
 
 * The default getter for DOM properties 
 
433
 * The default getter for DOM properties
446
434
 * Called with instance context (this === the Node instance)
447
435
 * @method DEFAULT_GETTER
448
436
 * @static
449
 
 * @param {String} name The attribute/property to look up 
 
437
 * @param {String} name The attribute/property to look up
450
438
 * @return {any} The current value
451
439
 */
452
440
Y_Node.DEFAULT_GETTER = function(name) {
455
443
 
456
444
    if (name.indexOf && name.indexOf(DOT) > -1) {
457
445
        val = Y.Object.getValue(node, name.split(DOT));
458
 
    } else if (node[name] !== undefined) { // pass thru from DOM
 
446
    } else if (typeof node[name] != 'undefined') { // pass thru from DOM
459
447
        val = node[name];
460
448
    }
461
449
 
469
457
/**
470
458
 * The method called when outputting Node instances as strings
471
459
 * @method toString
472
 
 * @return {String} A string representation of the Node instance 
 
460
 * @return {String} A string representation of the Node instance
473
461
 */
474
462
    toString: function() {
475
463
        var str = this[UID] + ': not bound to a node',
483
471
            str = node[NODE_NAME];
484
472
 
485
473
            if (id) {
486
 
                str += '#' + id; 
 
474
                str += '#' + id;
487
475
            }
488
476
 
489
477
            if (className) {
490
 
                str += '.' + className.replace(' ', '.'); 
 
478
                str += '.' + className.replace(' ', '.');
491
479
            }
492
480
 
493
481
            // TODO: add yuid?
498
486
 
499
487
    /**
500
488
     * Returns an attribute value on the Node instance.
501
 
     * Unless pre-configured (via Node.ATTRS), get hands 
 
489
     * Unless pre-configured (via Node.ATTRS), get hands
502
490
     * off to the underlying DOM node.  Only valid
503
491
     * attributes/properties for the node will be set.
504
492
     * @method get
523
511
    },
524
512
 
525
513
    /**
526
 
     * Helper method for get.  
 
514
     * Helper method for get.
527
515
     * @method _get
528
516
     * @private
529
517
     * @param {String} attr The attribute
536
524
        if (attrConfig && attrConfig.getter) {
537
525
            val = attrConfig.getter.call(this);
538
526
        } else if (Y_Node.re_aria.test(attr)) {
539
 
            val = this._node.getAttribute(attr, 2); 
 
527
            val = this._node.getAttribute(attr, 2);
540
528
        } else {
541
529
            val = Y_Node.DEFAULT_GETTER.apply(this, arguments);
542
530
        }
546
534
 
547
535
    /**
548
536
     * Sets an attribute on the Node instance.
549
 
     * Unless pre-configured (via Node.ATTRS), set hands 
 
537
     * Unless pre-configured (via Node.ATTRS), set hands
550
538
     * off to the underlying DOM node.  Only valid
551
539
     * attributes/properties for the node will be set.
552
540
     * To set custom attributes use setAttribute.
553
541
     * @method set
554
 
     * @param {String} attr The attribute to be set.  
555
 
     * @param {any} val The value to set the attribute to.  
 
542
     * @param {String} attr The attribute to be set.
 
543
     * @param {any} val The value to set the attribute to.
556
544
     * @chainable
557
545
     */
558
546
    set: function(attr, val) {
562
550
            this._setAttr.apply(this, arguments);
563
551
        } else { // use setters inline
564
552
            if (attrConfig && attrConfig.setter) {
565
 
                attrConfig.setter.call(this, val);
 
553
                attrConfig.setter.call(this, val, attr);
566
554
            } else if (Y_Node.re_aria.test(attr)) { // special case Aria
567
555
                this._node.setAttribute(attr, val);
568
556
            } else {
574
562
    },
575
563
 
576
564
    /**
577
 
     * Sets multiple attributes. 
 
565
     * Sets multiple attributes.
578
566
     * @method setAttrs
579
 
     * @param {Object} attrMap an object of name/value pairs to set  
 
567
     * @param {Object} attrMap an object of name/value pairs to set
580
568
     * @chainable
581
569
     */
582
570
    setAttrs: function(attrMap) {
584
572
            this._setAttrs(attrMap);
585
573
        } else { // use setters inline
586
574
            Y.Object.each(attrMap, function(v, n) {
587
 
                this.set(n, v); 
 
575
                this.set(n, v);
588
576
            }, this);
589
577
        }
590
578
 
592
580
    },
593
581
 
594
582
    /**
595
 
     * Returns an object containing the values for the requested attributes. 
 
583
     * Returns an object containing the values for the requested attributes.
596
584
     * @method getAttrs
597
 
     * @param {Array} attrs an array of attributes to get values  
 
585
     * @param {Array} attrs an array of attributes to get values
598
586
     * @return {Object} An object with attribute name/value pairs.
599
587
     */
600
588
    getAttrs: function(attrs) {
603
591
            this._getAttrs(attrs);
604
592
        } else { // use setters inline
605
593
            Y.Array.each(attrs, function(v, n) {
606
 
                ret[v] = this.get(v); 
 
594
                ret[v] = this.get(v);
607
595
            }, this);
608
596
        }
609
597
 
611
599
    },
612
600
 
613
601
    /**
614
 
     * Creates a new Node using the provided markup string. 
 
602
     * Creates a new Node using the provided markup string.
615
603
     * @method create
616
604
     * @param {String} html The markup used to create the element
617
 
     * @param {HTMLDocument} doc An optional document context 
618
 
     * @return {Node} A Node instance bound to a DOM node or fragment 
 
605
     * @param {HTMLDocument} doc An optional document context
 
606
     * @return {Node} A Node instance bound to a DOM node or fragment
619
607
     */
620
608
    create: Y_Node.create,
621
609
 
624
612
     * Node instances can be compared to each other and/or HTMLElements.
625
613
     * @method compareTo
626
614
     * @param {HTMLElement | Node} refNode The reference node to compare to the node.
627
 
     * @return {Boolean} True if the nodes match, false if they do not. 
 
615
     * @return {Boolean} True if the nodes match, false if they do not.
628
616
     */
629
617
    compareTo: function(refNode) {
630
618
        var node = this._node;
631
619
 
632
 
        if (refNode instanceof Y_Node) { 
 
620
        if (Y.instanceOf(refNode, Y_Node)) {
633
621
            refNode = refNode._node;
634
622
        }
635
623
        return node === refNode;
639
627
     * Determines whether the node is appended to the document.
640
628
     * @method inDoc
641
629
     * @param {Node|HTMLElement} doc optional An optional document to check against.
642
 
     * Defaults to current document. 
643
 
     * @return {Boolean} Whether or not this node is appended to the document. 
 
630
     * Defaults to current document.
 
631
     * @return {Boolean} Whether or not this node is appended to the document.
644
632
     */
645
633
    inDoc: function(doc) {
646
634
        var node = this._node;
665
653
     * Returns the nearest ancestor that passes the test applied by supplied boolean method.
666
654
     * @method ancestor
667
655
     * @param {String | Function} fn A selector string or boolean method for testing elements.
668
 
     * @param {Boolean} testSelf optional Whether or not to include the element in the scan 
 
656
     * @param {Boolean} testSelf optional Whether or not to include the element in the scan
669
657
     * If a function is used, it receives the current node being tested as the only argument.
670
658
     * @return {Node} The matching Node instance or null if not found
671
659
     */
673
661
        return Y.one(Y_DOM.ancestor(this._node, _wrapFn(fn), testSelf));
674
662
    },
675
663
 
 
664
   /**
 
665
     * Returns the ancestors that pass the test applied by supplied boolean method.
 
666
     * @method ancestors
 
667
     * @param {String | Function} fn A selector string or boolean method for testing elements.
 
668
     * @param {Boolean} testSelf optional Whether or not to include the element in the scan
 
669
     * If a function is used, it receives the current node being tested as the only argument.
 
670
     * @return {NodeList} A NodeList instance containing the matching elements 
 
671
     */
 
672
    ancestors: function(fn, testSelf) {
 
673
        return Y.all(Y_DOM.ancestors(this._node, _wrapFn(fn), testSelf));
 
674
    },
 
675
 
676
676
    /**
677
 
     * Returns the previous matching sibling. 
 
677
     * Returns the previous matching sibling.
678
678
     * Returns the nearest element node sibling if no method provided.
679
679
     * @method previous
680
680
     * @param {String | Function} fn A selector or boolean method for testing elements.
683
683
     */
684
684
    previous: function(fn, all) {
685
685
        return Y.one(Y_DOM.elementByAxis(this._node, 'previousSibling', _wrapFn(fn), all));
686
 
    }, 
 
686
    },
687
687
 
688
688
    /**
689
 
     * Returns the next matching sibling. 
 
689
     * Returns the next matching sibling.
690
690
     * Returns the nearest element node sibling if no method provided.
691
691
     * @method next
692
692
     * @param {String | Function} fn A selector or boolean method for testing elements.
698
698
    },
699
699
 
700
700
    /**
701
 
     * Returns all matching siblings. 
 
701
     * Returns all matching siblings.
702
702
     * Returns all siblings if no method provided.
703
703
     * @method siblings
704
704
     * @param {String | Function} fn A selector or boolean method for testing elements.
708
708
    siblings: function(fn) {
709
709
        return Y.all(Y_DOM.siblings(this._node, _wrapFn(fn)));
710
710
    },
711
 
        
 
711
 
712
712
    /**
713
 
     * Retrieves a Node instance of nodes based on the given CSS selector. 
 
713
     * Retrieves a Node instance of nodes based on the given CSS selector.
714
714
     * @method one
715
715
     *
716
716
     * @param {string} selector The CSS selector to test against.
721
721
    },
722
722
 
723
723
    /**
724
 
     * Retrieves a Node instance of nodes based on the given CSS selector. 
725
 
     * @method query
726
 
     * @deprecated Use one()
727
 
     * @param {string} selector The CSS selector to test against.
728
 
     * @return {Node} A Node instance for the matching HTMLElement.
729
 
     */
730
 
    query: function(selector) {
731
 
        return this.one(selector);
732
 
    },
733
 
 
734
 
    /**
735
 
     * Retrieves a nodeList based on the given CSS selector. 
 
724
     * Retrieves a nodeList based on the given CSS selector.
736
725
     * @method all
737
726
     *
738
727
     * @param {string} selector The CSS selector to test against.
745
734
        return nodelist;
746
735
    },
747
736
 
748
 
    /**
749
 
     * Retrieves a nodeList based on the given CSS selector. 
750
 
     * @method queryAll
751
 
     * @deprecated Use all()
752
 
     * @param {string} selector The CSS selector to test against.
753
 
     * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
754
 
     */
755
 
    queryAll: function(selector) {
756
 
        return this.all(selector);
757
 
    },
758
 
 
759
737
    // TODO: allow fn test
760
738
    /**
761
739
     * Test if the supplied node matches the supplied selector.
772
750
     * Removes the node from its parent.
773
751
     * Shortcut for myNode.get('parentNode').removeChild(myNode);
774
752
     * @method remove
 
753
     * @param {Boolean} destroy whether or not to call destroy() on the node
 
754
     * after removal.
775
755
     * @chainable
776
756
     *
777
757
     */
780
760
            parentNode = node.parentNode;
781
761
 
782
762
        if (parentNode) {
783
 
            parentNode.removeChild(node); 
 
763
            parentNode.removeChild(node);
784
764
        }
785
765
 
786
766
        if (destroy) {
787
 
            this.destroy(true);
 
767
            this.destroy();
788
768
        }
789
769
 
790
770
        return this;
801
781
     */
802
782
    replace: function(newNode) {
803
783
        var node = this._node;
 
784
        if (typeof newNode == 'string') {
 
785
            newNode = Y_Node.create(newNode);
 
786
        }
804
787
        node.parentNode.replaceChild(Y_Node.getDOMNode(newNode), node);
805
788
        return this;
806
789
    },
807
790
 
808
791
    /**
 
792
     * @method replaceChild
 
793
     * @for Node
 
794
     * @param {String | HTMLElement | Node} node Node to be inserted 
 
795
     * @param {HTMLElement | Node} refNode Node to be replaced 
 
796
     * @return {Node} The replaced node
 
797
     */
 
798
    replaceChild: function(node, refNode) {
 
799
        if (typeof node == 'string') {
 
800
            node = Y_DOM.create(node);
 
801
        }
 
802
 
 
803
        return Y.one(this._node.replaceChild(Y_Node.getDOMNode(node), Y_Node.getDOMNode(refNode)));
 
804
    },
 
805
 
 
806
    /**
 
807
     * @method appendChild
 
808
     * @param {String | HTMLElement | Node} node Node to be appended 
 
809
     * @return {Node} The appended node 
 
810
     */
 
811
    appendChild: function(node) {
 
812
        return Y_Node.scrubVal(this._insert(node));
 
813
    },
 
814
 
 
815
    /**
 
816
     * @method insertBefore
 
817
     * @param {String | HTMLElement | Node} newNode Node to be appended 
 
818
     * @param {HTMLElement | Node} refNode Node to be inserted before 
 
819
     * @return {Node} The inserted node 
 
820
     */
 
821
    insertBefore: function(newNode, refNode) {
 
822
        return Y.Node.scrubVal(this._insert(newNode, refNode));
 
823
    },
 
824
 
 
825
    /**
809
826
     * Removes event listeners from the node and (optionally) its subtree
810
827
     * @method purge
811
828
     * @param {Boolean} recurse (optional) Whether or not to remove listeners from the
826
843
     * node's subtree (default is false)
827
844
     *
828
845
     */
829
 
    destroy: function(recursivePurge) {
830
 
        delete Y_Node._instances[this[UID]];
831
 
        this.purge(recursivePurge);
 
846
    destroy: function(recursive) {
 
847
        this.purge(); // TODO: only remove events add via this Node
832
848
 
833
849
        if (this.unplug) { // may not be a PluginHost
834
850
            this.unplug();
835
851
        }
836
852
 
837
 
        this._node._yuid = null;
 
853
        this.clearData();
 
854
 
 
855
        if (recursive) {
 
856
            this.all('*').destroy();
 
857
        }
 
858
 
838
859
        this._node = null;
839
860
        this._stateProxy = null;
 
861
 
 
862
        delete Y_Node._instances[this[UID]];
840
863
    },
841
864
 
842
865
    /**
843
 
     * Invokes a method on the Node instance 
 
866
     * Invokes a method on the Node instance
844
867
     * @method invoke
845
868
     * @param {String} method The name of the method to invoke
846
 
     * @param {Any}  a, b, c, etc. Arguments to invoke the method with. 
847
 
     * @return Whatever the underly method returns. 
 
869
     * @param {Any}  a, b, c, etc. Arguments to invoke the method with.
 
870
     * @return Whatever the underly method returns.
848
871
     * DOM Nodes and Collections return values
849
872
     * are converted to Node/NodeList instances.
850
873
     *
853
876
        var node = this._node,
854
877
            ret;
855
878
 
856
 
        if (a && a instanceof Y_Node) {
 
879
        if (a && Y.instanceOf(a, Y_Node)) {
857
880
            a = a._node;
858
881
        }
859
882
 
860
 
        if (b && b instanceof Y_Node) {
 
883
        if (b && Y.instanceOf(b, Y_Node)) {
861
884
            b = b._node;
862
885
        }
863
886
 
864
 
        ret = node[method](a, b, c, d, e);    
 
887
        ret = node[method](a, b, c, d, e);
865
888
        return Y_Node.scrubVal(ret, this);
866
889
    },
867
890
 
868
891
    /**
869
 
     * Applies the given function to each Node in the NodeList.
870
 
     * @method each
871
 
     * @deprecated Use NodeList
872
 
     * @param {Function} fn The function to apply 
873
 
     * @param {Object} context optional An optional context to apply the function with
874
 
     * Default context is the NodeList instance
875
 
     * @chainable
876
 
     */
877
 
    each: function(fn, context) {
878
 
        context = context || this;
879
 
        return fn.call(context, this);
880
 
    },
881
 
 
882
 
    /**
883
 
     * Retrieves the Node instance at the given index. 
884
 
     * @method item
885
 
     * @deprecated Use NodeList
886
 
     *
887
 
     * @param {Number} index The index of the target Node.
888
 
     * @return {Node} The Node instance at the given index.
889
 
     */
890
 
    item: function(index) {
891
 
        return this;
892
 
    },
893
 
 
894
 
    /**
895
 
     * Returns the current number of items in the Node.
896
 
     * @method size
897
 
     * @deprecated Use NodeList
898
 
     * @return {Int} The number of items in the Node. 
899
 
     */
900
 
    size: function() {
901
 
        return this._node ? 1 : 0;
902
 
    },
903
 
 
904
 
    /**
905
 
     * Inserts the content before the reference node. 
 
892
     * Inserts the content before the reference node.
906
893
     * @method insert
907
 
     * @param {String | Y.Node | HTMLElement} content The content to insert 
 
894
     * @param {String | Y.Node | HTMLElement | Y.NodeList | HTMLCollection} content The content to insert
908
895
     * @param {Int | Y.Node | HTMLElement | String} where The position to insert at.
909
896
     * Possible "where" arguments
910
897
     * <dl>
926
913
     * @chainable
927
914
     */
928
915
    insert: function(content, where) {
929
 
        var node = this._node;
930
 
 
931
 
        if (content) {
932
 
            if (typeof where === 'number') { // allow index
933
 
                where = this._node.childNodes[where];
934
 
            } else if (where && where._node) { // Node
935
 
                where = where._node;
936
 
            }
937
 
 
938
 
            if (typeof content !== 'string') { // allow Node or NodeList/Array instances
939
 
                if (content._node) { // Node
940
 
                    content = content._node;
941
 
                } else if (content._nodes || (!content.nodeType && content.length)) { // NodeList or Array
942
 
                    content = Y.all(content);
943
 
                    Y.each(content._nodes, function(n) {
944
 
                        Y_DOM.addHTML(node, n, where);
945
 
                    });
946
 
 
947
 
                    return this; // NOTE: early return
948
 
                }
949
 
            }
950
 
            Y_DOM.addHTML(node, content, where);
951
 
        } else  {
952
 
        }
 
916
        this._insert(content, where);
953
917
        return this;
954
918
    },
955
919
 
 
920
    _insert: function(content, where) {
 
921
        var node = this._node,
 
922
            ret = null;
 
923
 
 
924
        if (typeof where == 'number') { // allow index
 
925
            where = this._node.childNodes[where];
 
926
        } else if (where && where._node) { // Node
 
927
            where = where._node;
 
928
        }
 
929
 
 
930
        if (content && typeof content != 'string') { // allow Node or NodeList/Array instances
 
931
            content = content._node || content._nodes || content;
 
932
        }
 
933
        ret = Y_DOM.addHTML(node, content, where);
 
934
 
 
935
        return ret;
 
936
    },
 
937
 
956
938
    /**
957
 
     * Inserts the content as the firstChild of the node. 
 
939
     * Inserts the content as the firstChild of the node.
958
940
     * @method prepend
959
 
     * @param {String | Y.Node | HTMLElement} content The content to insert 
 
941
     * @param {String | Y.Node | HTMLElement} content The content to insert
960
942
     * @chainable
961
943
     */
962
944
    prepend: function(content) {
964
946
    },
965
947
 
966
948
    /**
967
 
     * Inserts the content as the lastChild of the node. 
 
949
     * Inserts the content as the lastChild of the node.
968
950
     * @method append
969
 
     * @param {String | Y.Node | HTMLElement} content The content to insert 
 
951
     * @param {String | Y.Node | HTMLElement} content The content to insert
970
952
     * @chainable
971
953
     */
972
954
    append: function(content) {
974
956
    },
975
957
 
976
958
    /**
 
959
     * Appends the node to the given node. 
 
960
     * @method appendTo
 
961
     * @param {Y.Node | HTMLElement} node The node to append to
 
962
     * @chainable
 
963
     */
 
964
    appendTo: function(node) {
 
965
        Y.one(node).append(this);
 
966
        return this;
 
967
    },
 
968
 
 
969
    /**
977
970
     * Replaces the node's current content with the content.
978
971
     * @method setContent
979
 
     * @param {String | Y.Node | HTMLElement} content The content to insert 
 
972
     * @param {String | Y.Node | HTMLElement | Y.NodeList | HTMLCollection} content The content to insert
980
973
     * @chainable
981
974
     */
982
975
    setContent: function(content) {
983
 
        if (content) {
984
 
            if (content._node) { // map to DOMNode
985
 
                content = content._node;
986
 
            } else if (content._nodes) { // convert DOMNodeList to documentFragment
987
 
                content = Y_DOM._nl2frag(content._nodes);
988
 
            }
989
 
 
990
 
        }
991
 
 
992
 
        Y_DOM.addHTML(this._node, content, 'replace');
 
976
        this._insert(content, 'replace');
993
977
        return this;
994
978
    },
995
979
 
996
980
    /**
 
981
     * Returns the node's current content (e.g. innerHTML) 
 
982
     * @method getContent
 
983
     * @return {String} The current content
 
984
     */
 
985
    getContent: function(content) {
 
986
        return this.get('innerHTML');
 
987
    },
 
988
 
 
989
    /**
997
990
    * @method swap
998
991
    * @description Swap DOM locations with the given node.
999
992
    * This does not change which DOM node each Node instance refers to.
1000
993
    * @param {Node} otherNode The node to swap with
1001
994
     * @chainable
1002
995
    */
1003
 
    swap: Y.config.doc.documentElement.swapNode ? 
 
996
    swap: Y.config.doc.documentElement.swapNode ?
1004
997
        function(otherNode) {
1005
998
            this._node.swapNode(Y_Node.getDOMNode(otherNode));
1006
999
        } :
1041
1034
        }
1042
1035
 
1043
1036
        return ret;
1044
 
        
 
1037
 
1045
1038
    },
1046
1039
 
1047
1040
    /**
1060
1053
        } else {
1061
1054
            this._data = name;
1062
1055
        }
1063
 
       
 
1056
 
1064
1057
       return this;
1065
1058
    },
1066
1059
 
1067
1060
    /**
1068
1061
    * @method clearData
1069
 
    * @description Clears stored data. 
 
1062
    * @description Clears stored data.
1070
1063
    * @param {string} name The name of the field to clear. If no name
1071
 
    * is given, all data is cleared..
 
1064
    * is given, all data is cleared.
1072
1065
    * @chainable
1073
1066
    */
1074
1067
    clearData: function(name) {
1075
 
        if (this._data && arguments.length) {
1076
 
            delete this._data[name];
1077
 
        } else {
1078
 
            this._data = {};
 
1068
        if ('_data' in this) {
 
1069
            if (name) {
 
1070
                delete this._data[name];
 
1071
            } else {
 
1072
                delete this._data;
 
1073
            }
1079
1074
        }
1080
1075
 
1081
1076
        return this;
1084
1079
    hasMethod: function(method) {
1085
1080
        var node = this._node;
1086
1081
        return !!(node && method in node &&
1087
 
                typeof node[method] !== 'unknown' &&
1088
 
            (typeof node[method] === 'function' ||
 
1082
                typeof node[method] != 'unknown' &&
 
1083
            (typeof node[method] == 'function' ||
1089
1084
                String(node[method]).indexOf('function') === 1)); // IE reports as object, prepends space
 
1085
    },
 
1086
 
 
1087
    SHOW_TRANSITION: null,
 
1088
    HIDE_TRANSITION: null,
 
1089
 
 
1090
    /**
 
1091
     * Makes the node visible.
 
1092
     * If the "transition" module is loaded, show optionally
 
1093
     * animates the showing of the node using either the default
 
1094
     * transition effect ('fadeIn'), or the given named effect.
 
1095
     * @method show
 
1096
     * @param {String} name A named Transition effect to use as the show effect. 
 
1097
     * @param {Object} config Options to use with the transition. 
 
1098
     * @param {Function} callback An optional function to run after the transition completes. 
 
1099
     * @chainable
 
1100
     */
 
1101
    show: function(callback) {
 
1102
        callback = arguments[arguments.length - 1];
 
1103
        this.toggleView(true, callback);
 
1104
        return this;
 
1105
    },
 
1106
 
 
1107
    /**
 
1108
     * The implementation for showing nodes.
 
1109
     * Default is to toggle the style.display property.
 
1110
     * @protected
 
1111
     * @chainable
 
1112
     */
 
1113
    _show: function() {
 
1114
        this.setStyle('display', '');
 
1115
 
 
1116
    },
 
1117
 
 
1118
    _isHidden: function() {
 
1119
        return Y.DOM.getStyle(this._node, 'display') === 'none';
 
1120
    },
 
1121
 
 
1122
    toggleView: function(on, callback) {
 
1123
        this._toggleView.apply(this, arguments);
 
1124
    },
 
1125
 
 
1126
    _toggleView: function(on, callback) {
 
1127
        callback = arguments[arguments.length - 1];
 
1128
 
 
1129
        // base on current state if not forcing 
 
1130
        if (typeof on != 'boolean') {
 
1131
            on = (this._isHidden()) ? 1 : 0;
 
1132
        }
 
1133
 
 
1134
        if (on) {
 
1135
            this._show();
 
1136
        }  else {
 
1137
            this._hide();
 
1138
        }
 
1139
 
 
1140
        if (typeof callback == 'function') {
 
1141
            callback.call(this);
 
1142
        }
 
1143
 
 
1144
        return this;
 
1145
    },
 
1146
 
 
1147
    /**
 
1148
     * Hides the node.
 
1149
     * If the "transition" module is loaded, hide optionally
 
1150
     * animates the hiding of the node using either the default
 
1151
     * transition effect ('fadeOut'), or the given named effect.
 
1152
     * @method hide
 
1153
     * @param {String} name A named Transition effect to use as the show effect. 
 
1154
     * @param {Object} config Options to use with the transition. 
 
1155
     * @param {Function} callback An optional function to run after the transition completes. 
 
1156
     * @chainable
 
1157
     */
 
1158
    hide: function(callback) {
 
1159
        callback = arguments[arguments.length - 1];
 
1160
        this.toggleView(false, callback);
 
1161
        return this;
 
1162
    },
 
1163
 
 
1164
    /**
 
1165
     * The implementation for hiding nodes.
 
1166
     * Default is to toggle the style.display property.
 
1167
     * @protected
 
1168
     * @chainable
 
1169
     */
 
1170
    _hide: function() {
 
1171
        this.setStyle('display', 'none');
 
1172
    },
 
1173
 
 
1174
    isFragment: function() {
 
1175
        return (this.get('nodeType') === 11);
 
1176
    },
 
1177
 
 
1178
    /**
 
1179
     * Removes all of the child nodes from the node.
 
1180
     * @param {Boolean} destroy Whether the nodes should also be destroyed. 
 
1181
     * @chainable
 
1182
     */
 
1183
    empty: function(destroy) {
 
1184
        this.get('childNodes').remove(destroy);
 
1185
        return this;
1090
1186
    }
 
1187
 
1091
1188
}, true);
1092
1189
 
1093
1190
Y.Node = Y_Node;
1094
 
Y.get = Y.Node.get;
1095
1191
Y.one = Y.Node.one;
1096
1192
/**
1097
1193
 * The NodeList module provides support for managing collections of Nodes.
1098
1194
 * @module node
1099
1195
 * @submodule nodelist
1100
 
 */    
 
1196
 */
1101
1197
 
1102
1198
/**
1103
1199
 * The NodeList class provides a wrapper for manipulating DOM NodeLists.
1115
1211
        nodes = Y.Selector.query(nodes);
1116
1212
    } else if (nodes.nodeType || Y_DOM.isWindow(nodes)) { // domNode || window
1117
1213
        nodes = [nodes];
1118
 
    } else if (nodes instanceof Y.Node) {
 
1214
    } else if (Y.instanceOf(nodes, Y.Node)) {
1119
1215
        nodes = [nodes._node];
1120
 
    } else if (nodes[0] instanceof Y.Node) { // allow array of Y.Nodes
 
1216
    } else if (Y.instanceOf(nodes[0], Y.Node)) { // allow array of Y.Nodes
1121
1217
        Y.Array.each(nodes, function(node) {
1122
1218
            if (node._node) {
1123
1219
                tmp.push(node._node);
1143
1239
 * @method NodeList.getDOMNodes
1144
1240
 * @static
1145
1241
 *
1146
 
 * @param {Y.NodeList} node The NodeList instance
 
1242
 * @param {Y.NodeList} nodelist The NodeList instance
1147
1243
 * @return {Array} The array of DOM nodes bound to the NodeList
1148
1244
 */
1149
 
NodeList.getDOMNodes = function(nodeList) {
1150
 
    return nodeList._nodes;
 
1245
NodeList.getDOMNodes = function(nodelist) {
 
1246
    return (nodelist && nodelist._nodes) ? nodelist._nodes : nodelist;
1151
1247
};
1152
1248
 
1153
1249
NodeList.each = function(instance, fn, context) {
1212
1308
 
1213
1309
Y.mix(NodeList.prototype, {
1214
1310
    /**
1215
 
     * Retrieves the Node instance at the given index. 
 
1311
     * Retrieves the Node instance at the given index.
1216
1312
     * @method item
1217
1313
     *
1218
1314
     * @param {Number} index The index of the target Node.
1273
1369
    },
1274
1370
 
1275
1371
    /**
1276
 
     * Creates a documenFragment from the nodes bound to the NodeList instance 
 
1372
     * Creates a documenFragment from the nodes bound to the NodeList instance
1277
1373
     * @method toFrag
1278
1374
     * @return Node a Node instance bound to the documentFragment
1279
1375
     */
1296
1392
     * Filters the NodeList instance down to only nodes matching the given selector.
1297
1393
     * @method filter
1298
1394
     * @param {String} selector The selector to filter against
1299
 
     * @return {NodeList} NodeList containing the updated collection 
 
1395
     * @return {NodeList} NodeList containing the updated collection
1300
1396
     * @see Selector
1301
1397
     */
1302
1398
    filter: function(selector) {
1305
1401
 
1306
1402
 
1307
1403
    /**
1308
 
     * Creates a new NodeList containing all nodes at every n indices, where 
 
1404
     * Creates a new NodeList containing all nodes at every n indices, where
1309
1405
     * remainder n % index equals r.
1310
1406
     * (zero-based index).
1311
1407
     * @method modulus
1312
1408
     * @param {Int} n The offset to use (return every nth node)
1313
 
     * @param {Int} r An optional remainder to use with the modulus operation (defaults to zero) 
1314
 
     * @return {NodeList} NodeList containing the updated collection 
 
1409
     * @param {Int} r An optional remainder to use with the modulus operation (defaults to zero)
 
1410
     * @return {NodeList} NodeList containing the updated collection
1315
1411
     */
1316
1412
    modulus: function(n, r) {
1317
1413
        r = r || 0;
1329
1425
     * Creates a new NodeList containing all nodes at odd indices
1330
1426
     * (zero-based index).
1331
1427
     * @method odd
1332
 
     * @return {NodeList} NodeList containing the updated collection 
 
1428
     * @return {NodeList} NodeList containing the updated collection
1333
1429
     */
1334
1430
    odd: function() {
1335
1431
        return this.modulus(2, 1);
1337
1433
 
1338
1434
    /**
1339
1435
     * Creates a new NodeList containing all nodes at even indices
1340
 
     * (zero-based index), including zero. 
 
1436
     * (zero-based index), including zero.
1341
1437
     * @method even
1342
 
     * @return {NodeList} NodeList containing the updated collection 
 
1438
     * @return {NodeList} NodeList containing the updated collection
1343
1439
     */
1344
1440
    even: function() {
1345
1441
        return this.modulus(2);
1349
1445
    },
1350
1446
 
1351
1447
    /**
1352
 
     * Reruns the initial query, when created using a selector query 
 
1448
     * Reruns the initial query, when created using a selector query
1353
1449
     * @method refresh
1354
1450
     * @chainable
1355
1451
     */
1388
1484
    },
1389
1485
 
1390
1486
    /**
1391
 
     * Applies an event listener to each Node bound to the NodeList. 
 
1487
     * Applies an event listener to each Node bound to the NodeList.
1392
1488
     * @method on
1393
1489
     * @param {String} type The event being listened for
1394
1490
     * @param {Function} fn The handler to call when the event fires
1395
1491
     * @param {Object} context The context to call the handler with.
1396
 
     * Default is the NodeList instance. 
1397
 
     * @return {Object} Returns an event handle that can later be use to detach(). 
 
1492
     * Default is the NodeList instance.
 
1493
     * @param {Object} context The context to call the handler with.
 
1494
     * param {mixed} arg* 0..n additional arguments to supply to the subscriber
 
1495
     * when the event fires.
 
1496
     * @return {Object} Returns an event handle that can later be use to detach().
1398
1497
     * @see Event.on
1399
1498
     */
1400
1499
    on: function(type, fn, context) {
1402
1501
    },
1403
1502
 
1404
1503
    /**
1405
 
     * Applies an event listener to each Node bound to the NodeList. 
 
1504
     * Applies an one-time event listener to each Node bound to the NodeList.
 
1505
     * @method once
 
1506
     * @param {String} type The event being listened for
 
1507
     * @param {Function} fn The handler to call when the event fires
 
1508
     * @param {Object} context The context to call the handler with.
 
1509
     * Default is the NodeList instance.
 
1510
     * @return {Object} Returns an event handle that can later be use to detach().
 
1511
     * @see Event.on
 
1512
     */
 
1513
    once: function(type, fn, context) {
 
1514
        return Y.once.apply(Y, this._prepEvtArgs.apply(this, arguments));
 
1515
    },
 
1516
 
 
1517
    /**
 
1518
     * Applies an event listener to each Node bound to the NodeList.
1406
1519
     * The handler is called only after all on() handlers are called
1407
1520
     * and the event is not prevented.
1408
1521
     * @method after
1409
1522
     * @param {String} type The event being listened for
1410
1523
     * @param {Function} fn The handler to call when the event fires
1411
1524
     * @param {Object} context The context to call the handler with.
1412
 
     * Default is the NodeList instance. 
1413
 
     * @return {Object} Returns an event handle that can later be use to detach(). 
 
1525
     * Default is the NodeList instance.
 
1526
     * @return {Object} Returns an event handle that can later be use to detach().
1414
1527
     * @see Event.on
1415
1528
     */
1416
1529
    after: function(type, fn, context) {
1420
1533
    /**
1421
1534
     * Returns the current number of items in the NodeList.
1422
1535
     * @method size
1423
 
     * @return {Int} The number of items in the NodeList. 
 
1536
     * @return {Int} The number of items in the NodeList.
1424
1537
     */
1425
1538
    size: function() {
1426
1539
        return this._nodes.length;
1429
1542
    /**
1430
1543
     * Determines if the instance is bound to any nodes
1431
1544
     * @method isEmpty
1432
 
     * @return {Boolean} Whether or not the NodeList is bound to any nodes 
 
1545
     * @return {Boolean} Whether or not the NodeList is bound to any nodes
1433
1546
     */
1434
1547
    isEmpty: function() {
1435
1548
        return this._nodes.length < 1;
1445
1558
            node = nodes[0];
1446
1559
            str += node[NODE_NAME];
1447
1560
            if (node.id) {
1448
 
                str += '#' + node.id; 
 
1561
                str += '#' + node.id;
1449
1562
            }
1450
1563
 
1451
1564
            if (node.className) {
1452
 
                str += '.' + node.className.replace(' ', '.'); 
 
1565
                str += '.' + node.className.replace(' ', '.');
1453
1566
            }
1454
1567
 
1455
1568
            if (nodes.length > 1) {
1470
1583
     */
1471
1584
    'append',
1472
1585
 
 
1586
    /** Called on each Node instance
 
1587
      * @method destroy
 
1588
      * @see Node.destroy
 
1589
      */
 
1590
    'destroy',
 
1591
 
1473
1592
    /**
1474
1593
      * Called on each Node instance
1475
1594
      * @method detach
1476
1595
      * @see Node.detach
1477
1596
      */
1478
1597
    'detach',
1479
 
    
 
1598
 
1480
1599
    /** Called on each Node instance
1481
1600
      * @method detachAll
1482
1601
      * @see Node.detachAll
1484
1603
    'detachAll',
1485
1604
 
1486
1605
    /** Called on each Node instance
 
1606
      * @method empty
 
1607
      * @see Node.empty
 
1608
      */
 
1609
    'empty',
 
1610
 
 
1611
    /** Called on each Node instance
1487
1612
      * @method insert
1488
 
      * @see NodeInsert
 
1613
      * @see Node.insert
1489
1614
      */
1490
1615
    'insert',
1491
1616
 
1511
1636
      * @method setContent
1512
1637
      * @see Node.setContent
1513
1638
      */
1514
 
    'setContent'
 
1639
    'setContent',
 
1640
 
 
1641
    /**
 
1642
     * Makes each node visible.
 
1643
     * If the "transition" module is loaded, show optionally
 
1644
     * animates the showing of the node using either the default
 
1645
     * transition effect ('fadeIn'), or the given named effect.
 
1646
     * @method show
 
1647
     * @param {String} name A named Transition effect to use as the show effect. 
 
1648
     * @param {Object} config Options to use with the transition. 
 
1649
     * @param {Function} callback An optional function to run after the transition completes. 
 
1650
     * @chainable
 
1651
     */
 
1652
    'show',
 
1653
 
 
1654
    /**
 
1655
     * Hides each node.
 
1656
     * If the "transition" module is loaded, hide optionally
 
1657
     * animates the hiding of the node using either the default
 
1658
     * transition effect ('fadeOut'), or the given named effect.
 
1659
     * @method hide
 
1660
     * @param {String} name A named Transition effect to use as the show effect. 
 
1661
     * @param {Object} config Options to use with the transition. 
 
1662
     * @param {Function} callback An optional function to run after the transition completes. 
 
1663
     * @chainable
 
1664
     */
 
1665
    'hide',
 
1666
 
 
1667
    'toggleView'
1515
1668
]);
1516
1669
 
1517
1670
// one-off implementation to convert array of Nodes to NodeList
1565
1718
Y.Array.each([
1566
1719
    /**
1567
1720
     * Passes through to DOM method.
1568
 
     * @method replaceChild
1569
1721
     * @for Node
1570
 
     * @param {HTMLElement | Node} node Node to be inserted 
1571
 
     * @param {HTMLElement | Node} refNode Node to be replaced 
1572
 
     * @return {Node} The replaced node 
1573
 
     */
1574
 
    'replaceChild',
1575
 
 
1576
 
    /**
1577
 
     * Passes through to DOM method.
1578
 
     * @method appendChild
1579
 
     * @param {HTMLElement | Node} node Node to be appended 
1580
 
     * @return {Node} The appended node 
1581
 
     */
1582
 
    'appendChild',
1583
 
 
1584
 
    /**
1585
 
     * Passes through to DOM method.
1586
 
     * @method insertBefore
1587
 
     * @param {HTMLElement | Node} newNode Node to be appended 
1588
 
     * @param {HTMLElement | Node} refNode Node to be inserted before 
1589
 
     * @return {Node} The inserted node 
1590
 
     */
1591
 
    'insertBefore',
1592
 
 
1593
 
    /**
1594
 
     * Passes through to DOM method.
1595
1722
     * @method removeChild
1596
1723
     * @param {HTMLElement | Node} node Node to be removed 
1597
1724
     * @return {Node} The removed node 
1680
1807
     * @method select
1681
1808
     * @chainable
1682
1809
     */
1683
 
     'select'
 
1810
     'select',
 
1811
 
 
1812
    /**
 
1813
     * Passes through to DOM method.
 
1814
     * Only valid on TABLE elements
 
1815
     * @method createCaption
 
1816
     * @chainable
 
1817
     */
 
1818
    'createCaption'
 
1819
 
1684
1820
], function(method) {
1685
1821
    Y.Node.prototype[method] = function(arg1, arg2, arg3) {
1686
1822
        var ret = this.invoke(method, arg1, arg2, arg3);
1716
1852
     * @param {string} name The attribute name 
1717
1853
     * @return {string} The attribute value 
1718
1854
     */
1719
 
    'getAttribute'
 
1855
    'getAttribute',
 
1856
 
 
1857
    /**
 
1858
     * Wraps the given HTML around the node.
 
1859
     * @method wrap
 
1860
     * @param {String} html The markup to wrap around the node. 
 
1861
     * @chainable
 
1862
     */
 
1863
    'wrap',
 
1864
 
 
1865
    /**
 
1866
     * Removes the node's parent node. 
 
1867
     * @method unwrap
 
1868
     * @chainable
 
1869
     */
 
1870
    'unwrap',
 
1871
 
 
1872
    /**
 
1873
     * Applies a unique ID to the node if none exists
 
1874
     * @method generateID
 
1875
     * @return {String} The existing or generated ID
 
1876
     */
 
1877
    'generateID'
1720
1878
]);
1721
1879
 
 
1880
Y.NodeList.importMethod(Y.Node.prototype, [
 
1881
/**
 
1882
 * Allows getting attributes on DOM nodes, normalizing in some cases.
 
1883
 * This passes through to the DOM node, allowing for custom attributes.
 
1884
 * @method getAttribute
 
1885
 * @see Node
 
1886
 * @for NodeList
 
1887
 * @param {string} name The attribute name 
 
1888
 * @return {string} The attribute value 
 
1889
 */
 
1890
 
 
1891
    'getAttribute',
1722
1892
/**
1723
1893
 * Allows setting attributes on DOM nodes, normalizing in some cases.
1724
1894
 * This passes through to the DOM node, allowing for custom attributes.
1729
1899
 * @param {string} name The attribute name 
1730
1900
 * @param {string} value The value to set
1731
1901
 */
1732
 
 
1733
 
/**
1734
 
 * Allows getting attributes on DOM nodes, normalizing in some cases.
1735
 
 * This passes through to the DOM node, allowing for custom attributes.
1736
 
 * @method getAttribute
1737
 
 * @see Node
1738
 
 * @for NodeList
1739
 
 * @param {string} name The attribute name 
1740
 
 * @return {string} The attribute value 
1741
 
 */
1742
 
 
 
1902
    'setAttribute',
 
1903
 
1743
1904
/**
1744
1905
 * Allows for removing attributes on DOM nodes.
1745
1906
 * This passes through to the DOM node, allowing for custom attributes.
1748
1909
 * @for NodeList
1749
1910
 * @param {string} name The attribute to remove 
1750
1911
 */
1751
 
Y.NodeList.importMethod(Y.Node.prototype, ['getAttribute', 'setAttribute', 'removeAttribute']);
 
1912
    'removeAttribute',
 
1913
/**
 
1914
 * Removes the parent node from node in the list. 
 
1915
 * @method unwrap
 
1916
 * @chainable
 
1917
 */
 
1918
    'unwrap',
 
1919
/**
 
1920
 * Wraps the given HTML around each node.
 
1921
 * @method wrap
 
1922
 * @param {String} html The markup to wrap around the node. 
 
1923
 * @chainable
 
1924
 */
 
1925
    'wrap',
 
1926
 
 
1927
/**
 
1928
 * Applies a unique ID to each node if none exists
 
1929
 * @method generateID
 
1930
 * @return {String} The existing or generated ID
 
1931
 */
 
1932
    'generateID'
 
1933
]);
1752
1934
(function(Y) {
1753
1935
    var methods = [
1754
1936
    /**
1756
1938
     * @method hasClass
1757
1939
     * @for Node
1758
1940
     * @param {String} className the class name to search for
1759
 
     * @return {Array} An array of booleans for each node bound to the NodeList. 
 
1941
     * @return {Boolean} Whether or not the element has the specified class 
1760
1942
     */
1761
1943
     'hasClass',
1762
1944
 
1790
1972
     * If the className exists on the node it is removed, if it doesn't exist it is added.
1791
1973
     * @method toggleClass  
1792
1974
     * @param {String} className the class name to be toggled
 
1975
     * @param {Boolean} force Option to force adding or removing the class. 
1793
1976
     * @chainable
1794
1977
     */
1795
1978
     'toggleClass'
1853
2036
    };
1854
2037
}
1855
2038
 
 
2039
// IE throws an error when calling focus() on an element that's invisible, not
 
2040
// displayed, or disabled.
 
2041
Y.Node.prototype.focus = function () {
 
2042
    try {
 
2043
        this._node.focus();
 
2044
    } catch (e) {
 
2045
    }
 
2046
};
 
2047
 
1856
2048
// IE throws error when setting input.type = 'hidden',
1857
2049
// input.setAttribute('type', 'hidden') and input.attributes.type.value = 'hidden'
1858
2050
Y.Node.ATTRS.type = {
1928
2120
        });
1929
2121
    }
1930
2122
});
1931
 
 
1932
 
 
1933
 
}, '3.2.0' ,{requires:['dom-base', 'selector-css2', 'event-base']});
 
2123
var Y_NodeList = Y.NodeList,
 
2124
    ArrayProto = Array.prototype,
 
2125
    ArrayMethods = [
 
2126
        /** Returns a new NodeList combining the given NodeList(s) 
 
2127
          * @for NodeList
 
2128
          * @method concat
 
2129
          * @param {NodeList | Array} valueN Arrays/NodeLists and/or values to
 
2130
          * concatenate to the resulting NodeList
 
2131
          * @return {NodeList} A new NodeList comprised of this NodeList joined with the input.
 
2132
          */
 
2133
        'concat',
 
2134
        /** Removes the first last from the NodeList and returns it.
 
2135
          * @for NodeList
 
2136
          * @method pop
 
2137
          * @return {Node} The last item in the NodeList.
 
2138
          */
 
2139
        'pop',
 
2140
        /** Adds the given Node(s) to the end of the NodeList. 
 
2141
          * @for NodeList
 
2142
          * @method push
 
2143
          * @param {Node | DOMNode} nodeN One or more nodes to add to the end of the NodeList. 
 
2144
          */
 
2145
        'push',
 
2146
        /** Removes the first item from the NodeList and returns it.
 
2147
          * @for NodeList
 
2148
          * @method shift
 
2149
          * @return {Node} The first item in the NodeList.
 
2150
          */
 
2151
        'shift',
 
2152
        /** Returns a new NodeList comprising the Nodes in the given range. 
 
2153
          * @for NodeList
 
2154
          * @method slice
 
2155
          * @param {Number} begin Zero-based index at which to begin extraction.
 
2156
          As a negative index, start indicates an offset from the end of the sequence. slice(-2) extracts the second-to-last element and the last element in the sequence.
 
2157
          * @param {Number} end Zero-based index at which to end extraction. slice extracts up to but not including end.
 
2158
          slice(1,4) extracts the second element through the fourth element (elements indexed 1, 2, and 3).
 
2159
          As a negative index, end indicates an offset from the end of the sequence. slice(2,-1) extracts the third element through the second-to-last element in the sequence.
 
2160
          If end is omitted, slice extracts to the end of the sequence.
 
2161
          * @return {NodeList} A new NodeList comprised of this NodeList joined with the input.
 
2162
          */
 
2163
        'slice',
 
2164
        /** Changes the content of the NodeList, adding new elements while removing old elements.
 
2165
          * @for NodeList
 
2166
          * @method splice
 
2167
          * @param {Number} index Index at which to start changing the array. If negative, will begin that many elements from the end.
 
2168
          * @param {Number} howMany An integer indicating the number of old array elements to remove. If howMany is 0, no elements are removed. In this case, you should specify at least one new element. If no howMany parameter is specified (second syntax above, which is a SpiderMonkey extension), all elements after index are removed.
 
2169
          * {Node | DOMNode| element1, ..., elementN 
 
2170
          The elements to add to the array. If you don't specify any elements, splice simply removes elements from the array.
 
2171
          * @return {NodeList} The element(s) removed.
 
2172
          */
 
2173
        'splice',
 
2174
        /** Adds the given Node(s) to the beginning of the NodeList. 
 
2175
          * @for NodeList
 
2176
          * @method push
 
2177
          * @param {Node | DOMNode} nodeN One or more nodes to add to the NodeList. 
 
2178
          */
 
2179
        'unshift'
 
2180
    ];
 
2181
 
 
2182
 
 
2183
Y.Array.each(ArrayMethods, function(name) {
 
2184
    Y_NodeList.prototype[name] = function() {
 
2185
        var args = [],
 
2186
            i = 0,
 
2187
            arg;
 
2188
 
 
2189
        while ((arg = arguments[i++])) { // use DOM nodes/nodeLists 
 
2190
            args.push(arg._node || arg._nodes || arg);
 
2191
        }
 
2192
        return Y.Node.scrubVal(ArrayProto[name].apply(this._nodes, args));
 
2193
    };
 
2194
});
 
2195
 
 
2196
 
 
2197
}, '3.3.0' ,{requires:['dom-base', 'selector-css2', 'event-base']});
1934
2198
YUI.add('node-style', function(Y) {
1935
2199
 
1936
2200
(function(Y) {
2013
2277
})(Y);
2014
2278
 
2015
2279
 
2016
 
}, '3.2.0' ,{requires:['dom-style', 'node-base']});
 
2280
}, '3.3.0' ,{requires:['dom-style', 'node-base']});
2017
2281
YUI.add('node-screen', function(Y) {
2018
2282
 
2019
2283
/**
2175
2439
]);
2176
2440
 
2177
2441
/**
2178
 
 * Returns a region object for the node 
 
2442
 * Returns a region object for the node
2179
2443
 * @config region
2180
2444
 * @for Node
2181
2445
 * @type Node
2195
2459
        } else {
2196
2460
            region = Y.DOM.region(node);
2197
2461
        }
2198
 
        return region; 
 
2462
        return region;
2199
2463
    }
2200
2464
};
2201
 
    
 
2465
 
2202
2466
/**
2203
 
 * Returns a region object for the node's viewport 
 
2467
 * Returns a region object for the node's viewport
2204
2468
 * @config viewportRegion
2205
2469
 * @type Node
2206
2470
 */
2214
2478
 
2215
2479
// these need special treatment to extract 2nd node arg
2216
2480
/**
2217
 
 * Compares the intersection of the node with another node or region 
2218
 
 * @method intersect         
 
2481
 * Compares the intersection of the node with another node or region
 
2482
 * @method intersect
2219
2483
 * @for Node
2220
2484
 * @param {Node|Object} node2 The node or region to compare with.
2221
 
 * @param {Object} altRegion An alternate region to use (rather than this node's). 
2222
 
 * @return {Object} An object representing the intersection of the regions. 
 
2485
 * @param {Object} altRegion An alternate region to use (rather than this node's).
 
2486
 * @return {Object} An object representing the intersection of the regions.
2223
2487
 */
2224
2488
Y.Node.prototype.intersect = function(node2, altRegion) {
2225
2489
    var node1 = Y.Node.getDOMNode(this);
2226
 
    if (node2 instanceof Y.Node) { // might be a region object
 
2490
    if (Y.instanceOf(node2, Y.Node)) { // might be a region object
2227
2491
        node2 = Y.Node.getDOMNode(node2);
2228
2492
    }
2229
 
    return Y.DOM.intersect(node1, node2, altRegion); 
 
2493
    return Y.DOM.intersect(node1, node2, altRegion);
2230
2494
};
2231
2495
 
2232
2496
/**
2233
2497
 * Determines whether or not the node is within the giving region.
2234
 
 * @method inRegion         
 
2498
 * @method inRegion
2235
2499
 * @param {Node|Object} node2 The node or region to compare with.
2236
 
 * @param {Boolean} all Whether or not all of the node must be in the region. 
2237
 
 * @param {Object} altRegion An alternate region to use (rather than this node's). 
2238
 
 * @return {Object} An object representing the intersection of the regions. 
 
2500
 * @param {Boolean} all Whether or not all of the node must be in the region.
 
2501
 * @param {Object} altRegion An alternate region to use (rather than this node's).
 
2502
 * @return {Object} An object representing the intersection of the regions.
2239
2503
 */
2240
2504
Y.Node.prototype.inRegion = function(node2, all, altRegion) {
2241
2505
    var node1 = Y.Node.getDOMNode(this);
2242
 
    if (node2 instanceof Y.Node) { // might be a region object
 
2506
    if (Y.instanceOf(node2, Y.Node)) { // might be a region object
2243
2507
        node2 = Y.Node.getDOMNode(node2);
2244
2508
    }
2245
 
    return Y.DOM.inRegion(node1, node2, all, altRegion); 
 
2509
    return Y.DOM.inRegion(node1, node2, all, altRegion);
2246
2510
};
2247
2511
 
2248
2512
 
2249
 
}, '3.2.0' ,{requires:['dom-screen']});
 
2513
}, '3.3.0' ,{requires:['dom-screen']});
2250
2514
YUI.add('node-pluginhost', function(Y) {
2251
2515
 
2252
2516
/**
2300
2564
};
2301
2565
 
2302
2566
 
2303
 
}, '3.2.0' ,{requires:['node-base', 'pluginhost']});
 
2567
}, '3.3.0' ,{requires:['node-base', 'pluginhost']});
2304
2568
YUI.add('node-event-delegate', function(Y) {
2305
2569
 
2306
2570
/**
2343
2607
 * @return {EventHandle} the detach handle
2344
2608
 * @for Node
2345
2609
 */
2346
 
Y.Node.prototype.delegate = function(type, fn, selector) {
2347
 
 
2348
 
    var args = Y.Array(arguments, 0, true);
2349
 
 
2350
 
    args.splice(2, 0, this._node);
 
2610
Y.Node.prototype.delegate = function(type) {
 
2611
 
 
2612
    var args = Y.Array(arguments, 0, true),
 
2613
        index = (Y.Lang.isObject(type) && !Y.Lang.isArray(type)) ? 1 : 2;
 
2614
 
 
2615
    args.splice(index, 0, this._node);
2351
2616
 
2352
2617
    return Y.delegate.apply(Y, args);
2353
2618
};
2354
2619
 
2355
2620
 
2356
 
}, '3.2.0' ,{requires:['node-base', 'event-delegate']});
2357
 
 
2358
 
 
2359
 
YUI.add('node', function(Y){}, '3.2.0' ,{requires:['dom', 'event-base', 'event-delegate', 'pluginhost'], use:['node-base', 'node-style', 'node-screen', 'node-pluginhost', 'node-event-delegate'], skinnable:false});
 
2621
}, '3.3.0' ,{requires:['node-base', 'event-delegate']});
 
2622
 
 
2623
 
 
2624
YUI.add('node', function(Y){}, '3.3.0' ,{requires:['dom', 'event-base', 'event-delegate', 'pluginhost'], use:['node-base', 'node-style', 'node-screen', 'node-pluginhost', 'node-event-delegate'], skinnable:false});
2360
2625