~ubuntu-branches/ubuntu/lucid/loggerhead/lucid-security

« back to all changes in this revision

Viewing changes to loggerhead/static/javascript/yui/build/node/node-base.js

  • Committer: Bazaar Package Importer
  • Author(s): James Westby, Roland Mas, Jelmer Vernooij, James Westby
  • Date: 2009-08-26 13:18:03 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090826131803-0ce1fhaetci8b0c5
Tags: 1.17-0ubuntu1
[ Roland Mas ]
* Use the YUI library provided by libjs-yui. (Closes: #511286)

[ Jelmer Vernooij ]
* Use my debian.org address in Uploaders field.
* Add ${misc:Depends} to please lintian.
* Suggest recent version of paste, which doesn't expose internal port
  numbers in links. (Closes: #507000)
* Bump standards version to 3.8.1.

[ James Westby ]
* New upstream release.
* Drop get-orig-source rule in favour of debian/watch.
* Add python-pkg-resources and python-paste to Build-Depends,
  python-pkg-resources to Depends and python-simplejson to
  Recommends due to dependency changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
Copyright (c) 2008, Yahoo! Inc. All rights reserved.
3
3
Code licensed under the BSD License:
4
4
http://developer.yahoo.net/yui/license.txt
5
 
version: 3.0.0pr1
 
5
version: 3.0.0pr2
6
6
*/
7
7
YUI.add('node-base', function(Y) {
8
8
 
10
10
     * The Node Utility provides a DOM-like interface for interacting with DOM nodes.
11
11
     * @module node
12
12
     * @submodule node-base
13
 
     */     
 
13
     */    
14
14
 
15
15
    /**
16
16
     * The Node class provides a wrapper for manipulating DOM Nodes.
17
17
     * Node properties can be accessed via the set/get methods.
18
18
     * Use Y.get() to retrieve Node instances.
19
19
     *
20
 
     * <strong>NOTE:</strong> All node properties are accessed using the
21
 
     * <code>set</code> and <code>get</code> methods.
 
20
     * <strong>NOTE:</strong> Node properties are accessed using
 
21
     * the <code>set</code> and <code>get</code> methods.
22
22
     *
23
23
     * @class Node
24
24
     * @constructor
25
25
     */
26
26
 
27
 
    var BASE_NODE                   = 0, 
28
 
        ELEMENT_NODE                = 1,
29
 
        //ATTRIBUTE_NODE              = 2,
30
 
        //TEXT_NODE                   = 3,
31
 
        //CDATA_SECTION_NODE          = 4,
32
 
        //ENTITY_REFERENCE_NODE       = 5,
33
 
        //ENTITY_NODE                 = 6,
34
 
        //PROCESSING_INSTRUCTION_NODE = 7,
35
 
        //COMMENT_NODE                = 8,
36
 
        DOCUMENT_NODE               = 9; //,
37
 
        //DOCUMENT_TYPE_NODE          = 10,
38
 
        //DOCUMENT_FRAGMENT_NODE      = 11,
39
 
        //NOTATION_NODE               = 12;
40
 
 
41
27
    var OWNER_DOCUMENT = 'ownerDocument',
42
28
        TAG_NAME = 'tagName',
43
29
        NODE_NAME = 'nodeName',
44
 
        NODE_TYPE = 'nodeType';
45
 
 
46
 
    var RE_VALID_PROP_TYPES = /(?:string|boolean|number)/;
47
 
 
48
 
    var Selector = Y.Selector;
49
 
    var _instances = {};
50
 
    var _nodes = {};
51
 
    var _nodelists = {};
52
 
    var _restrict = null;
53
 
 
54
 
    var slice = [].slice;
55
 
 
56
 
    var wrapDOM = function(node) {
57
 
        var ret = null,
58
 
            yuid = (node) ? node._yuid : null,
59
 
            instance = _instances[yuid],
60
 
            existingNode = _nodes[yuid];
61
 
 
62
 
        if (node) {
63
 
            if (NODE_TYPE in node) {
64
 
                if (instance && existingNode && node === existingNode) {
65
 
                    ret = instance; // reuse existing Nodes if nodes match
66
 
                } else {
67
 
                    ret = new Node(node);
68
 
                }
69
 
            } else if ('item' in node || 'push' in node) {
70
 
                ret = new Y.NodeList(node);
71
 
            }
72
 
        }
73
 
        return ret;
74
 
    };
75
 
 
76
 
    var wrapFn = function(fn) {
 
30
        NODE_TYPE = 'nodeType',
 
31
 
 
32
        Selector = Y.Selector,
 
33
        _instances = {},
 
34
        _restrict = {},
 
35
        _slice = [].slice;
 
36
 
 
37
    // used with previous/next/ancestor tests
 
38
    var _wrapFn = function(fn) {
77
39
        var ret = null;
78
40
        if (fn) {
79
41
            ret = (typeof fn === 'string') ?
81
43
                return Y.Selector.test(n, fn);
82
44
            } : 
83
45
            function(n) {
84
 
                return fn(_instances[n._yuid]);
 
46
                return fn(Y.get(n));
85
47
            };
86
48
        }
87
49
 
88
50
        return ret;
89
51
    };
90
52
 
91
 
    var getDoc = function(node) {
92
 
        node = _nodes[node._yuid];
93
 
        return (node[NODE_TYPE] === 9) ? node : node[OWNER_DOCUMENT];
 
53
    var _getDoc = function(node) {
 
54
        var doc = Y.config.doc;
 
55
 
 
56
        if (node) {
 
57
            if (node[NODE_TYPE]) {
 
58
                if (node[NODE_TYPE] === 9) { // already a document node
 
59
                    doc = node;
 
60
                } else {
 
61
                    doc = node[OWNER_DOCUMENT];
 
62
                }
 
63
            } else if (Node[node._yuid]) { // Node instance document
 
64
                doc = Node[node._yuid]()[0];
 
65
            }
 
66
        }
 
67
 
 
68
        return doc;
94
69
    };
95
70
 
96
 
    // returns HTMLElement
97
 
    var getDOMNode = function(node) {
98
 
        if (node && !node.nodeType && node._yuid) {
99
 
            node = _nodes[node._yuid];
 
71
    var _getDOMNode = function(node) {
 
72
        if (node && !node[NODE_TYPE] && node._yuid) {
 
73
            node = Node[node._yuid]()[0];
100
74
        }
101
75
 
102
76
        return  node || null;
103
 
 
104
 
    };
105
 
 
106
 
    /*
107
 
     * Wraps the input and outputs of a node instance
108
 
     */
109
 
    var nodeInOut = function(method, a, b, c, d, e) {
110
 
        if (a) { // first 2 may be Node instances or nodes (TODO: or strings?)
111
 
            a = getDOMNode(a);
112
 
            if (b) {
113
 
                b = getDOMNode(b);
114
 
            }
115
 
        }
116
 
        return wrapDOM(_nodes[this._yuid][method](a, b, c, d, e));
117
 
    };
118
 
 
119
 
    /*
120
 
     * Wraps the return value in a node instance
121
 
     */
122
 
    var nodeOut = function(method, a, b, c, d, e) {
123
 
        return wrapDOM(_nodes[this._yuid][method](a, b, c, d, e));
124
 
    };
125
 
 
126
 
    /* 
127
 
     * Returns directy from node method call 
128
 
     */
129
 
    var rawOut = function(method, a, b, c, d, e) {
130
 
        return _nodes[this._yuid][method](a, b, c, d, e);
131
 
    };
132
 
 
133
 
    var noOut = function(method, a, b, c, d, e) {
134
 
        _nodes[this._yuid][method](a, b, c, d, e);
135
 
        return this;
136
 
    };
137
 
 
138
 
    var PROPS_WRAP = {
139
 
        /**
140
 
         * Returns a Node instance. 
141
 
         * @property parentNode
142
 
         * @type Node
143
 
         */
144
 
        'parentNode': BASE_NODE,
145
 
 
146
 
        /**
147
 
         * Returns a NodeList instance. 
148
 
         * @property childNodes
149
 
         * @type NodeList
150
 
         */
151
 
        'childNodes': BASE_NODE,
 
77
    };
 
78
 
 
79
    var Node = function() {
 
80
        this.init.apply(this, arguments);
 
81
    };
 
82
 
 
83
    Node.PLUGINS = {};
 
84
 
 
85
    Node._deepGet = function (path, val) {
 
86
        var pl = path.length,
 
87
            i;
 
88
 
 
89
        if (pl > 0) {
 
90
            for (i = 0; val !== undefined && i < pl; ++i) {
 
91
                val = val[path[i]];
 
92
            }
 
93
        }
 
94
 
 
95
        return val;
 
96
    };
 
97
 
 
98
    Node._deepSet = function(path, val, subval) {
 
99
        var leafIdx = path.length-1,
 
100
            i,
 
101
            o;
 
102
 
 
103
        if (leafIdx >= 0) {
 
104
            o = val;
 
105
 
 
106
            for (i = 0; o !== undefined && i < leafIdx; ++i) {
 
107
                o = o[path[i]];
 
108
            }
 
109
 
 
110
            if (o !== undefined && o[path[i]] !== undefined) {
 
111
                o[path[i]] = subval;
 
112
            }
 
113
        }
 
114
    };
 
115
 
 
116
    Node.scrubVal = function(val, node, depth) {
 
117
        if (val !== undefined) {
 
118
            if (typeof val === 'object' || typeof val === 'function') { // safari nodeList === function
 
119
                if (val !== null && (
 
120
                        NODE_TYPE in val || // dom node
 
121
                        val.item || // dom collection or Node instance
 
122
                        (val[0] && val[0][NODE_TYPE]) || // assume array of nodes
 
123
                        val.document) // window TODO: restrict?
 
124
                    ) { 
 
125
                    if (node && _restrict && _restrict[node._yuid] && !node.contains(val)) {
 
126
                        val = null; // not allowed to go outside of root node
 
127
                    } else {
 
128
                        if (val[NODE_TYPE] || val.document) { // node or window
 
129
                            val = Node.get(val);
 
130
                        } else {
 
131
                            val = Node.all(val);
 
132
                        }
 
133
                    }
 
134
                } else {
 
135
                    depth = (depth === undefined) ? 4 : depth;
 
136
                    if (depth > 0) {
 
137
                        for (var i in val) {
 
138
                            if (val.hasOwnProperty && val.hasOwnProperty(i)) {
 
139
                                val[i] = Node.scrubVal(val[i], node, --depth);
 
140
                            }
 
141
                        }
 
142
                    }
 
143
                    
 
144
                }
 
145
            }
 
146
        } else {
 
147
            val = node; // for chaining
 
148
        }
 
149
 
 
150
        return val;
 
151
    };
 
152
 
 
153
    Node.setters = {};
 
154
    Node.getters = {
 
155
        /**
 
156
         * Normalizes nodeInnerText and textContent. 
 
157
         * @property text
 
158
         * @type String
 
159
         */
 
160
        'text': function(node) {
 
161
            return Y.DOM.getText(node);
 
162
        },
 
163
 
 
164
        'options': function(node) {
 
165
            return (node) ? node.getElementsByTagName('option') : [];
 
166
        },
152
167
 
153
168
        /**
154
169
         * Returns a NodeList instance. 
156
171
         * @type NodeList
157
172
         */
158
173
        'children': function(node) {
159
 
            node = _nodes[node._yuid];
160
174
            var children = node.children;
161
175
 
162
176
            if (children === undefined) {
170
184
                }
171
185
            }
172
186
            return children;
173
 
        },
174
 
 
175
 
        /**
176
 
         * Returns a Node instance. 
177
 
         * @property firstChild
178
 
         * @type Node
179
 
         */
180
 
        'firstChild': BASE_NODE,
181
 
 
182
 
        /**
183
 
         * Returns a Node instance. 
184
 
         * @property lastChild
185
 
         * @type Node
186
 
         */
187
 
        'lastChild': BASE_NODE,
188
 
 
189
 
        /**
190
 
         * Returns a Node instance. 
191
 
         * @property previousSibling
192
 
         * @type Node
193
 
         */
194
 
        'previousSibling': BASE_NODE,
195
 
 
196
 
        /**
197
 
         * Returns a Node instance. 
198
 
         * @property previousSibling
199
 
         * @type Node
200
 
         */
201
 
        'nextSibling': BASE_NODE,
202
 
 
203
 
        /**
204
 
         * Returns a Node instance. 
205
 
         * @property ownerDocument
206
 
         * @type Doc
207
 
         */
208
 
        'ownerDocument': BASE_NODE,
209
 
 
210
 
        /**
211
 
         * Returns a Node instance. 
212
 
         * @property offsetParent
213
 
         * @type Node
214
 
         */
215
 
        'offsetParent': ELEMENT_NODE,
216
 
 
217
 
        /**
218
 
         * Returns a Node instance. 
219
 
         * @property documentElement
220
 
         * @type Node
221
 
         */
222
 
        'documentElement': DOCUMENT_NODE,
223
 
 
224
 
        /**
225
 
         * Returns a Node instance. 
226
 
         * @property body
227
 
         * @type Node
228
 
         */
229
 
        'body': DOCUMENT_NODE,
230
 
 
231
 
        // form
232
 
        /**
233
 
         * Returns a NodeList instance. 
234
 
         * @property elements
235
 
         * @type NodeList
236
 
         */
237
 
        'elements': ELEMENT_NODE,
238
 
 
239
 
        // table
240
 
        /**
241
 
         * Returns a NodeList instance. 
242
 
         * @property rows
243
 
         * @type NodeList
244
 
         */
245
 
        'rows': ELEMENT_NODE,
246
 
 
247
 
        /**
248
 
         * Returns a NodeList instance. 
249
 
         * @property cells
250
 
         * @type NodeList
251
 
         */
252
 
        'cells': ELEMENT_NODE,
253
 
 
254
 
        /**
255
 
         * Returns a Node instance. 
256
 
         * @property tHead
257
 
         * @type Node
258
 
         */
259
 
        'tHead': ELEMENT_NODE,
260
 
 
261
 
        /**
262
 
         * Returns a Node instance. 
263
 
         * @property tFoot
264
 
         * @type Node
265
 
         */
266
 
        'tFoot': ELEMENT_NODE,
267
 
 
268
 
        /**
269
 
         * Returns a NodeList instance. 
270
 
         * @property tBodies
271
 
         * @type NodeList
272
 
         */
273
 
        'tBodies': ELEMENT_NODE
274
 
    };
275
 
    var METHODS = {
276
 
        /**
277
 
         * Passes through to DOM method.
278
 
         * @method replaceChild
279
 
         * @param {HTMLElement | Node} node Node to be inserted 
280
 
         * @param {HTMLElement | Node} refNode Node to be replaced 
281
 
         * @return {Node} The replaced node 
282
 
         */
283
 
        replaceChild: nodeInOut,
284
 
 
285
 
        /**
286
 
         * Passes through to DOM method.
287
 
         * @method appendChild
288
 
         * @param {HTMLElement | Node} node Node to be appended 
289
 
         * @return {Node} The appended node 
290
 
         */
291
 
        appendChild: nodeInOut,
292
 
 
293
 
        /**
294
 
         * Passes through to DOM method.
295
 
         * @method insertBefore
296
 
         * @param {HTMLElement | Node} newNode Node to be appended 
297
 
         * @param {HTMLElement | Node} refNode Node to be inserted before 
298
 
         * @return {Node} The inserted node 
299
 
         */
300
 
        insertBefore: nodeInOut,
301
 
 
302
 
        /**
303
 
         * Passes through to DOM method.
304
 
         * @method removeChild
305
 
         * @param {HTMLElement | Node} node Node to be removed 
306
 
         * @return {Node} The removed node 
307
 
         */
308
 
        removeChild: nodeInOut,
309
 
 
310
 
        /**
311
 
         * Passes through to DOM method.
312
 
         * @method hasChildNodes
313
 
         * @return {Boolean} Whether or not the node has any childNodes 
314
 
         */
315
 
        hasChildNodes: rawOut,
316
 
 
317
 
        /**
318
 
         * Passes through to DOM method.
319
 
         * @method cloneNode
320
 
         * @param {HTMLElement | Node} node Node to be cloned 
321
 
         * @return {Node} The clone 
322
 
         */
323
 
        cloneNode: nodeOut,
324
 
 
325
 
        /**
326
 
         * Passes through to DOM method.
327
 
         * @method getAttribute
328
 
         * @param {String} attribute The attribute to retrieve 
329
 
         * @return {String} The current value of the attribute 
330
 
         */
331
 
        getAttribute: rawOut,
332
 
 
333
 
        /**
334
 
         * Passes through to DOM method.
335
 
         * @method setAttribute
336
 
         * @param {String} attribute The attribute to set 
337
 
         * @param {String} The value to apply to the attribute 
338
 
         * @chainable
339
 
         */
340
 
        setAttribute: noOut,
341
 
 
342
 
        /**
343
 
         * Passes through to DOM method.
344
 
         * @method hasAttribute
345
 
         * @param {String} attribute The attribute to test for 
346
 
         * @return {Boolean} Whether or not the attribute is present 
347
 
         */
348
 
        hasAttribute: rawOut,
349
 
 
350
 
        /**
351
 
         * Passes through to DOM method.
352
 
         * @method scrollIntoView
353
 
         * @chainable
354
 
         */
355
 
        scrollIntoView: noOut,
356
 
 
357
 
        /**
358
 
         * Passes through to DOM method.
359
 
         * @method getElementsByTagName
360
 
         * @param {String} tagName The tagName to collect 
361
 
         * @return {NodeList} A NodeList representing the HTMLCollection
362
 
         */
363
 
        getElementsByTagName: nodeOut,
364
 
 
365
 
        /**
366
 
         * Passes through to DOM method.
367
 
         * @method focus
368
 
         * @chainable
369
 
         */
370
 
        focus: noOut,
371
 
 
372
 
        /**
373
 
         * Passes through to DOM method.
374
 
         * @method blur
375
 
         * @chainable
376
 
         */
377
 
        blur: noOut,
378
 
 
379
 
        /**
380
 
         * Passes through to DOM method.
381
 
         * Only valid on FORM elements
382
 
         * @method submit
383
 
         * @chainable
384
 
         */
385
 
        submit: noOut,
386
 
 
387
 
        /**
388
 
         * Passes through to DOM method.
389
 
         * Only valid on FORM elements
390
 
         * @method reset
391
 
         * @chainable
392
 
         */
393
 
        reset: noOut
394
 
    };
395
 
 
396
 
    var addNodeListMethod = function(name) {
397
 
        NodeList.prototype[name] = function() {
398
 
            var a = [],
399
 
                nodes = _nodelists[this._yuid],
400
 
                ret;
401
 
 
402
 
            for (var i = 0, len = nodes.length; i < len; ++i) {
403
 
                _nodes[_tmpNode._yuid] = nodes[i];
404
 
                ret = _tmpNode[name].apply(_tmpNode, arguments);
405
 
                if (ret !== _tmpNode) {
406
 
                    a[i] = ret;
407
 
                }
408
 
            }
409
 
 
410
 
            return a.length ? a : this;
411
 
        };
412
 
    };
413
 
 
414
 
    var METHODS_INVOKE = {
415
 
        'getBoundingClientRect': true
416
 
    };
417
 
 
418
 
    var Node = function(node) {
419
 
        if (!node || !node[NODE_TYPE]) {
420
 
            return null;
421
 
        }
422
 
        
423
 
        var yuid = Y.guid();
424
 
        try { // IE errors on non-element expandos (cant be reused)
425
 
            node._yuid = yuid;
426
 
        } catch(e) {}
427
 
        this._yuid = yuid;
428
 
        _nodes[yuid] = node;
429
 
        _instances[yuid] = this;
430
 
 
431
 
    };
432
 
 
433
 
    var SETTERS = {};
434
 
    var GETTERS = {
435
 
        /**
436
 
         * Normalizes nodeInnerText and textContent. 
437
 
         * @property text
438
 
         * @type String
439
 
         */
440
 
        'text': function(node) {
441
 
            return Y.DOM.getText(_nodes[node._yuid]);
442
 
        },
443
 
 
444
 
        /**
445
 
         * Returns a nodeList of option elements 
446
 
         * @property options
447
 
         * @type String
448
 
         */
449
 
        'options': function(node) {
450
 
            return (node) ? node.getElementsByTagName('option') : [];
451
 
        }
452
 
    };
453
 
 
454
 
    Node.setters = function(prop, fn) {
455
 
        if (typeof prop == 'string') {
456
 
            SETTERS[prop] = fn;
457
 
        } else { // assume object
458
 
            Y.each(prop, function(fn, prop) {
459
 
                Node.setters(prop, fn);
460
 
            });
461
 
        } 
462
 
    };
463
 
 
464
 
    Node.getters = function(prop, fn) {
465
 
        if (typeof prop == 'string') {
466
 
            GETTERS[prop] = fn;
467
 
        } else { // assume object
468
 
            Y.each(prop, function(fn, prop) {
469
 
                Node.getters(prop, fn);
470
 
            });
471
 
        } 
 
187
        }
472
188
    };
473
189
 
474
190
    Node.methods = function(name, fn) {
475
191
        if (typeof name == 'string') {
476
192
            Node.prototype[name] = function() {
477
 
                var args = slice.call(arguments);
478
 
                args.unshift(this);
479
 
                var ret = fn.apply(null, args);
480
 
                if (ret === undefined) {
481
 
                    ret = this;
482
 
                }
 
193
                var args = _slice.call(arguments, 0),
 
194
                    instance = this,
 
195
                    getAll =  (_instances[this._yuid]) ? false : true, // return array of vals for lists
 
196
                    ret = (getAll) ? [] : null,
 
197
                    val;
 
198
 
 
199
                var getValue = function(node) {
 
200
                    args[0] = node;
 
201
                    val = Node.scrubVal(fn.apply(instance, args), instance);
 
202
                    if (getAll) {
 
203
                        ret[ret.length] = val;
 
204
                    } else {
 
205
                        ret = val;
 
206
                    }
 
207
                };
 
208
 
 
209
                args.unshift('');
 
210
                Node[instance._yuid](getValue);
483
211
                return ret;
484
212
            };
485
 
 
486
 
            addNodeListMethod(name);
487
 
 
488
 
 
489
213
        } else { // assume object
490
214
            Y.each(name, function(fn, name) {
491
215
                Node.methods(name, fn);
492
216
            });
493
217
        }
494
 
    };
495
 
 
496
 
    Node.getDOMNode = function(node) {
497
 
        var ret;
498
 
 
499
 
        if (node.nodeType) {
500
 
            ret = node;
501
 
        } else if (typeof node === 'string') {
502
 
            ret = Selector.query(node, null, true);
503
 
        } else {
504
 
            ret = _nodes[node._yuid];
505
 
        }
506
 
        return ret || null;
507
 
    };
508
 
 
 
218
 
 
219
    };
 
220
 
 
221
    Node.getDOMNode = _getDOMNode;
 
222
    
509
223
    Node.wrapDOMMethod = function(name) {
510
224
        return function() {
511
 
            var args = slice.call(arguments);
512
 
            args.unshift(Y.Node.getDOMNode(args.shift()));
513
 
            return Y.DOM[name].apply(Y.DOM, args);
 
225
            return Y.DOM[name].apply(Y.DOM, arguments);
514
226
        };
515
227
 
516
228
    };
525
237
    };
526
238
 
527
239
    Node.prototype = {
 
240
        init: function(nodes, doc, isRoot, getAll) {
 
241
            var uid;
 
242
 
 
243
            doc = _getDoc(doc);
 
244
 
 
245
            this.getId = function() {
 
246
                return uid;
 
247
            };
 
248
 
 
249
            var _all = function(fn, i) {
 
250
                if (fn) {
 
251
                    i = i || 0;
 
252
                    for (var node; node = nodes[i++];) {
 
253
                        fn(node);
 
254
                    }
 
255
                }
 
256
                return nodes;
 
257
            };
 
258
 
 
259
            // uid = selector || Y.guid(); // to cache queryAll results
 
260
            uid = Y.guid();
 
261
 
 
262
            if (nodes) { // zero length collection returns null
 
263
                if (nodes[NODE_TYPE] || nodes.document) { // node or window
 
264
                    nodes = [nodes];
 
265
                }
 
266
            } else {
 
267
                nodes = [];
 
268
            }
 
269
 
 
270
            if (!getAll && nodes.length) { // stamp the dom node
 
271
                try { // IE only allows ID on Element
 
272
                    if (nodes[0].uniqueID) {
 
273
                        uid = nodes[0].uniqueID;
 
274
                    }
 
275
                    nodes[0]._yuid = uid;
 
276
                } catch(e) { // not cacheable
 
277
                }
 
278
            }
 
279
 
 
280
            this._yuid = uid;
 
281
            Node[uid] = _all; // for applying/returning dom nodes
 
282
 
 
283
            if (!getAll) {
 
284
                _instances[uid] = this;
 
285
            }
 
286
 
 
287
            this.initPlugins();
 
288
        },
 
289
 
 
290
        initPlugins: function() {
 
291
            Y.each(Node.PLUGINS, function(config, fn) {
 
292
                this.plug(fn, config);
 
293
            });
 
294
        },
 
295
 
 
296
        /**
 
297
         * Filters the NodeList instance down to only nodes matching the given selector.
 
298
         * @method filter
 
299
         * @param {String} selector The selector to filter against
 
300
         * @return {NodeList} NodeList containing the updated collection 
 
301
         * @see Selector
 
302
         */
 
303
        filter: function(selector) {
 
304
            return Node.scrubVal(Selector.filter(Node[this._yuid](), selector), this);
 
305
        },
 
306
 
 
307
        /**
 
308
         * Applies the given function to each Node in the NodeList.
 
309
         * @method each
 
310
         * @param {Function} fn The function to apply 
 
311
         * @param {Object} context optional An optional context to apply the function with
 
312
         * Default context is the NodeList instance
 
313
         * @return {NodeList} NodeList containing the updated collection 
 
314
         * @chainable
 
315
         */
 
316
        each: function(fn, context) {
 
317
            context = context || this;
 
318
            Node[this._yuid](function(node) {
 
319
                fn.call(context, Node.get(node));
 
320
            });
 
321
        },
 
322
 
 
323
        /**
 
324
         * Returns the current number of items in the NodeList.
 
325
         * @method size
 
326
         * @return {Int} The number of items in the NodeList. 
 
327
         */
 
328
        size: function() {
 
329
            return Node[this._yuid]().length;
 
330
        },
 
331
 
 
332
        /**
 
333
         * Retrieves the Node instance at the given index. 
 
334
         * @method item
 
335
         *
 
336
         * @param {Number} index The index of the target Node.
 
337
         * @return {Node} The Node instance at the given index.
 
338
         */
 
339
        item: function(index) {
 
340
            var node = Node[this._yuid]()[index];
 
341
            return Node.get(node);
 
342
        },
 
343
 
 
344
       /**
 
345
         * Attaches a DOM event handler.
 
346
         * @method attach
 
347
         * @param {String} type The type of DOM Event to listen for 
 
348
         * @param {Function} fn The handler to call when the event fires 
 
349
         * @param {Object} arg An argument object to pass to the handler 
 
350
         */
 
351
 
 
352
        attach: function(type, fn, arg) {
 
353
            var args = _slice.call(arguments, 0);
 
354
            args.splice(2, 0, Node[this._yuid]());
 
355
            return Y.Event.attach.apply(Y.Event, args);
 
356
        },
 
357
 
 
358
       /**
 
359
         * Alias for attach.
 
360
         * @method on
 
361
         * @param {String} type The type of DOM Event to listen for 
 
362
         * @param {Function} fn The handler to call when the event fires 
 
363
         * @param {Object} arg An argument object to pass to the handler 
 
364
         * @see attach
 
365
         */
 
366
        on: function(type, fn, arg) {
 
367
            return this.attach.apply(this, arguments);
 
368
        },
 
369
 
 
370
       /**
 
371
         * Detaches a DOM event handler. 
 
372
         * @method detach
 
373
         * @param {String} type The type of DOM Event
 
374
         * @param {Function} fn The handler to call when the event fires 
 
375
         */
 
376
        detach: function(type, fn) {
 
377
            var args = _slice.call(arguments, 0);
 
378
            args.splice(2, 0, Node[this._yuid]());
 
379
            return Y.Event.detach.apply(Y.Event, args);
 
380
        },
 
381
 
 
382
       /**
 
383
         * Creates a Node instance from HTML string
 
384
         * @method create
 
385
         * @param {String|Array} html The string of html to create
 
386
         * @return {Node} A new Node instance 
 
387
         */
 
388
        create: function(html) {
 
389
            return Y.Node.create(html);
 
390
        },
 
391
 
 
392
        /**
 
393
         * Applies the supplied plugin to the node.
 
394
         * @method plug
 
395
         * @param {Function} The plugin Class to apply
 
396
         * @param {Object} config An optional config to pass to the constructor
 
397
         * @chainable
 
398
         */
 
399
        plug: function(PluginClass, config) {
 
400
            config = config || {};
 
401
            config.owner = this;
 
402
            if (PluginClass && PluginClass.NS) {
 
403
                this[PluginClass.NS] = new PluginClass(config);
 
404
            }
 
405
            return this;
 
406
        },
 
407
 
 
408
        //normalize: function() {},
 
409
        //isSupported: function(feature, version) {},
 
410
        toString: function() {
 
411
            var str = '', 
 
412
            node = Node[this._yuid]()[0] || {};
 
413
 
 
414
            if (node) {
 
415
                str += node[NODE_NAME];
 
416
                if (node.id) {
 
417
                    str += '#' + node.id; 
 
418
                }
 
419
 
 
420
                if (node.className) {
 
421
                    str += '.' + node.className.replace(' ', '.'); 
 
422
                }
 
423
            } else {
 
424
                'no nodes for ' + this._yuid;
 
425
            }
 
426
            return str;
 
427
        }
 
428
    };
 
429
 
 
430
    Node.methods({
 
431
        addEventListener: function() {
 
432
            return Y.Event.nativeAdd.apply(Y.Event, arguments);
 
433
        },
 
434
        
 
435
        removeEventListener: function() {
 
436
            return Y.Event.nativeRemove.apply(Y.Event, arguments);
 
437
        },
 
438
 
528
439
        /**
529
440
         * Set the value of the property/attribute on the HTMLElement bound to this Node.
530
441
         * Only strings/numbers/booleans are passed through unless a SETTER exists.
533
444
         * @param {any} val Value to apply to the given property
534
445
         * @chainable
535
446
         */
536
 
        set: function(prop, val) {
537
 
            var node = _nodes[this._yuid];
538
 
            if (prop in SETTERS) { // use custom setter
539
 
                SETTERS[prop](this, prop, val);  // passing Node instance
540
 
            } else if (RE_VALID_PROP_TYPES.test(typeof node[prop])) { // safe to write
541
 
                node[prop] = val;
 
447
        // TODO: document.location.href
 
448
        set: function(node, prop, val) {
 
449
            if (prop.indexOf('.') < 0) {
 
450
                if (prop in Node.setters) { // use custom setter
 
451
                    Node.setters[prop](this, prop, val);  // passing Node instance
 
452
                } else if (node[prop] !== undefined) { // no expandos 
 
453
                    node[prop] = val;
 
454
                } else {
 
455
                }
 
456
            } else {
 
457
                Node._deepSet(prop.split('.'), node, val);
542
458
            }
543
 
            return this;
544
459
        },
545
460
 
546
461
        /**
550
465
         * @param {String} prop Property to get 
551
466
         * @return {any} Current value of the property
552
467
         */
553
 
        get: function(prop) {
 
468
        get: function(node, prop) {
554
469
            var val;
555
 
            var node = _nodes[this._yuid];
556
 
            if (prop in GETTERS) { // use custom getter
557
 
                val = GETTERS[prop](this, prop);
558
 
            } else if (prop in PROPS_WRAP) { // wrap DOM object (HTMLElement, HTMLCollection, Document)
559
 
                if (typeof PROPS_WRAP[prop] === 'function') {
560
 
                    val = PROPS_WRAP[prop](this);
 
470
            if (prop.indexOf('.') < 0) {
 
471
                if (prop in Node.getters) { // use custom getter
 
472
                    val = Node.getters[prop].call(this, node, prop);
561
473
                } else {
562
474
                    val = node[prop];
563
475
                }
564
476
 
565
 
                if (_restrict && _restrict[this._yuid] && !Y.DOM.contains(node, val)) {
566
 
                    val = null; // not allowed to go outside of root node
567
 
                } else {
568
 
                    val = wrapDOM(val);
 
477
                // method wrapper uses undefined in chaining test
 
478
                if (val === undefined) {
 
479
                    val = null;
569
480
                }
570
 
            } else if (RE_VALID_PROP_TYPES.test(typeof node[prop])) { // safe to read
571
 
                val = node[prop];
 
481
            } else {
 
482
                val = Node._deepGet(prop.split('.'), node);
572
483
            }
 
484
 
573
485
            return val;
574
486
        },
575
487
 
576
 
        invoke: function(method, a, b, c, d, e) {
577
 
            if (a) { // first 2 may be Node instances or strings
578
 
                a = (a[NODE_TYPE]) ? a : getDOMNode(a);
 
488
        invoke: function(node, method, a, b, c, d, e) {
 
489
            var ret;
 
490
 
 
491
            if (a) { // first 2 may be Node instances
 
492
                a = (a[NODE_TYPE]) ? a : _getDOMNode(a);
579
493
                if (b) {
580
 
                    b = (b[NODE_TYPE]) ? b : getDOMNode(b);
 
494
                    b = (b[NODE_TYPE]) ? b : _getDOMNode(b);
581
495
                }
582
496
            }
583
 
            var node = _nodes[this._yuid];
584
 
            if (node && METHODS_INVOKE[method] && node[method]) {
585
 
                return node[method](a, b, c, d, e);
586
 
            }
587
 
            return null;
588
 
        },
589
 
 
590
 
        hasMethod: function(method) {
591
 
            return !!(METHODS_INVOKE[method] && _nodes[this._yuid][method]);
592
 
        },
593
 
 
594
 
        //normalize: function() {},
595
 
        //isSupported: function(feature, version) {},
596
 
        toString: function() {
597
 
            var node = _nodes[this._yuid] || {};
598
 
            return node.id || node[NODE_NAME] || 'undefined node';
 
497
 
 
498
            ret = node[method](a, b, c, d, e);    
 
499
            return ret;
 
500
        },
 
501
 
 
502
        hasMethod: function(node, method) {
 
503
            return !! node[method];
599
504
        },
600
505
 
601
506
        /**
602
 
         * Retrieves a single node based on the given CSS selector. 
 
507
         * Retrieves a Node instance of nodes based on the given CSS selector. 
603
508
         * @method query
604
509
         *
605
510
         * @param {string} selector The CSS selector to test against.
606
511
         * @return {Node} A Node instance for the matching HTMLElement.
607
512
         */
608
 
        query: function(selector) {
609
 
            return wrapDOM(Selector.query(selector, _nodes[this._yuid], true));
 
513
        query: function(node, selector) {
 
514
            var ret = Selector.query(selector, node, true);
 
515
            if (!ret) {
 
516
                ret = null;
 
517
            }
 
518
 
 
519
            return ret;
610
520
        },
611
521
 
612
522
        /**
613
523
         * Retrieves a nodeList based on the given CSS selector. 
614
524
         * @method queryAll
 
525
         * @deprecated Use query() which returns all matches
615
526
         *
616
527
         * @param {string} selector The CSS selector to test against.
617
528
         * @return {NodeList} A NodeList instance for the matching HTMLCollection/Array.
618
529
         */
619
 
        queryAll: function(selector) {
620
 
            return wrapDOM(Selector.query(selector, _nodes[this._yuid]));
 
530
        queryAll: function(node, selector) {
 
531
            var ret = Selector.query(selector, node);
 
532
            if (!ret.length) {
 
533
                ret = null;
 
534
            }
 
535
 
 
536
            return ret;
621
537
        },
622
538
 
623
539
        /**
627
543
         * @param {string} selector The CSS selector to test against.
628
544
         * @return {boolean} Whether or not the node matches the selector.
629
545
         */
630
 
        test: function(selector) {
631
 
            return Selector.test(_nodes[this._yuid], selector);
 
546
        test: function(node, selector) {
 
547
            return Selector.test(node, selector);
632
548
        },
633
549
 
634
550
        /**
638
554
         * @param {HTMLElement | Node} refNode The reference node to compare to the node.
639
555
         * @return {Boolean} True if the nodes match, false if they do not. 
640
556
         */
641
 
        compareTo: function(refNode) {
642
 
            refNode = refNode[NODE_TYPE] ? refNode : _nodes[refNode._yuid];
643
 
            return _nodes[this._yuid] === refNode;
 
557
        compareTo: function(node, refNode) {
 
558
            refNode = _getDOMNode(refNode) || node;
 
559
            return node === refNode;
644
560
        },
645
561
 
646
 
       /*
 
562
       /**
647
563
         * Returns the nearest ancestor that passes the test applied by supplied boolean method.
648
564
         * @method ancestor
649
565
         * @param {String | Function} fn A selector or boolean method for testing elements.
650
566
         * If a function is used, it receives the current node being tested as the only argument.
651
567
         * @return {Node} The matching Node instance or null if not found
652
568
         */
653
 
        ancestor: function(fn) {
654
 
            return wrapDOM(Y.DOM.elementByAxis(_nodes[this._yuid], 'parentNode', wrapFn(fn)));
 
569
        ancestor: function(node, fn) {
 
570
            return Y.DOM.elementByAxis(node, 'parentNode', _wrapFn(fn));
655
571
        },
656
572
 
657
573
        /**
663
579
         * @param {Boolean} all optional Whether all node types should be returned, or just element nodes.
664
580
         * @return {Node} Node instance or null if not found
665
581
         */
666
 
        previous: function(fn, all) {
667
 
            return wrapDOM(Y.DOM.elementByAxis(_nodes[this._yuid], 'previousSibling', wrapFn(fn)), all);
 
582
        previous: function(node, fn, all) {
 
583
            return Y.DOM.elementByAxis(node, 'previousSibling', _wrapFn(fn), all);
668
584
        }, 
669
585
 
670
586
        /**
676
592
         * @param {Boolean} all optional Whether all node types should be returned, or just element nodes.
677
593
         * @return {Node} Node instance or null if not found
678
594
         */
679
 
        next: function(fn, all) {
680
 
            return wrapDOM(Y.DOM.elementByAxis(_nodes[this._yuid], 'nextSibling', wrapFn(fn)), all);
681
 
        },
682
 
        
683
 
       /**
684
 
         * Attaches a DOM event handler.
685
 
         * @method attach
686
 
         * @param {String} type The type of DOM Event to listen for 
687
 
         * @param {Function} fn The handler to call when the event fires 
688
 
         * @param {Object} arg An argument object to pass to the handler 
689
 
         */
690
 
 
691
 
        attach: function(type, fn, arg) {
692
 
            var args = slice.call(arguments, 0);
693
 
            args.unshift(_nodes[this._yuid]);
694
 
            return Y.Event.addListener.apply(Y.Event, args);
695
 
        },
696
 
 
697
 
       /**
698
 
         * Alias for attach.
699
 
         * @method on
700
 
         * @param {String} type The type of DOM Event to listen for 
701
 
         * @param {Function} fn The handler to call when the event fires 
702
 
         * @param {Object} arg An argument object to pass to the handler 
703
 
         * @see attach
704
 
         */
705
 
 
706
 
        on: function(type, fn, arg) {
707
 
            return this.attach.apply(this, arguments);
708
 
        },
709
 
 
710
 
        addEventListener: function(type, fn, arg) {
711
 
            return Y.Event.nativeAdd(_nodes[this._yuid], type, fn, arg);
712
 
        },
713
 
        
714
 
       /**
715
 
         * Detaches a DOM event handler. 
716
 
         * @method detach
717
 
         * @param {String} type The type of DOM Event
718
 
         * @param {Function} fn The handler to call when the event fires 
719
 
         */
720
 
        detach: function(type, fn) {
721
 
            var args = slice.call(arguments, 0);
722
 
            args.unshift(_nodes[this._yuid]);
723
 
            return Y.Event.removeListener.apply(Y.Event, args);
724
 
        },
725
 
 
726
 
        removeEventListener: function(type, fn) {
727
 
            return Y.Event.nativeRemove(_nodes[this._yuid], type, fn);
728
 
        },
729
 
 
730
 
       /**
731
 
         * Creates a Node instance from HTML string
732
 
         * @method create
733
 
         * @param {String|Array} html The string of html to create
734
 
         * @return {Node} A new Node instance 
735
 
         */
736
 
        create: function(html) {
737
 
            return Y.Node.create(html);
738
 
        },
739
 
 
 
595
        next: function(node, fn, all) {
 
596
            return Y.DOM.elementByAxis(node, 'nextSibling', _wrapFn(fn), all);
 
597
        },
 
598
        
740
599
        /**
741
600
         * Determines whether the ndoe is an ancestor of another HTML element in the DOM hierarchy.
742
601
         * @method contains
743
602
         * @param {Node | HTMLElement} needle The possible node or descendent
744
603
         * @return {Boolean} Whether or not this node is the needle its ancestor
745
604
         */
746
 
        contains: function(needle) {
747
 
            return Y.DOM.contains(_nodes[this._yuid], getDOMNode(needle));
748
 
        },
749
 
 
750
 
        /**
751
 
         * Applies the supplied plugin to the node.
752
 
         * @method plug
753
 
         * @param {Function} The plugin Class to apply
754
 
         * @param {Object} config An optional config to pass to the constructor
755
 
         * @chainable
756
 
         */
757
 
        plug: function(PluginClass, config) {
758
 
            config = config || {};
759
 
            config.owner = this;
760
 
            if (PluginClass && PluginClass.NS) {
761
 
                this[PluginClass.NS] = new PluginClass(config);
762
 
            }
763
 
            return this;
 
605
        contains: function(node, needle) {
 
606
            return Y.DOM.contains(node, _getDOMNode(needle));
764
607
        },
765
608
 
766
609
        /**
770
613
         * Defaults to current document. 
771
614
         * @return {Boolean} Whether or not this node is appended to the document. 
772
615
         */
773
 
        inDoc: function(doc) {
774
 
            var node = _nodes[this._yuid];
775
 
            doc = (doc) ? getDoc(doc) : node.ownerDocument;
 
616
        inDoc: function(node, doc) {
 
617
            doc = (doc) ? _getDoc(doc) : node.ownerDocument;
776
618
            if (doc.documentElement) {
777
619
                return Y.DOM.contains(doc.documentElement, node);
778
620
            }
 
621
        },
 
622
 
 
623
        byId: function(node, id) {
 
624
            var ret = node[OWNER_DOCUMENT].getElementById(id);
 
625
            if (!ret || !Y.DOM.contains(node, ret)) {
 
626
                ret = null;
 
627
            }
 
628
            return ret;
779
629
        }
780
 
    };
781
630
 
782
 
    Y.each(METHODS, function(fn, method) {
783
 
        Node.prototype[method] = function() {
784
 
            return fn.apply(this, [method].concat(slice.call(arguments)));
785
 
        };
786
631
    });
787
632
 
788
633
    /** 
791
636
     * @param {String} html HTML string
792
637
     */
793
638
    Node.create = function(html) {
794
 
        return wrapDOM(Y.DOM.create(html));
 
639
        return Node.get(Y.DOM.create(html));
795
640
    };
796
641
 
797
642
    Node.getById = function(id, doc) {
798
643
        doc = (doc && doc[NODE_TYPE]) ? doc : Y.config.doc;
799
 
        return wrapDOM(doc.getElementById(id));
 
644
        return Node.get(doc.getElementById(id));
800
645
    };
801
646
 
802
647
    /**
803
 
     * Retrieves a Node instance for the given object/string. 
 
648
     * Retrieves a Node instance for the given query or nodes. 
804
649
     * Note: Use 'document' string to retrieve document Node instance from string
805
 
     * @method get
 
650
     * @method Y.get
806
651
     * @static
807
652
     * @param {document|HTMLElement|HTMLCollection|Array|String} node The object to wrap.
808
653
     * @param {document|Node} doc optional The document containing the node. Defaults to current document.
809
654
     * @param {boolean} isRoot optional Whether or not this node should be treated as a root node. Root nodes
810
655
     * aren't allowed to traverse outside their DOM tree.
811
 
     * @return {Node} A wrapper instance for the supplied object.
 
656
     * @return {Node} A Node instance bound to the supplied node(s).
812
657
     */
813
 
    Node.get = function(node, doc, isRoot) {
814
 
        if (node instanceof Node) {
815
 
            return node;
816
 
        }
817
 
 
818
 
        if (!doc) {
819
 
            doc = Y.config.doc;
820
 
        } else if (doc._yuid && _nodes[doc._yuid]) {
821
 
            doc = _nodes[doc._yuid]; 
822
 
        }
823
 
    
824
 
        if (node && typeof node === 'string') {
825
 
            if (node === 'document') {
826
 
                node = Y.config.doc;
827
 
            } else {
828
 
                node = Y.Selector.query(node, doc, true);
829
 
            }
830
 
        }
831
 
 
832
 
        node = wrapDOM(node);
833
 
 
834
 
        if (isRoot) {
835
 
            _restrict = _restrict || {};
836
 
            _restrict[node._yuid] = node;
837
 
        }
838
 
 
839
 
        return node;
 
658
    Node.get = function(node, doc, isRoot, getAll) {
 
659
        var instance;
 
660
 
 
661
        if (node) {
 
662
            if (typeof node === 'string') {
 
663
                if (node === 'document') { // TODO: allow 'doc'? 'window'?
 
664
                    node = [Y.config.doc];
 
665
                } else {
 
666
                    node = Selector.query(node, doc, !getAll); // Selector arg is getFirst
 
667
                }
 
668
            }
 
669
 
 
670
            if (node) {
 
671
                if (!getAll) { // reuse single element node instances
 
672
                    if (node._yuid) {
 
673
                        // verify IE's uniqueID in case the node was cloned
 
674
                        if (!node.uniqueID || (node.uniqueID === node._yuid)) {
 
675
                            instance = _instances[node._yuid];
 
676
                        }
 
677
                    }
 
678
                }
 
679
 
 
680
                if (!instance) {
 
681
                    instance = new Node(node, doc, isRoot, getAll);
 
682
                }
 
683
 
 
684
                if (instance && isRoot && !getAll) {
 
685
                    _restrict[instance._yuid] = true;
 
686
                }
 
687
            }
 
688
        }
 
689
 
 
690
        // zero length collection returns null
 
691
        return (instance && instance.size()) ? instance : null;
840
692
    };
841
693
 
842
694
    /**
843
695
     * Retrieves a NodeList instance for the given object/string. 
844
 
     * @method all
 
696
     * @method Y.all
845
697
     * @static
846
698
     * @param {HTMLCollection|Array|String} node The object to wrap.
847
699
     * @param {document|Node} doc optional The document containing the node. Defaults to current document.
 
700
     * @param {boolean} isRoot optional Whether or not this node should be treated as a root node. Root nodes
848
701
     * @return {NodeList} A NodeList instance for the supplied nodes.
849
702
     */
850
 
    Node.all = function(nodes, doc) {
851
 
        if (nodes instanceof NodeList) {
852
 
            return nodes;
853
 
        }
854
 
 
855
 
        if (!doc) {
856
 
            doc = Y.config.doc;
857
 
        } else if (doc._yuid && _nodes[doc._yuid]) {
858
 
            doc = _nodes[doc._yuid]; 
859
 
        }
860
 
    
861
 
        if (nodes && typeof nodes == 'string') {
862
 
            nodes = Selector.query(nodes, doc);
863
 
        }
864
 
 
865
 
        return wrapDOM(nodes);
866
 
 
867
 
    };
868
 
 
869
 
    /** 
870
 
     * A wrapper for manipulating multiple DOM elements
871
 
     * @class NodeList
872
 
     * @extends Node
873
 
     * @constructor
874
 
     */
875
 
    var NodeList = function(nodes) {
876
 
        // TODO: input validation
877
 
        _nodelists[Y.stamp(this)] = nodes;
878
 
    };
 
703
    Node.all = function(node, doc, isRoot) {
 
704
        return Node.get.call(Node, node, doc, isRoot, true);
 
705
    };
 
706
 
 
707
    Y.Array.each([
 
708
        /**
 
709
         * Passes through to DOM method.
 
710
         * @method replaceChild
 
711
         * @param {HTMLElement | Node} node Node to be inserted 
 
712
         * @param {HTMLElement | Node} refNode Node to be replaced 
 
713
         * @return {Node} The replaced node 
 
714
         */
 
715
        'replaceChild',
 
716
 
 
717
        /**
 
718
         * Passes through to DOM method.
 
719
         * @method appendChild
 
720
         * @param {HTMLElement | Node} node Node to be appended 
 
721
         * @return {Node} The appended node 
 
722
         */
 
723
        'appendChild',
 
724
 
 
725
        /**
 
726
         * Passes through to DOM method.
 
727
         * @method insertBefore
 
728
         * @param {HTMLElement | Node} newNode Node to be appended 
 
729
         * @param {HTMLElement | Node} refNode Node to be inserted before 
 
730
         * @return {Node} The inserted node 
 
731
         */
 
732
        'insertBefore',
 
733
 
 
734
        /**
 
735
         * Passes through to DOM method.
 
736
         * @method removeChild
 
737
         * @param {HTMLElement | Node} node Node to be removed 
 
738
         * @return {Node} The removed node 
 
739
         */
 
740
        'removeChild',
 
741
 
 
742
        /**
 
743
         * Passes through to DOM method.
 
744
         * @method hasChildNodes
 
745
         * @return {Boolean} Whether or not the node has any childNodes 
 
746
         */
 
747
        'hasChildNodes',
 
748
 
 
749
        /**
 
750
         * Passes through to DOM method.
 
751
         * @method cloneNode
 
752
         * @param {HTMLElement | Node} node Node to be cloned 
 
753
         * @return {Node} The clone 
 
754
         */
 
755
        'cloneNode',
 
756
 
 
757
        /**
 
758
         * Passes through to DOM method.
 
759
         * @method getAttribute
 
760
         * @param {String} attribute The attribute to retrieve 
 
761
         * @return {String} The current value of the attribute 
 
762
         */
 
763
        'getAttribute',
 
764
 
 
765
        /**
 
766
         * Passes through to DOM method.
 
767
         * @method setAttribute
 
768
         * @param {String} attribute The attribute to set 
 
769
         * @param {String} The value to apply to the attribute 
 
770
         * @chainable
 
771
         */
 
772
        'setAttribute',
 
773
 
 
774
        /**
 
775
         * Passes through to DOM method.
 
776
         * @method hasAttribute
 
777
         * @param {String} attribute The attribute to test for 
 
778
         * @return {Boolean} Whether or not the attribute is present 
 
779
         */
 
780
        'hasAttribute',
 
781
 
 
782
        /**
 
783
         * Passes through to DOM method.
 
784
         * @method removeAttribute
 
785
         * @param {String} attribute The attribute to be removed 
 
786
         * @chainable
 
787
         */
 
788
        'removeAttribute',
 
789
 
 
790
        /**
 
791
         * Passes through to DOM method.
 
792
         * @method scrollIntoView
 
793
         * @chainable
 
794
         */
 
795
        'scrollIntoView',
 
796
 
 
797
        /**
 
798
         * Passes through to DOM method.
 
799
         * @method getElementsByTagName
 
800
         * @param {String} tagName The tagName to collect 
 
801
         * @return {NodeList} A NodeList representing the HTMLCollection
 
802
         */
 
803
        'getElementsByTagName',
 
804
 
 
805
        /**
 
806
         * Passes through to DOM method.
 
807
         * @method focus
 
808
         * @chainable
 
809
         */
 
810
        'focus',
 
811
 
 
812
        /**
 
813
         * Passes through to DOM method.
 
814
         * @method blur
 
815
         * @chainable
 
816
         */
 
817
        'blur',
 
818
 
 
819
        /**
 
820
         * Passes through to DOM method.
 
821
         * Only valid on FORM elements
 
822
         * @method submit
 
823
         * @chainable
 
824
         */
 
825
        'submit',
 
826
 
 
827
        /**
 
828
         * Passes through to DOM method.
 
829
         * Only valid on FORM elements
 
830
         * @method reset
 
831
         * @chainable
 
832
         */
 
833
        'reset',
 
834
 
 
835
        /**
 
836
         * Passes through to DOM method.
 
837
         * @method select
 
838
         * @chainable
 
839
         */
 
840
         'select'
 
841
    ], function(method) {
 
842
        Node.prototype[method] = function(arg1, arg2, arg3) {
 
843
            var ret = this.invoke(method, arg1, arg2, arg3);
 
844
            return ret;
 
845
        };
 
846
    });
 
847
 
 
848
    if (!document.documentElement.hasAttribute) {
 
849
        Node.methods({
 
850
            'hasAttribute': function(node, att) {
 
851
                return !! node.getAttribute(att);
 
852
            }
 
853
        });
 
854
    }
879
855
 
880
856
    // used to call Node methods against NodeList nodes
881
 
    var _tmpNode = Node.create('<div></div>');
882
 
    NodeList.prototype = {};
883
 
 
884
 
    Y.each(Node.prototype, function(fn, name) {
885
 
        if (typeof Node.prototype[name] == 'function') {
886
 
            addNodeListMethod(name);
887
 
        }
888
 
    });
889
 
 
890
 
    Y.mix(NodeList.prototype, {
891
 
        /**
892
 
         * Retrieves the Node instance at the given index. 
893
 
         * @method item
894
 
         *
895
 
         * @param {Number} index The index of the target Node.
896
 
         * @return {Node} The Node instance at the given index.
897
 
         */
898
 
        item: function(index) {
899
 
            var node = _nodelists[this._yuid][index];
900
 
            return (node && node[TAG_NAME]) ? wrapDOM(node) : (node && node.get) ? node : null;
901
 
        },
902
 
 
903
 
        /**
904
 
         * Set the value of the property/attribute on all HTMLElements bound to this NodeList.
905
 
         * Only strings/numbers/booleans are passed through unless a SETTER exists.
906
 
         * @method set
907
 
         * @param {String} prop Property to set 
908
 
         * @param {any} val Value to apply to the given property
909
 
         * @see Node
910
 
         * @chainable
911
 
         */
912
 
        set: function(name, val) {
913
 
            var nodes = _nodelists[this._yuid];
914
 
            for (var i = 0, len = nodes.length; i < len; ++i) {
915
 
                _nodes[_tmpNode._yuid] = nodes[i];
916
 
                _tmpNode.set(name, val);
917
 
            }
918
 
 
919
 
            return this;
920
 
        },
921
 
 
922
 
        /**
923
 
         * Get the value of the property/attribute for each of the HTMLElements bound to this NodeList.
924
 
         * Only strings/numbers/booleans are passed through unless a GETTER exists.
925
 
         * @method get
926
 
         * @param {String} prop Property to get 
927
 
         * @return {Array} Array containing the current values mapped to the Node indexes 
928
 
         * @see Node
929
 
         */
930
 
        get: function(name) {
931
 
            if (name == 'length') { // TODO: remove
932
 
                return _nodelists[this._yuid].length;
933
 
            }
934
 
            var nodes = _nodelists[this._yuid];
935
 
            var ret = [];
936
 
            for (var i = 0, len = nodes.length; i < len; ++i) {
937
 
                _nodes[_tmpNode._yuid] = nodes[i];
938
 
                ret[i] = _tmpNode.get(name);
939
 
            }
940
 
 
941
 
            return ret;
942
 
        },
943
 
 
944
 
        /**
945
 
         * Filters the NodeList instance down to only nodes matching the given selector.
946
 
         * @method filter
947
 
         * @param {String} selector The selector to filter against
948
 
         * @return {NodeList} NodeList containing the updated collection 
949
 
         * @see Selector
950
 
         */
951
 
        filter: function(selector) {
952
 
            return wrapDOM(Selector.filter(_nodelists[this._yuid], selector));
953
 
        },
954
 
 
955
 
        /**
956
 
         * Applies the given function to each Node in the NodeList.
957
 
         * @method each
958
 
         * @param {Function} fn The function to apply 
959
 
         * @param {Object} context optional An optional context to apply the function with
960
 
         * Default context is the NodeList instance
961
 
         * @return {NodeList} NodeList containing the updated collection 
962
 
         * @chainable
963
 
         */
964
 
        each: function(fn, context) {
965
 
            context = context || this;
966
 
            var nodes = _nodelists[this._yuid];
967
 
            for (var i = 0, len = nodes.length; i < len; ++i) {
968
 
                fn.call(context, Y.Node.get(nodes[i]), i, this);
969
 
            }
970
 
            return this;
971
 
        },
972
 
 
973
 
        /**
974
 
         * Returns the current number of items in the NodeList.
975
 
         * @method size
976
 
         * @return {Int} The number of items in the NodeList. 
977
 
         */
978
 
        size: function() {
979
 
            return _nodelists[this._yuid].length;
980
 
        },
981
 
 
982
 
        toString: function() {
983
 
            var nodes = _nodelists[this._yuid] || [];
984
 
            return 'NodeList (' + nodes.length + ' items)';
985
 
        }
986
 
 
987
 
    }, true);
988
 
 
989
857
    Y.Node = Node;
990
 
    Y.NodeList = NodeList;
991
858
    Y.all = Y.Node.all;
992
859
    Y.get = Y.Node.get;
993
860
/**
994
861
 * Extended Node interface for managing classNames.
995
862
 * @module node
 
863
 * @submodule node
996
864
 * @for Node
997
865
 */
998
866
 
1041
909
    ]);
1042
910
 
1043
911
 
1044
 
}, '3.0.0pr1' ,{requires:['dom-base', 'selector']});
 
912
}, '3.0.0pr2' ,{requires:['dom-base', 'selector']});