~michael.nelson/ubuntu-webcatalog/1267731-import-sca-apps-error

« back to all changes in this revision

Viewing changes to src/webcatalog/static/yui/3.10.3/build/node-base/node-base.js

  • Committer: Tarmac
  • Author(s): Stephen Stewart
  • Date: 2013-06-26 09:19:32 UTC
  • mfrom: (184.1.4 ubuntu-global-nav)
  • Revision ID: tarmac-20130626091932-8urtuli368k8p7ds
[r=beuno,jonas-drange] add ubuntu global nav to apps.ubuntu.com

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
YUI 3.10.3 (build 2fb5187)
 
3
Copyright 2013 Yahoo! Inc. All rights reserved.
 
4
Licensed under the BSD License.
 
5
http://yuilibrary.com/license/
 
6
*/
 
7
 
 
8
YUI.add('node-base', function (Y, NAME) {
 
9
 
 
10
/**
 
11
 * @module node
 
12
 * @submodule node-base
 
13
 */
 
14
 
 
15
var methods = [
 
16
/**
 
17
 * Determines whether each node has the given className.
 
18
 * @method hasClass
 
19
 * @for Node
 
20
 * @param {String} className the class name to search for
 
21
 * @return {Boolean} Whether or not the element has the specified class
 
22
 */
 
23
 'hasClass',
 
24
 
 
25
/**
 
26
 * Adds a class name to each node.
 
27
 * @method addClass
 
28
 * @param {String} className the class name to add to the node's class attribute
 
29
 * @chainable
 
30
 */
 
31
 'addClass',
 
32
 
 
33
/**
 
34
 * Removes a class name from each node.
 
35
 * @method removeClass
 
36
 * @param {String} className the class name to remove from the node's class attribute
 
37
 * @chainable
 
38
 */
 
39
 'removeClass',
 
40
 
 
41
/**
 
42
 * Replace a class with another class for each node.
 
43
 * If no oldClassName is present, the newClassName is simply added.
 
44
 * @method replaceClass
 
45
 * @param {String} oldClassName the class name to be replaced
 
46
 * @param {String} newClassName the class name that will be replacing the old class name
 
47
 * @chainable
 
48
 */
 
49
 'replaceClass',
 
50
 
 
51
/**
 
52
 * If the className exists on the node it is removed, if it doesn't exist it is added.
 
53
 * @method toggleClass
 
54
 * @param {String} className the class name to be toggled
 
55
 * @param {Boolean} force Option to force adding or removing the class.
 
56
 * @chainable
 
57
 */
 
58
 'toggleClass'
 
59
];
 
60
 
 
61
Y.Node.importMethod(Y.DOM, methods);
 
62
/**
 
63
 * Determines whether each node has the given className.
 
64
 * @method hasClass
 
65
 * @see Node.hasClass
 
66
 * @for NodeList
 
67
 * @param {String} className the class name to search for
 
68
 * @return {Array} An array of booleans for each node bound to the NodeList.
 
69
 */
 
70
 
 
71
/**
 
72
 * Adds a class name to each node.
 
73
 * @method addClass
 
74
 * @see Node.addClass
 
75
 * @param {String} className the class name to add to the node's class attribute
 
76
 * @chainable
 
77
 */
 
78
 
 
79
/**
 
80
 * Removes a class name from each node.
 
81
 * @method removeClass
 
82
 * @see Node.removeClass
 
83
 * @param {String} className the class name to remove from the node's class attribute
 
84
 * @chainable
 
85
 */
 
86
 
 
87
/**
 
88
 * Replace a class with another class for each node.
 
89
 * If no oldClassName is present, the newClassName is simply added.
 
90
 * @method replaceClass
 
91
 * @see Node.replaceClass
 
92
 * @param {String} oldClassName the class name to be replaced
 
93
 * @param {String} newClassName the class name that will be replacing the old class name
 
94
 * @chainable
 
95
 */
 
96
 
 
97
/**
 
98
 * If the className exists on the node it is removed, if it doesn't exist it is added.
 
99
 * @method toggleClass
 
100
 * @see Node.toggleClass
 
101
 * @param {String} className the class name to be toggled
 
102
 * @chainable
 
103
 */
 
104
Y.NodeList.importMethod(Y.Node.prototype, methods);
 
105
/**
 
106
 * @module node
 
107
 * @submodule node-base
 
108
 */
 
109
 
 
110
var Y_Node = Y.Node,
 
111
    Y_DOM = Y.DOM;
 
112
 
 
113
/**
 
114
 * Returns a new dom node using the provided markup string.
 
115
 * @method create
 
116
 * @static
 
117
 * @param {String} html The markup used to create the element
 
118
 * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
119
 * to escape html content.
 
120
 * @param {HTMLDocument} doc An optional document context
 
121
 * @return {Node} A Node instance bound to a DOM node or fragment
 
122
 * @for Node
 
123
 */
 
124
Y_Node.create = function(html, doc) {
 
125
    if (doc && doc._node) {
 
126
        doc = doc._node;
 
127
    }
 
128
    return Y.one(Y_DOM.create(html, doc));
 
129
};
 
130
 
 
131
Y.mix(Y_Node.prototype, {
 
132
    /**
 
133
     * Creates a new Node using the provided markup string.
 
134
     * @method create
 
135
     * @param {String} html The markup used to create the element.
 
136
     * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
137
     * to escape html content.
 
138
     * @param {HTMLDocument} doc An optional document context
 
139
     * @return {Node} A Node instance bound to a DOM node or fragment
 
140
     */
 
141
    create: Y_Node.create,
 
142
 
 
143
    /**
 
144
     * Inserts the content before the reference node.
 
145
     * @method insert
 
146
     * @param {String | Node | HTMLElement | NodeList | HTMLCollection} content The content to insert
 
147
     * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
148
     * to escape html content.
 
149
     * @param {Int | Node | HTMLElement | String} where The position to insert at.
 
150
     * Possible "where" arguments
 
151
     * <dl>
 
152
     * <dt>Y.Node</dt>
 
153
     * <dd>The Node to insert before</dd>
 
154
     * <dt>HTMLElement</dt>
 
155
     * <dd>The element to insert before</dd>
 
156
     * <dt>Int</dt>
 
157
     * <dd>The index of the child element to insert before</dd>
 
158
     * <dt>"replace"</dt>
 
159
     * <dd>Replaces the existing HTML</dd>
 
160
     * <dt>"before"</dt>
 
161
     * <dd>Inserts before the existing HTML</dd>
 
162
     * <dt>"before"</dt>
 
163
     * <dd>Inserts content before the node</dd>
 
164
     * <dt>"after"</dt>
 
165
     * <dd>Inserts content after the node</dd>
 
166
     * </dl>
 
167
     * @chainable
 
168
     */
 
169
    insert: function(content, where) {
 
170
        this._insert(content, where);
 
171
        return this;
 
172
    },
 
173
 
 
174
    _insert: function(content, where) {
 
175
        var node = this._node,
 
176
            ret = null;
 
177
 
 
178
        if (typeof where == 'number') { // allow index
 
179
            where = this._node.childNodes[where];
 
180
        } else if (where && where._node) { // Node
 
181
            where = where._node;
 
182
        }
 
183
 
 
184
        if (content && typeof content != 'string') { // allow Node or NodeList/Array instances
 
185
            content = content._node || content._nodes || content;
 
186
        }
 
187
        ret = Y_DOM.addHTML(node, content, where);
 
188
 
 
189
        return ret;
 
190
    },
 
191
 
 
192
    /**
 
193
     * Inserts the content as the firstChild of the node.
 
194
     * @method prepend
 
195
     * @param {String | Node | HTMLElement} content The content to insert
 
196
     * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
197
     * to escape html content.
 
198
     * @chainable
 
199
     */
 
200
    prepend: function(content) {
 
201
        return this.insert(content, 0);
 
202
    },
 
203
 
 
204
    /**
 
205
     * Inserts the content as the lastChild of the node.
 
206
     * @method append
 
207
     * @param {String | Node | HTMLElement} content The content to insert
 
208
     * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
209
     * to escape html content.
 
210
     * @chainable
 
211
     */
 
212
    append: function(content) {
 
213
        return this.insert(content, null);
 
214
    },
 
215
 
 
216
    /**
 
217
     * @method appendChild
 
218
     * @param {String | HTMLElement | Node} node Node to be appended
 
219
     * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
220
     * to escape html content.
 
221
     * @return {Node} The appended node
 
222
     */
 
223
    appendChild: function(node) {
 
224
        return Y_Node.scrubVal(this._insert(node));
 
225
    },
 
226
 
 
227
    /**
 
228
     * @method insertBefore
 
229
     * @param {String | HTMLElement | Node} newNode Node to be appended
 
230
     * @param {HTMLElement | Node} refNode Node to be inserted before
 
231
     * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
232
     * to escape html content.
 
233
     * @return {Node} The inserted node
 
234
     */
 
235
    insertBefore: function(newNode, refNode) {
 
236
        return Y.Node.scrubVal(this._insert(newNode, refNode));
 
237
    },
 
238
 
 
239
    /**
 
240
     * Appends the node to the given node.
 
241
     * @method appendTo
 
242
     * @param {Node | HTMLElement} node The node to append to
 
243
     * @chainable
 
244
     */
 
245
    appendTo: function(node) {
 
246
        Y.one(node).append(this);
 
247
        return this;
 
248
    },
 
249
 
 
250
    /**
 
251
     * Replaces the node's current content with the content.
 
252
     * Note that this passes to innerHTML and is not escaped.
 
253
     * Use <a href="../classes/Escape.html#method_html">`Y.Escape.html()`</a>
 
254
     * to escape html content or `set('text')` to add as text.
 
255
     * @method setContent
 
256
     * @deprecated Use setHTML
 
257
     * @param {String | Node | HTMLElement | NodeList | HTMLCollection} content The content to insert
 
258
     * @chainable
 
259
     */
 
260
    setContent: function(content) {
 
261
        this._insert(content, 'replace');
 
262
        return this;
 
263
    },
 
264
 
 
265
    /**
 
266
     * Returns the node's current content (e.g. innerHTML)
 
267
     * @method getContent
 
268
     * @deprecated Use getHTML
 
269
     * @return {String} The current content
 
270
     */
 
271
    getContent: function(content) {
 
272
        return this.get('innerHTML');
 
273
    }
 
274
});
 
275
 
 
276
/**
 
277
 * Replaces the node's current html content with the content provided.
 
278
 * Note that this passes to innerHTML and is not escaped.
 
279
 * Use `Y.Escape.html()` to escape HTML, or `set('text')` to add as text.
 
280
 * @method setHTML
 
281
 * @param {String | HTML | Node | HTMLElement | NodeList | HTMLCollection} content The content to insert
 
282
 * @chainable
 
283
 */
 
284
Y.Node.prototype.setHTML = Y.Node.prototype.setContent;
 
285
 
 
286
/**
 
287
 * Returns the node's current html content (e.g. innerHTML)
 
288
 * @method getHTML
 
289
 * @return {String} The html content
 
290
 */
 
291
Y.Node.prototype.getHTML = Y.Node.prototype.getContent;
 
292
 
 
293
Y.NodeList.importMethod(Y.Node.prototype, [
 
294
    /**
 
295
     * Called on each Node instance
 
296
     * @for NodeList
 
297
     * @method append
 
298
     * @see Node.append
 
299
     */
 
300
    'append',
 
301
 
 
302
    /**
 
303
     * Called on each Node instance
 
304
     * @for NodeList
 
305
     * @method insert
 
306
     * @see Node.insert
 
307
     */
 
308
    'insert',
 
309
 
 
310
    /**
 
311
     * Called on each Node instance
 
312
     * @for NodeList
 
313
     * @method appendChild
 
314
     * @see Node.appendChild
 
315
     */
 
316
    'appendChild',
 
317
 
 
318
    /**
 
319
     * Called on each Node instance
 
320
     * @for NodeList
 
321
     * @method insertBefore
 
322
     * @see Node.insertBefore
 
323
     */
 
324
    'insertBefore',
 
325
 
 
326
    /**
 
327
     * Called on each Node instance
 
328
     * @for NodeList
 
329
     * @method prepend
 
330
     * @see Node.prepend
 
331
     */
 
332
    'prepend',
 
333
 
 
334
    /**
 
335
     * Called on each Node instance
 
336
     * Note that this passes to innerHTML and is not escaped.
 
337
     * Use `Y.Escape.html()` to escape HTML, or `set('text')` to add as text.
 
338
     * @for NodeList
 
339
     * @method setContent
 
340
     * @deprecated Use setHTML
 
341
     */
 
342
    'setContent',
 
343
 
 
344
    /**
 
345
     * Called on each Node instance
 
346
     * @for NodeList
 
347
     * @method getContent
 
348
     * @deprecated Use getHTML
 
349
     */
 
350
    'getContent',
 
351
 
 
352
    /**
 
353
     * Called on each Node instance
 
354
     * Note that this passes to innerHTML and is not escaped.
 
355
     * Use `Y.Escape.html()` to escape HTML, or `set('text')` to add as text.
 
356
     * @for NodeList
 
357
     * @method setHTML
 
358
     * @see Node.setHTML
 
359
     */
 
360
    'setHTML',
 
361
 
 
362
    /**
 
363
     * Called on each Node instance
 
364
     * @for NodeList
 
365
     * @method getHTML
 
366
     * @see Node.getHTML
 
367
     */
 
368
    'getHTML'
 
369
]);
 
370
/**
 
371
 * @module node
 
372
 * @submodule node-base
 
373
 */
 
374
 
 
375
var Y_Node = Y.Node,
 
376
    Y_DOM = Y.DOM;
 
377
 
 
378
/**
 
379
 * Static collection of configuration attributes for special handling
 
380
 * @property ATTRS
 
381
 * @static
 
382
 * @type object
 
383
 */
 
384
Y_Node.ATTRS = {
 
385
    /**
 
386
     * Allows for getting and setting the text of an element.
 
387
     * Formatting is preserved and special characters are treated literally.
 
388
     * @config text
 
389
     * @type String
 
390
     */
 
391
    text: {
 
392
        getter: function() {
 
393
            return Y_DOM.getText(this._node);
 
394
        },
 
395
 
 
396
        setter: function(content) {
 
397
            Y_DOM.setText(this._node, content);
 
398
            return content;
 
399
        }
 
400
    },
 
401
 
 
402
    /**
 
403
     * Allows for getting and setting the text of an element.
 
404
     * Formatting is preserved and special characters are treated literally.
 
405
     * @config for
 
406
     * @type String
 
407
     */
 
408
    'for': {
 
409
        getter: function() {
 
410
            return Y_DOM.getAttribute(this._node, 'for');
 
411
        },
 
412
 
 
413
        setter: function(val) {
 
414
            Y_DOM.setAttribute(this._node, 'for', val);
 
415
            return val;
 
416
        }
 
417
    },
 
418
 
 
419
    'options': {
 
420
        getter: function() {
 
421
            return this._node.getElementsByTagName('option');
 
422
        }
 
423
    },
 
424
 
 
425
    /**
 
426
     * Returns a NodeList instance of all HTMLElement children.
 
427
     * @readOnly
 
428
     * @config children
 
429
     * @type NodeList
 
430
     */
 
431
    'children': {
 
432
        getter: function() {
 
433
            var node = this._node,
 
434
                children = node.children,
 
435
                childNodes, i, len;
 
436
 
 
437
            if (!children) {
 
438
                childNodes = node.childNodes;
 
439
                children = [];
 
440
 
 
441
                for (i = 0, len = childNodes.length; i < len; ++i) {
 
442
                    if (childNodes[i].tagName) {
 
443
                        children[children.length] = childNodes[i];
 
444
                    }
 
445
                }
 
446
            }
 
447
            return Y.all(children);
 
448
        }
 
449
    },
 
450
 
 
451
    value: {
 
452
        getter: function() {
 
453
            return Y_DOM.getValue(this._node);
 
454
        },
 
455
 
 
456
        setter: function(val) {
 
457
            Y_DOM.setValue(this._node, val);
 
458
            return val;
 
459
        }
 
460
    }
 
461
};
 
462
 
 
463
Y.Node.importMethod(Y.DOM, [
 
464
    /**
 
465
     * Allows setting attributes on DOM nodes, normalizing in some cases.
 
466
     * This passes through to the DOM node, allowing for custom attributes.
 
467
     * @method setAttribute
 
468
     * @for Node
 
469
     * @for NodeList
 
470
     * @chainable
 
471
     * @param {string} name The attribute name
 
472
     * @param {string} value The value to set
 
473
     */
 
474
    'setAttribute',
 
475
    /**
 
476
     * Allows getting attributes on DOM nodes, normalizing in some cases.
 
477
     * This passes through to the DOM node, allowing for custom attributes.
 
478
     * @method getAttribute
 
479
     * @for Node
 
480
     * @for NodeList
 
481
     * @param {string} name The attribute name
 
482
     * @return {string} The attribute value
 
483
     */
 
484
    'getAttribute'
 
485
 
 
486
]);
 
487
/**
 
488
 * @module node
 
489
 * @submodule node-base
 
490
 */
 
491
 
 
492
var Y_Node = Y.Node;
 
493
var Y_NodeList = Y.NodeList;
 
494
/**
 
495
 * List of events that route to DOM events
 
496
 * @static
 
497
 * @property DOM_EVENTS
 
498
 * @for Node
 
499
 */
 
500
 
 
501
Y_Node.DOM_EVENTS = {
 
502
    abort: 1,
 
503
    beforeunload: 1,
 
504
    blur: 1,
 
505
    change: 1,
 
506
    click: 1,
 
507
    close: 1,
 
508
    command: 1,
 
509
    contextmenu: 1,
 
510
    dblclick: 1,
 
511
    DOMMouseScroll: 1,
 
512
    drag: 1,
 
513
    dragstart: 1,
 
514
    dragenter: 1,
 
515
    dragover: 1,
 
516
    dragleave: 1,
 
517
    dragend: 1,
 
518
    drop: 1,
 
519
    error: 1,
 
520
    focus: 1,
 
521
    key: 1,
 
522
    keydown: 1,
 
523
    keypress: 1,
 
524
    keyup: 1,
 
525
    load: 1,
 
526
    message: 1,
 
527
    mousedown: 1,
 
528
    mouseenter: 1,
 
529
    mouseleave: 1,
 
530
    mousemove: 1,
 
531
    mousemultiwheel: 1,
 
532
    mouseout: 1,
 
533
    mouseover: 1,
 
534
    mouseup: 1,
 
535
    mousewheel: 1,
 
536
    orientationchange: 1,
 
537
    reset: 1,
 
538
    resize: 1,
 
539
    select: 1,
 
540
    selectstart: 1,
 
541
    submit: 1,
 
542
    scroll: 1,
 
543
    textInput: 1,
 
544
    unload: 1
 
545
};
 
546
 
 
547
// Add custom event adaptors to this list.  This will make it so
 
548
// that delegate, key, available, contentready, etc all will
 
549
// be available through Node.on
 
550
Y.mix(Y_Node.DOM_EVENTS, Y.Env.evt.plugins);
 
551
 
 
552
Y.augment(Y_Node, Y.EventTarget);
 
553
 
 
554
Y.mix(Y_Node.prototype, {
 
555
    /**
 
556
     * Removes event listeners from the node and (optionally) its subtree
 
557
     * @method purge
 
558
     * @param {Boolean} recurse (optional) Whether or not to remove listeners from the
 
559
     * node's subtree
 
560
     * @param {String} type (optional) Only remove listeners of the specified type
 
561
     * @chainable
 
562
     *
 
563
     */
 
564
    purge: function(recurse, type) {
 
565
        Y.Event.purgeElement(this._node, recurse, type);
 
566
        return this;
 
567
    }
 
568
 
 
569
});
 
570
 
 
571
Y.mix(Y.NodeList.prototype, {
 
572
    _prepEvtArgs: function(type, fn, context) {
 
573
        // map to Y.on/after signature (type, fn, nodes, context, arg1, arg2, etc)
 
574
        var args = Y.Array(arguments, 0, true);
 
575
 
 
576
        if (args.length < 2) { // type only (event hash) just add nodes
 
577
            args[2] = this._nodes;
 
578
        } else {
 
579
            args.splice(2, 0, this._nodes);
 
580
        }
 
581
 
 
582
        args[3] = context || this; // default to NodeList instance as context
 
583
 
 
584
        return args;
 
585
    },
 
586
 
 
587
    /**
 
588
    Subscribe a callback function for each `Node` in the collection to execute
 
589
    in response to a DOM event.
 
590
 
 
591
    NOTE: Generally, the `on()` method should be avoided on `NodeLists`, in
 
592
    favor of using event delegation from a parent Node.  See the Event user
 
593
    guide for details.
 
594
 
 
595
    Most DOM events are associated with a preventable default behavior, such as
 
596
    link clicks navigating to a new page.  Callbacks are passed a
 
597
    `DOMEventFacade` object as their first argument (usually called `e`) that
 
598
    can be used to prevent this default behavior with `e.preventDefault()`. See
 
599
    the `DOMEventFacade` API for all available properties and methods on the
 
600
    object.
 
601
 
 
602
    By default, the `this` object will be the `NodeList` that the subscription
 
603
    came from, <em>not the `Node` that received the event</em>.  Use
 
604
    `e.currentTarget` to refer to the `Node`.
 
605
 
 
606
    Returning `false` from a callback is supported as an alternative to calling
 
607
    `e.preventDefault(); e.stopPropagation();`.  However, it is recommended to
 
608
    use the event methods.
 
609
 
 
610
    @example
 
611
 
 
612
        Y.all(".sku").on("keydown", function (e) {
 
613
            if (e.keyCode === 13) {
 
614
                e.preventDefault();
 
615
 
 
616
                // Use e.currentTarget to refer to the individual Node
 
617
                var item = Y.MyApp.searchInventory( e.currentTarget.get('value') );
 
618
                // etc ...
 
619
            }
 
620
        });
 
621
 
 
622
    @method on
 
623
    @param {String} type The name of the event
 
624
    @param {Function} fn The callback to execute in response to the event
 
625
    @param {Object} [context] Override `this` object in callback
 
626
    @param {Any} [arg*] 0..n additional arguments to supply to the subscriber
 
627
    @return {EventHandle} A subscription handle capable of detaching that
 
628
                          subscription
 
629
    @for NodeList
 
630
    **/
 
631
    on: function(type, fn, context) {
 
632
        return Y.on.apply(Y, this._prepEvtArgs.apply(this, arguments));
 
633
    },
 
634
 
 
635
    /**
 
636
     * Applies an one-time event listener to each Node bound to the NodeList.
 
637
     * @method once
 
638
     * @param {String} type The event being listened for
 
639
     * @param {Function} fn The handler to call when the event fires
 
640
     * @param {Object} context The context to call the handler with.
 
641
     * Default is the NodeList instance.
 
642
     * @return {EventHandle} A subscription handle capable of detaching that
 
643
     *                    subscription
 
644
     * @for NodeList
 
645
     */
 
646
    once: function(type, fn, context) {
 
647
        return Y.once.apply(Y, this._prepEvtArgs.apply(this, arguments));
 
648
    },
 
649
 
 
650
    /**
 
651
     * Applies an event listener to each Node bound to the NodeList.
 
652
     * The handler is called only after all on() handlers are called
 
653
     * and the event is not prevented.
 
654
     * @method after
 
655
     * @param {String} type The event being listened for
 
656
     * @param {Function} fn The handler to call when the event fires
 
657
     * @param {Object} context The context to call the handler with.
 
658
     * Default is the NodeList instance.
 
659
     * @return {EventHandle} A subscription handle capable of detaching that
 
660
     *                    subscription
 
661
     * @for NodeList
 
662
     */
 
663
    after: function(type, fn, context) {
 
664
        return Y.after.apply(Y, this._prepEvtArgs.apply(this, arguments));
 
665
    },
 
666
 
 
667
    /**
 
668
     * Applies an one-time event listener to each Node bound to the NodeList
 
669
     * that will be called only after all on() handlers are called and the
 
670
     * event is not prevented.
 
671
     *
 
672
     * @method onceAfter
 
673
     * @param {String} type The event being listened for
 
674
     * @param {Function} fn The handler to call when the event fires
 
675
     * @param {Object} context The context to call the handler with.
 
676
     * Default is the NodeList instance.
 
677
     * @return {EventHandle} A subscription handle capable of detaching that
 
678
     *                    subscription
 
679
     * @for NodeList
 
680
     */
 
681
    onceAfter: function(type, fn, context) {
 
682
        return Y.onceAfter.apply(Y, this._prepEvtArgs.apply(this, arguments));
 
683
    }
 
684
});
 
685
 
 
686
Y_NodeList.importMethod(Y.Node.prototype, [
 
687
    /**
 
688
      * Called on each Node instance
 
689
      * @method detach
 
690
      * @see Node.detach
 
691
      * @for NodeList
 
692
      */
 
693
    'detach',
 
694
 
 
695
    /** Called on each Node instance
 
696
      * @method detachAll
 
697
      * @see Node.detachAll
 
698
      * @for NodeList
 
699
      */
 
700
    'detachAll'
 
701
]);
 
702
 
 
703
/**
 
704
Subscribe a callback function to execute in response to a DOM event or custom
 
705
event.
 
706
 
 
707
Most DOM events are associated with a preventable default behavior such as
 
708
link clicks navigating to a new page.  Callbacks are passed a `DOMEventFacade`
 
709
object as their first argument (usually called `e`) that can be used to
 
710
prevent this default behavior with `e.preventDefault()`. See the
 
711
`DOMEventFacade` API for all available properties and methods on the object.
 
712
 
 
713
If the event name passed as the first parameter is not a whitelisted DOM event,
 
714
it will be treated as a custom event subscriptions, allowing
 
715
`node.fire('customEventName')` later in the code.  Refer to the Event user guide
 
716
for the full DOM event whitelist.
 
717
 
 
718
By default, the `this` object in the callback will refer to the subscribed
 
719
`Node`.
 
720
 
 
721
Returning `false` from a callback is supported as an alternative to calling
 
722
`e.preventDefault(); e.stopPropagation();`.  However, it is recommended to use
 
723
the event methods.
 
724
 
 
725
@example
 
726
 
 
727
    Y.one("#my-form").on("submit", function (e) {
 
728
        e.preventDefault();
 
729
 
 
730
        // proceed with ajax form submission instead...
 
731
    });
 
732
 
 
733
@method on
 
734
@param {String} type The name of the event
 
735
@param {Function} fn The callback to execute in response to the event
 
736
@param {Object} [context] Override `this` object in callback
 
737
@param {Any} [arg*] 0..n additional arguments to supply to the subscriber
 
738
@return {EventHandle} A subscription handle capable of detaching that
 
739
                      subscription
 
740
@for Node
 
741
**/
 
742
 
 
743
Y.mix(Y.Node.ATTRS, {
 
744
    offsetHeight: {
 
745
        setter: function(h) {
 
746
            Y.DOM.setHeight(this._node, h);
 
747
            return h;
 
748
        },
 
749
 
 
750
        getter: function() {
 
751
            return this._node.offsetHeight;
 
752
        }
 
753
    },
 
754
 
 
755
    offsetWidth: {
 
756
        setter: function(w) {
 
757
            Y.DOM.setWidth(this._node, w);
 
758
            return w;
 
759
        },
 
760
 
 
761
        getter: function() {
 
762
            return this._node.offsetWidth;
 
763
        }
 
764
    }
 
765
});
 
766
 
 
767
Y.mix(Y.Node.prototype, {
 
768
    sizeTo: function(w, h) {
 
769
        var node;
 
770
        if (arguments.length < 2) {
 
771
            node = Y.one(w);
 
772
            w = node.get('offsetWidth');
 
773
            h = node.get('offsetHeight');
 
774
        }
 
775
 
 
776
        this.setAttrs({
 
777
            offsetWidth: w,
 
778
            offsetHeight: h
 
779
        });
 
780
    }
 
781
});
 
782
/**
 
783
 * @module node
 
784
 * @submodule node-base
 
785
 */
 
786
 
 
787
var Y_Node = Y.Node;
 
788
 
 
789
Y.mix(Y_Node.prototype, {
 
790
    /**
 
791
     * Makes the node visible.
 
792
     * If the "transition" module is loaded, show optionally
 
793
     * animates the showing of the node using either the default
 
794
     * transition effect ('fadeIn'), or the given named effect.
 
795
     * @method show
 
796
     * @for Node
 
797
     * @param {String} name A named Transition effect to use as the show effect.
 
798
     * @param {Object} config Options to use with the transition.
 
799
     * @param {Function} callback An optional function to run after the transition completes.
 
800
     * @chainable
 
801
     */
 
802
    show: function(callback) {
 
803
        callback = arguments[arguments.length - 1];
 
804
        this.toggleView(true, callback);
 
805
        return this;
 
806
    },
 
807
 
 
808
    /**
 
809
     * The implementation for showing nodes.
 
810
     * Default is to remove the hidden attribute and reset the CSS style.display property.
 
811
     * @method _show
 
812
     * @protected
 
813
     * @chainable
 
814
     */
 
815
    _show: function() {
 
816
        this.removeAttribute('hidden');
 
817
 
 
818
        // For back-compat we need to leave this in for browsers that
 
819
        // do not visually hide a node via the hidden attribute
 
820
        // and for users that check visibility based on style display.
 
821
        this.setStyle('display', '');
 
822
 
 
823
    },
 
824
 
 
825
    _isHidden: function() {
 
826
        return Y.DOM.getAttribute(this._node, 'hidden') === 'true';
 
827
    },
 
828
 
 
829
    /**
 
830
     * Displays or hides the node.
 
831
     * If the "transition" module is loaded, toggleView optionally
 
832
     * animates the toggling of the node using given named effect.
 
833
     * @method toggleView
 
834
     * @for Node
 
835
     * @param {String} [name] An optional string value to use as transition effect.
 
836
     * @param {Boolean} [on] An optional boolean value to force the node to be shown or hidden
 
837
     * @param {Function} [callback] An optional function to run after the transition completes.
 
838
     * @chainable
 
839
     */
 
840
    toggleView: function(on, callback) {
 
841
        this._toggleView.apply(this, arguments);
 
842
        return this;
 
843
    },
 
844
 
 
845
    _toggleView: function(on, callback) {
 
846
        callback = arguments[arguments.length - 1];
 
847
 
 
848
        // base on current state if not forcing
 
849
        if (typeof on != 'boolean') {
 
850
            on = (this._isHidden()) ? 1 : 0;
 
851
        }
 
852
 
 
853
        if (on) {
 
854
            this._show();
 
855
        }  else {
 
856
            this._hide();
 
857
        }
 
858
 
 
859
        if (typeof callback == 'function') {
 
860
            callback.call(this);
 
861
        }
 
862
 
 
863
        return this;
 
864
    },
 
865
 
 
866
    /**
 
867
     * Hides the node.
 
868
     * If the "transition" module is loaded, hide optionally
 
869
     * animates the hiding of the node using either the default
 
870
     * transition effect ('fadeOut'), or the given named effect.
 
871
     * @method hide
 
872
     * @param {String} name A named Transition effect to use as the show effect.
 
873
     * @param {Object} config Options to use with the transition.
 
874
     * @param {Function} callback An optional function to run after the transition completes.
 
875
     * @chainable
 
876
     */
 
877
    hide: function(callback) {
 
878
        callback = arguments[arguments.length - 1];
 
879
        this.toggleView(false, callback);
 
880
        return this;
 
881
    },
 
882
 
 
883
    /**
 
884
     * The implementation for hiding nodes.
 
885
     * Default is to set the hidden attribute to true and set the CSS style.display to 'none'.
 
886
     * @method _hide
 
887
     * @protected
 
888
     * @chainable
 
889
     */
 
890
    _hide: function() {
 
891
        this.setAttribute('hidden', true);
 
892
 
 
893
        // For back-compat we need to leave this in for browsers that
 
894
        // do not visually hide a node via the hidden attribute
 
895
        // and for users that check visibility based on style display.
 
896
        this.setStyle('display', 'none');
 
897
    }
 
898
});
 
899
 
 
900
Y.NodeList.importMethod(Y.Node.prototype, [
 
901
    /**
 
902
     * Makes each node visible.
 
903
     * If the "transition" module is loaded, show optionally
 
904
     * animates the showing of the node using either the default
 
905
     * transition effect ('fadeIn'), or the given named effect.
 
906
     * @method show
 
907
     * @param {String} name A named Transition effect to use as the show effect.
 
908
     * @param {Object} config Options to use with the transition.
 
909
     * @param {Function} callback An optional function to run after the transition completes.
 
910
     * @for NodeList
 
911
     * @chainable
 
912
     */
 
913
    'show',
 
914
 
 
915
    /**
 
916
     * Hides each node.
 
917
     * If the "transition" module is loaded, hide optionally
 
918
     * animates the hiding of the node using either the default
 
919
     * transition effect ('fadeOut'), or the given named effect.
 
920
     * @method hide
 
921
     * @param {String} name A named Transition effect to use as the show effect.
 
922
     * @param {Object} config Options to use with the transition.
 
923
     * @param {Function} callback An optional function to run after the transition completes.
 
924
     * @chainable
 
925
     */
 
926
    'hide',
 
927
 
 
928
    /**
 
929
     * Displays or hides each node.
 
930
     * If the "transition" module is loaded, toggleView optionally
 
931
     * animates the toggling of the nodes using given named effect.
 
932
     * @method toggleView
 
933
     * @param {String} [name] An optional string value to use as transition effect.
 
934
     * @param {Boolean} [on] An optional boolean value to force the nodes to be shown or hidden
 
935
     * @param {Function} [callback] An optional function to run after the transition completes.
 
936
     * @chainable
 
937
     */
 
938
    'toggleView'
 
939
]);
 
940
 
 
941
if (!Y.config.doc.documentElement.hasAttribute) { // IE < 8
 
942
    Y.Node.prototype.hasAttribute = function(attr) {
 
943
        if (attr === 'value') {
 
944
            if (this.get('value') !== "") { // IE < 8 fails to populate specified when set in HTML
 
945
                return true;
 
946
            }
 
947
        }
 
948
        return !!(this._node.attributes[attr] &&
 
949
                this._node.attributes[attr].specified);
 
950
    };
 
951
}
 
952
 
 
953
// IE throws an error when calling focus() on an element that's invisible, not
 
954
// displayed, or disabled.
 
955
Y.Node.prototype.focus = function () {
 
956
    try {
 
957
        this._node.focus();
 
958
    } catch (e) {
 
959
    }
 
960
 
 
961
    return this;
 
962
};
 
963
 
 
964
// IE throws error when setting input.type = 'hidden',
 
965
// input.setAttribute('type', 'hidden') and input.attributes.type.value = 'hidden'
 
966
Y.Node.ATTRS.type = {
 
967
    setter: function(val) {
 
968
        if (val === 'hidden') {
 
969
            try {
 
970
                this._node.type = 'hidden';
 
971
            } catch(e) {
 
972
                this.setStyle('display', 'none');
 
973
                this._inputType = 'hidden';
 
974
            }
 
975
        } else {
 
976
            try { // IE errors when changing the type from "hidden'
 
977
                this._node.type = val;
 
978
            } catch (e) {
 
979
            }
 
980
        }
 
981
        return val;
 
982
    },
 
983
 
 
984
    getter: function() {
 
985
        return this._inputType || this._node.type;
 
986
    },
 
987
 
 
988
    _bypassProxy: true // don't update DOM when using with Attribute
 
989
};
 
990
 
 
991
if (Y.config.doc.createElement('form').elements.nodeType) {
 
992
    // IE: elements collection is also FORM node which trips up scrubVal.
 
993
    Y.Node.ATTRS.elements = {
 
994
            getter: function() {
 
995
                return this.all('input, textarea, button, select');
 
996
            }
 
997
    };
 
998
}
 
999
 
 
1000
/**
 
1001
 * Provides methods for managing custom Node data.
 
1002
 * 
 
1003
 * @module node
 
1004
 * @main node
 
1005
 * @submodule node-data
 
1006
 */
 
1007
 
 
1008
Y.mix(Y.Node.prototype, {
 
1009
    _initData: function() {
 
1010
        if (! ('_data' in this)) {
 
1011
            this._data = {};
 
1012
        }
 
1013
    },
 
1014
 
 
1015
    /**
 
1016
    * @method getData
 
1017
    * @for Node
 
1018
    * @description Retrieves arbitrary data stored on a Node instance.
 
1019
    * If no data is associated with the Node, it will attempt to retrieve
 
1020
    * a value from the corresponding HTML data attribute. (e.g. node.getData('foo')
 
1021
    * will check node.getAttribute('data-foo')).
 
1022
    * @param {string} name Optional name of the data field to retrieve.
 
1023
    * If no name is given, all data is returned.
 
1024
    * @return {any | Object} Whatever is stored at the given field,
 
1025
    * or an object hash of all fields.
 
1026
    */
 
1027
    getData: function(name) {
 
1028
        this._initData();
 
1029
        var data = this._data,
 
1030
            ret = data;
 
1031
 
 
1032
        if (arguments.length) { // single field
 
1033
            if (name in data) {
 
1034
                ret = data[name];
 
1035
            } else { // initialize from HTML attribute
 
1036
                ret = this._getDataAttribute(name);
 
1037
            }
 
1038
        } else if (typeof data == 'object' && data !== null) { // all fields
 
1039
            ret = {};
 
1040
            Y.Object.each(data, function(v, n) {
 
1041
                ret[n] = v;
 
1042
            });
 
1043
 
 
1044
            ret = this._getDataAttributes(ret);
 
1045
        }
 
1046
 
 
1047
        return ret;
 
1048
 
 
1049
    },
 
1050
 
 
1051
    _getDataAttributes: function(ret) {
 
1052
        ret = ret || {};
 
1053
        var i = 0,
 
1054
            attrs = this._node.attributes,
 
1055
            len = attrs.length,
 
1056
            prefix = this.DATA_PREFIX,
 
1057
            prefixLength = prefix.length,
 
1058
            name;
 
1059
 
 
1060
        while (i < len) {
 
1061
            name = attrs[i].name;
 
1062
            if (name.indexOf(prefix) === 0) {
 
1063
                name = name.substr(prefixLength);
 
1064
                if (!(name in ret)) { // only merge if not already stored
 
1065
                    ret[name] = this._getDataAttribute(name);
 
1066
                }
 
1067
            }
 
1068
 
 
1069
            i += 1;
 
1070
        }
 
1071
 
 
1072
        return ret;
 
1073
    },
 
1074
 
 
1075
    _getDataAttribute: function(name) {
 
1076
        name = this.DATA_PREFIX + name;
 
1077
 
 
1078
        var node = this._node,
 
1079
            attrs = node.attributes,
 
1080
            data = attrs && attrs[name] && attrs[name].value;
 
1081
 
 
1082
        return data;
 
1083
    },
 
1084
 
 
1085
    /**
 
1086
    * @method setData
 
1087
    * @for Node
 
1088
    * @description Stores arbitrary data on a Node instance.
 
1089
    * This is not stored with the DOM node.
 
1090
    * @param {string} name The name of the field to set. If no val
 
1091
    * is given, name is treated as the data and overrides any existing data.
 
1092
    * @param {any} val The value to be assigned to the field.
 
1093
    * @chainable
 
1094
    */
 
1095
    setData: function(name, val) {
 
1096
        this._initData();
 
1097
        if (arguments.length > 1) {
 
1098
            this._data[name] = val;
 
1099
        } else {
 
1100
            this._data = name;
 
1101
        }
 
1102
 
 
1103
       return this;
 
1104
    },
 
1105
 
 
1106
    /**
 
1107
    * @method clearData
 
1108
    * @for Node
 
1109
    * @description Clears internally stored data.
 
1110
    * @param {string} name The name of the field to clear. If no name
 
1111
    * is given, all data is cleared.
 
1112
    * @chainable
 
1113
    */
 
1114
    clearData: function(name) {
 
1115
        if ('_data' in this) {
 
1116
            if (typeof name != 'undefined') {
 
1117
                delete this._data[name];
 
1118
            } else {
 
1119
                delete this._data;
 
1120
            }
 
1121
        }
 
1122
 
 
1123
        return this;
 
1124
    }
 
1125
});
 
1126
 
 
1127
Y.mix(Y.NodeList.prototype, {
 
1128
    /**
 
1129
    * @method getData
 
1130
    * @for NodeList
 
1131
    * @description Retrieves arbitrary data stored on each Node instance
 
1132
    * bound to the NodeList.
 
1133
    * @see Node
 
1134
    * @param {string} name Optional name of the data field to retrieve.
 
1135
    * If no name is given, all data is returned.
 
1136
    * @return {Array} An array containing all of the data for each Node instance. 
 
1137
    * or an object hash of all fields.
 
1138
    */
 
1139
    getData: function(name) {
 
1140
        var args = (arguments.length) ? [name] : [];
 
1141
        return this._invoke('getData', args, true);
 
1142
    },
 
1143
 
 
1144
    /**
 
1145
    * @method setData
 
1146
    * @for NodeList
 
1147
    * @description Stores arbitrary data on each Node instance bound to the
 
1148
    *  NodeList. This is not stored with the DOM node.
 
1149
    * @param {string} name The name of the field to set. If no name
 
1150
    * is given, name is treated as the data and overrides any existing data.
 
1151
    * @param {any} val The value to be assigned to the field.
 
1152
    * @chainable
 
1153
    */
 
1154
    setData: function(name, val) {
 
1155
        var args = (arguments.length > 1) ? [name, val] : [name];
 
1156
        return this._invoke('setData', args);
 
1157
    },
 
1158
 
 
1159
    /**
 
1160
    * @method clearData
 
1161
    * @for NodeList
 
1162
    * @description Clears data on all Node instances bound to the NodeList.
 
1163
    * @param {string} name The name of the field to clear. If no name
 
1164
    * is given, all data is cleared.
 
1165
    * @chainable
 
1166
    */
 
1167
    clearData: function(name) {
 
1168
        var args = (arguments.length) ? [name] : [];
 
1169
        return this._invoke('clearData', [name]);
 
1170
    }
 
1171
});
 
1172
 
 
1173
 
 
1174
}, '3.10.3', {"requires": ["event-base", "node-core", "dom-base"]});