~ubuntu-branches/ubuntu/natty/otrs2/natty-updates

« back to all changes in this revision

Viewing changes to var/httpd/htdocs/yui/2.7.0/build/tabview/tabview.js

  • Committer: Package Import Robot
  • Author(s): Patrick Matthäi
  • Date: 2010-08-09 19:43:44 UTC
  • mfrom: (1.1.12)
  • Revision ID: package-import@ubuntu.com-20100809194344-absef1ut5mfj3qhv
Tags: 2.4.7+dfsg1-1
* Strip out yui from the source in the dfsg version.
  Closes: #591196
* Depend on libjs-yui and link to this package, instead of using the embedded
  yui version. This changes make the flash ticket statistics unuseable!
  Closes: #592146

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
Copyright (c) 2009, Yahoo! Inc. All rights reserved.
3
 
Code licensed under the BSD License:
4
 
http://developer.yahoo.net/yui/license.txt
5
 
version: 2.7.0
6
 
*/
7
 
(function() {
8
 
 
9
 
    /**
10
 
     * The tabview module provides a widget for managing content bound to tabs.
11
 
     * @module tabview
12
 
     * @requires yahoo, dom, event, element
13
 
     *
14
 
     */
15
 
 
16
 
    var Y = YAHOO.util,
17
 
        Dom = Y.Dom,
18
 
        Event = Y.Event,
19
 
        document = window.document,
20
 
    
21
 
        // STRING CONSTANTS
22
 
        ACTIVE = 'active',
23
 
        ACTIVE_INDEX = 'activeIndex',
24
 
        ACTIVE_TAB = 'activeTab',
25
 
        CONTENT_EL = 'contentEl',
26
 
        ELEMENT = 'element',
27
 
    
28
 
    /**
29
 
     * A widget to control tabbed views.
30
 
     * @namespace YAHOO.widget
31
 
     * @class TabView
32
 
     * @extends YAHOO.util.Element
33
 
     * @constructor
34
 
     * @param {HTMLElement | String | Object} el(optional) The html 
35
 
     * element that represents the TabView, or the attribute object to use. 
36
 
     * An element will be created if none provided.
37
 
     * @param {Object} attr (optional) A key map of the tabView's 
38
 
     * initial attributes.  Ignored if first arg is attributes object.
39
 
     */
40
 
    TabView = function(el, attr) {
41
 
        attr = attr || {};
42
 
        if (arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName) {
43
 
            attr = el; // treat first arg as attr object
44
 
            el = attr.element || null;
45
 
        }
46
 
        
47
 
        if (!el && !attr.element) { // create if we dont have one
48
 
            el = this._createTabViewElement(attr);
49
 
        }
50
 
        TabView.superclass.constructor.call(this, el, attr); 
51
 
    };
52
 
 
53
 
    YAHOO.extend(TabView, Y.Element, {
54
 
        /**
55
 
         * The className to add when building from scratch. 
56
 
         * @property CLASSNAME
57
 
         * @default "navset"
58
 
         */
59
 
        CLASSNAME: 'yui-navset',
60
 
        
61
 
        /**
62
 
         * The className of the HTMLElement containing the TabView's tab elements
63
 
         * to look for when building from existing markup, or to add when building
64
 
         * from scratch. 
65
 
         * All childNodes of the tab container are treated as Tabs when building
66
 
         * from existing markup.
67
 
         * @property TAB_PARENT_CLASSNAME
68
 
         * @default "nav"
69
 
         */
70
 
        TAB_PARENT_CLASSNAME: 'yui-nav',
71
 
        
72
 
        /**
73
 
         * The className of the HTMLElement containing the TabView's label elements
74
 
         * to look for when building from existing markup, or to add when building
75
 
         * from scratch. 
76
 
         * All childNodes of the content container are treated as content elements when
77
 
         * building from existing markup.
78
 
         * @property CONTENT_PARENT_CLASSNAME
79
 
         * @default "nav-content"
80
 
         */
81
 
        CONTENT_PARENT_CLASSNAME: 'yui-content',
82
 
        
83
 
        _tabParent: null,
84
 
        _contentParent: null,
85
 
        
86
 
        /**
87
 
         * Adds a Tab to the TabView instance.  
88
 
         * If no index is specified, the tab is added to the end of the tab list.
89
 
         * @method addTab
90
 
         * @param {YAHOO.widget.Tab} tab A Tab instance to add.
91
 
         * @param {Integer} index The position to add the tab. 
92
 
         * @return void
93
 
         */
94
 
        addTab: function(tab, index) {
95
 
            var tabs = this.get('tabs'),
96
 
                before = this.getTab(index),
97
 
                tabParent = this._tabParent,
98
 
                contentParent = this._contentParent,
99
 
                tabElement = tab.get(ELEMENT),
100
 
                contentEl = tab.get(CONTENT_EL);
101
 
 
102
 
            if (!tabs) { // not ready yet
103
 
                this._queue[this._queue.length] = ['addTab', arguments];
104
 
                return false;
105
 
            }
106
 
            
107
 
            index = (index === undefined) ? tabs.length : index;
108
 
            
109
 
            if ( before ) {
110
 
                tabParent.insertBefore(tabElement, before.get(ELEMENT));
111
 
            } else {
112
 
                tabParent.appendChild(tabElement);
113
 
            }
114
 
 
115
 
            if ( contentEl && !Dom.isAncestor(contentParent, contentEl) ) {
116
 
                contentParent.appendChild(contentEl);
117
 
            }
118
 
            
119
 
            if ( !tab.get(ACTIVE) ) {
120
 
                tab.set('contentVisible', false, true); /* hide if not active */
121
 
            } else {
122
 
                this.set(ACTIVE_TAB, tab, true);
123
 
                
124
 
            }
125
 
 
126
 
            this._initTabEvents(tab);
127
 
            tabs.splice(index, 0, tab);
128
 
        },
129
 
 
130
 
        _initTabEvents: function(tab) {
131
 
            tab.addListener( tab.get('activationEvent'), tab._onActivate, this, tab);
132
 
            
133
 
            tab.addListener('activationEventChange', function(e) {
134
 
                if (e.prevValue != e.newValue) {
135
 
                    tab.removeListener(e.prevValue, tab._onActivate);
136
 
                    tab.addListener(e.newValue, tab._onActivate, this, tab);
137
 
                }
138
 
            });
139
 
        },
140
 
 
141
 
        /**
142
 
         * Routes childNode events.
143
 
         * @method DOMEventHandler
144
 
         * @param {event} e The Dom event that is being handled.
145
 
         * @return void
146
 
         */
147
 
        DOMEventHandler: function(e) {
148
 
            var target = Event.getTarget(e),
149
 
                tabParent = this._tabParent,
150
 
                tabs = this.get('tabs'),
151
 
                tab,
152
 
                tabEl,
153
 
                contentEl;
154
 
 
155
 
            
156
 
            if (Dom.isAncestor(tabParent, target) ) {
157
 
                for (var i = 0, len = tabs.length; i < len; i++) {
158
 
                    tabEl = tabs[i].get(ELEMENT);
159
 
                    contentEl = tabs[i].get(CONTENT_EL);
160
 
 
161
 
                    if ( target == tabEl || Dom.isAncestor(tabEl, target) ) {
162
 
                        tab = tabs[i];
163
 
                        break; // note break
164
 
                    }
165
 
                } 
166
 
                
167
 
                if (tab) {
168
 
                    tab.fireEvent(e.type, e);
169
 
                }
170
 
            }
171
 
        },
172
 
        
173
 
        /**
174
 
         * Returns the Tab instance at the specified index.
175
 
         * @method getTab
176
 
         * @param {Integer} index The position of the Tab.
177
 
         * @return YAHOO.widget.Tab
178
 
         */
179
 
        getTab: function(index) {
180
 
            return this.get('tabs')[index];
181
 
        },
182
 
        
183
 
        /**
184
 
         * Returns the index of given tab.
185
 
         * @method getTabIndex
186
 
         * @param {YAHOO.widget.Tab} tab The tab whose index will be returned.
187
 
         * @return int
188
 
         */
189
 
        getTabIndex: function(tab) {
190
 
            var index = null,
191
 
                tabs = this.get('tabs');
192
 
            for (var i = 0, len = tabs.length; i < len; ++i) {
193
 
                if (tab == tabs[i]) {
194
 
                    index = i;
195
 
                    break;
196
 
                }
197
 
            }
198
 
            
199
 
            return index;
200
 
        },
201
 
        
202
 
        /**
203
 
         * Removes the specified Tab from the TabView.
204
 
         * @method removeTab
205
 
         * @param {YAHOO.widget.Tab} item The Tab instance to be removed.
206
 
         * @return void
207
 
         */
208
 
        removeTab: function(tab) {
209
 
            var tabCount = this.get('tabs').length,
210
 
                index = this.getTabIndex(tab);
211
 
 
212
 
            if ( tab === this.get(ACTIVE_TAB) ) { 
213
 
                if (tabCount > 1) { // select another tab
214
 
                    if (index + 1 === tabCount) { // if last, activate previous
215
 
                        this.set(ACTIVE_INDEX, index - 1);
216
 
                    } else { // activate next tab
217
 
                        this.set(ACTIVE_INDEX, index + 1);
218
 
                    }
219
 
                } else { // no more tabs
220
 
                    this.set(ACTIVE_TAB, null);
221
 
                }
222
 
            }
223
 
            
224
 
            this._tabParent.removeChild( tab.get(ELEMENT) );
225
 
            this._contentParent.removeChild( tab.get(CONTENT_EL) );
226
 
            this._configs.tabs.value.splice(index, 1);
227
 
 
228
 
            tab.fireEvent('remove', { type: 'remove', tabview: this });
229
 
        },
230
 
        
231
 
        /**
232
 
         * Provides a readable name for the TabView instance.
233
 
         * @method toString
234
 
         * @return String
235
 
         */
236
 
        toString: function() {
237
 
            var name = this.get('id') || this.get('tagName');
238
 
            return "TabView " + name; 
239
 
        },
240
 
        
241
 
        /**
242
 
         * The transiton to use when switching between tabs.
243
 
         * @method contentTransition
244
 
         */
245
 
        contentTransition: function(newTab, oldTab) {
246
 
            if (newTab) {
247
 
                newTab.set('contentVisible', true);
248
 
            }
249
 
            if (oldTab) {
250
 
                oldTab.set('contentVisible', false);
251
 
            }
252
 
        },
253
 
        
254
 
        /**
255
 
         * setAttributeConfigs TabView specific properties.
256
 
         * @method initAttributes
257
 
         * @param {Object} attr Hash of initial attributes
258
 
         */
259
 
        initAttributes: function(attr) {
260
 
            TabView.superclass.initAttributes.call(this, attr);
261
 
            
262
 
            if (!attr.orientation) {
263
 
                attr.orientation = 'top';
264
 
            }
265
 
            
266
 
            var el = this.get(ELEMENT);
267
 
 
268
 
            if (!Dom.hasClass(el, this.CLASSNAME)) {
269
 
                Dom.addClass(el, this.CLASSNAME);        
270
 
            }
271
 
            
272
 
            /**
273
 
             * The Tabs belonging to the TabView instance.
274
 
             * @attribute tabs
275
 
             * @type Array
276
 
             */
277
 
            this.setAttributeConfig('tabs', {
278
 
                value: [],
279
 
                readOnly: true
280
 
            });
281
 
 
282
 
            /**
283
 
             * The container of the tabView's label elements.
284
 
             * @property _tabParent
285
 
             * @private
286
 
             * @type HTMLElement
287
 
             */
288
 
            this._tabParent = 
289
 
                    this.getElementsByClassName(this.TAB_PARENT_CLASSNAME,
290
 
                            'ul' )[0] || this._createTabParent();
291
 
                
292
 
            /**
293
 
             * The container of the tabView's content elements.
294
 
             * @property _contentParent
295
 
             * @type HTMLElement
296
 
             * @private
297
 
             */
298
 
            this._contentParent = 
299
 
                    this.getElementsByClassName(this.CONTENT_PARENT_CLASSNAME,
300
 
                            'div')[0] ||  this._createContentParent();
301
 
            
302
 
            /**
303
 
             * How the Tabs should be oriented relative to the TabView.
304
 
             * @attribute orientation
305
 
             * @type String
306
 
             * @default "top"
307
 
             */
308
 
            this.setAttributeConfig('orientation', {
309
 
                value: attr.orientation,
310
 
                method: function(value) {
311
 
                    var current = this.get('orientation');
312
 
                    this.addClass('yui-navset-' + value);
313
 
                    
314
 
                    if (current != value) {
315
 
                        this.removeClass('yui-navset-' + current);
316
 
                    }
317
 
                    
318
 
                    if (value === 'bottom') {
319
 
                        this.appendChild(this._tabParent);
320
 
                    }
321
 
                }
322
 
            });
323
 
            
324
 
            /**
325
 
             * The index of the tab currently active.
326
 
             * @attribute activeIndex
327
 
             * @type Int
328
 
             */
329
 
            this.setAttributeConfig(ACTIVE_INDEX, {
330
 
                value: attr.activeIndex,
331
 
                method: function(value) {
332
 
                },
333
 
                validator: function(value) {
334
 
                    var ret = true;
335
 
                    if (value && this.getTab(value).get('disabled')) { // cannot activate if disabled
336
 
                        ret = false;
337
 
                    }
338
 
                    return ret;
339
 
                }
340
 
            });
341
 
            
342
 
            /**
343
 
             * The tab currently active.
344
 
             * @attribute activeTab
345
 
             * @type YAHOO.widget.Tab
346
 
             */
347
 
            this.setAttributeConfig(ACTIVE_TAB, {
348
 
                value: attr.activeTab,
349
 
                method: function(tab) {
350
 
                    var activeTab = this.get(ACTIVE_TAB);
351
 
                    
352
 
                    if (tab) {
353
 
                        tab.set(ACTIVE, true);
354
 
                    }
355
 
                    
356
 
                    if (activeTab && activeTab !== tab) {
357
 
                        activeTab.set(ACTIVE, false);
358
 
                    }
359
 
                    
360
 
                    if (activeTab && tab !== activeTab) { // no transition if only 1
361
 
                        this.contentTransition(tab, activeTab);
362
 
                    } else if (tab) {
363
 
                        tab.set('contentVisible', true);
364
 
                    }
365
 
                },
366
 
                validator: function(value) {
367
 
                    var ret = true;
368
 
                    if (value && value.get('disabled')) { // cannot activate if disabled
369
 
                        ret = false;
370
 
                    }
371
 
                    return ret;
372
 
                }
373
 
            });
374
 
 
375
 
            this.on('activeTabChange', this._onActiveTabChange);
376
 
            this.on('activeIndexChange', this._onActiveIndexChange);
377
 
 
378
 
            if ( this._tabParent ) {
379
 
                this._initTabs();
380
 
            }
381
 
            
382
 
            // Due to delegation we add all DOM_EVENTS to the TabView container
383
 
            // but IE will leak when unsupported events are added, so remove these
384
 
            this.DOM_EVENTS.submit = false;
385
 
            this.DOM_EVENTS.focus = false;
386
 
            this.DOM_EVENTS.blur = false;
387
 
 
388
 
            for (var type in this.DOM_EVENTS) {
389
 
                if ( YAHOO.lang.hasOwnProperty(this.DOM_EVENTS, type) ) {
390
 
                    this.addListener.call(this, type, this.DOMEventHandler);
391
 
                }
392
 
            }
393
 
        },
394
 
 
395
 
        /**
396
 
         * Removes selected state from the given tab if it is the activeTab
397
 
         * @method deselectTab
398
 
         * @param {Int} index The tab index to deselect 
399
 
         */
400
 
        deselectTab: function(index) {
401
 
            if (this.getTab(index) === this.get('activeTab')) {
402
 
                this.set('activeTab', null);
403
 
            }
404
 
        },
405
 
 
406
 
        /**
407
 
         * Makes the tab at the given index the active tab
408
 
         * @method selectTab
409
 
         * @param {Int} index The tab index to be made active
410
 
         */
411
 
        selectTab: function(index) {
412
 
            this.set('activeTab', this.getTab(index));
413
 
        },
414
 
 
415
 
        _onActiveTabChange: function(e) {
416
 
            var activeIndex = this.get(ACTIVE_INDEX),
417
 
                newIndex = this.getTabIndex(e.newValue);
418
 
 
419
 
            if (activeIndex !== newIndex) {
420
 
                if (!(this.set(ACTIVE_INDEX, newIndex)) ) { // NOTE: setting
421
 
                     // revert if activeIndex update fails (cancelled via beforeChange) 
422
 
                    this.set(ACTIVE_TAB, e.prevValue);
423
 
                }
424
 
            }
425
 
        },
426
 
        
427
 
        _onActiveIndexChange: function(e) {
428
 
            // no set if called from ActiveTabChange event
429
 
            if (e.newValue !== this.getTabIndex(this.get(ACTIVE_TAB))) {
430
 
                if (!(this.set(ACTIVE_TAB, this.getTab(e.newValue))) ) { // NOTE: setting
431
 
                     // revert if activeTab update fails (cancelled via beforeChange) 
432
 
                    this.set(ACTIVE_INDEX, e.prevValue);
433
 
                }
434
 
            }
435
 
        },
436
 
 
437
 
        /**
438
 
         * Creates Tab instances from a collection of HTMLElements.
439
 
         * @method _initTabs
440
 
         * @private
441
 
         * @return void
442
 
         */
443
 
        _initTabs: function() {
444
 
            var tabs = Dom.getChildren(this._tabParent),
445
 
                contentElements = Dom.getChildren(this._contentParent),
446
 
                activeIndex = this.get(ACTIVE_INDEX),
447
 
                tab,
448
 
                attr,
449
 
                active;
450
 
 
451
 
            for (var i = 0, len = tabs.length; i < len; ++i) {
452
 
                attr = {};
453
 
                
454
 
                if (contentElements[i]) {
455
 
                    attr.contentEl = contentElements[i];
456
 
                }
457
 
 
458
 
                tab = new YAHOO.widget.Tab(tabs[i], attr);
459
 
                this.addTab(tab);
460
 
                
461
 
                if (tab.hasClass(tab.ACTIVE_CLASSNAME) ) {
462
 
                    active = tab;
463
 
                }
464
 
            }
465
 
            if (activeIndex) {
466
 
                this.set(ACTIVE_TAB, this.getTab(activeIndex));
467
 
            } else {
468
 
                this._configs.activeTab.value = active; // dont invoke method
469
 
                this._configs.activeIndex.value = this.getTabIndex(active);
470
 
            }
471
 
        },
472
 
 
473
 
        _createTabViewElement: function(attr) {
474
 
            var el = document.createElement('div');
475
 
 
476
 
            if ( this.CLASSNAME ) {
477
 
                el.className = this.CLASSNAME;
478
 
            }
479
 
            
480
 
            return el;
481
 
        },
482
 
 
483
 
        _createTabParent: function(attr) {
484
 
            var el = document.createElement('ul');
485
 
 
486
 
            if ( this.TAB_PARENT_CLASSNAME ) {
487
 
                el.className = this.TAB_PARENT_CLASSNAME;
488
 
            }
489
 
            
490
 
            this.get(ELEMENT).appendChild(el);
491
 
            
492
 
            return el;
493
 
        },
494
 
        
495
 
        _createContentParent: function(attr) {
496
 
            var el = document.createElement('div');
497
 
 
498
 
            if ( this.CONTENT_PARENT_CLASSNAME ) {
499
 
                el.className = this.CONTENT_PARENT_CLASSNAME;
500
 
            }
501
 
            
502
 
            this.get(ELEMENT).appendChild(el);
503
 
            
504
 
            return el;
505
 
        }
506
 
    });
507
 
    
508
 
    
509
 
    YAHOO.widget.TabView = TabView;
510
 
})();
511
 
 
512
 
(function() {
513
 
    var Y = YAHOO.util, 
514
 
        Dom = Y.Dom,
515
 
        Lang = YAHOO.lang,
516
 
    
517
 
 
518
 
    // STRING CONSTANTS
519
 
        ACTIVE_TAB = 'activeTab',
520
 
        LABEL = 'label',
521
 
        LABEL_EL = 'labelEl',
522
 
        CONTENT = 'content',
523
 
        CONTENT_EL = 'contentEl',
524
 
        ELEMENT = 'element',
525
 
        CACHE_DATA = 'cacheData',
526
 
        DATA_SRC = 'dataSrc',
527
 
        DATA_LOADED = 'dataLoaded',
528
 
        DATA_TIMEOUT = 'dataTimeout',
529
 
        LOAD_METHOD = 'loadMethod',
530
 
        POST_DATA = 'postData',
531
 
        DISABLED = 'disabled',
532
 
    
533
 
    /**
534
 
     * A representation of a Tab's label and content.
535
 
     * @namespace YAHOO.widget
536
 
     * @class Tab
537
 
     * @extends YAHOO.util.Element
538
 
     * @constructor
539
 
     * @param element {HTMLElement | String} (optional) The html element that 
540
 
     * represents the TabView. An element will be created if none provided.
541
 
     * @param {Object} properties A key map of initial properties
542
 
     */
543
 
    Tab = function(el, attr) {
544
 
        attr = attr || {};
545
 
        if (arguments.length == 1 && !Lang.isString(el) && !el.nodeName) {
546
 
            attr = el;
547
 
            el = attr.element;
548
 
        }
549
 
 
550
 
        if (!el && !attr.element) {
551
 
            el = this._createTabElement(attr);
552
 
        }
553
 
 
554
 
        this.loadHandler =  {
555
 
            success: function(o) {
556
 
                this.set(CONTENT, o.responseText);
557
 
            },
558
 
            failure: function(o) {
559
 
            }
560
 
        };
561
 
        
562
 
        Tab.superclass.constructor.call(this, el, attr);
563
 
        
564
 
        this.DOM_EVENTS = {}; // delegating to tabView
565
 
    };
566
 
 
567
 
    YAHOO.extend(Tab, YAHOO.util.Element, {
568
 
        /**
569
 
         * The default tag name for a Tab's inner element.
570
 
         * @property LABEL_INNER_TAGNAME
571
 
         * @type String
572
 
         * @default "em"
573
 
         */
574
 
        LABEL_TAGNAME: 'em',
575
 
        
576
 
        /**
577
 
         * The class name applied to active tabs.
578
 
         * @property ACTIVE_CLASSNAME
579
 
         * @type String
580
 
         * @default "selected"
581
 
         */
582
 
        ACTIVE_CLASSNAME: 'selected',
583
 
        
584
 
        /**
585
 
         * The class name applied to active tabs.
586
 
         * @property ACTIVE_CLASSNAME
587
 
         * @type String
588
 
         * @default "selected"
589
 
         */
590
 
        HIDDEN_CLASSNAME: 'yui-hidden',
591
 
        
592
 
        /**
593
 
         * The title applied to active tabs.
594
 
         * @property ACTIVE_TITLE
595
 
         * @type String
596
 
         * @default "active"
597
 
         */
598
 
        ACTIVE_TITLE: 'active',
599
 
 
600
 
        /**
601
 
         * The class name applied to disabled tabs.
602
 
         * @property DISABLED_CLASSNAME
603
 
         * @type String
604
 
         * @default "disabled"
605
 
         */
606
 
        DISABLED_CLASSNAME: DISABLED,
607
 
        
608
 
        /**
609
 
         * The class name applied to dynamic tabs while loading.
610
 
         * @property LOADING_CLASSNAME
611
 
         * @type String
612
 
         * @default "disabled"
613
 
         */
614
 
        LOADING_CLASSNAME: 'loading',
615
 
 
616
 
        /**
617
 
         * Provides a reference to the connection request object when data is
618
 
         * loaded dynamically.
619
 
         * @property dataConnection
620
 
         * @type Object
621
 
         */
622
 
        dataConnection: null,
623
 
        
624
 
        /**
625
 
         * Object containing success and failure callbacks for loading data.
626
 
         * @property loadHandler
627
 
         * @type object
628
 
         */
629
 
        loadHandler: null,
630
 
 
631
 
        _loading: false,
632
 
        
633
 
        /**
634
 
         * Provides a readable name for the tab.
635
 
         * @method toString
636
 
         * @return String
637
 
         */
638
 
        toString: function() {
639
 
            var el = this.get(ELEMENT),
640
 
                id = el.id || el.tagName;
641
 
            return "Tab " + id; 
642
 
        },
643
 
        
644
 
        /**
645
 
         * setAttributeConfigs TabView specific properties.
646
 
         * @method initAttributes
647
 
         * @param {Object} attr Hash of initial attributes
648
 
         */
649
 
        initAttributes: function(attr) {
650
 
            attr = attr || {};
651
 
            Tab.superclass.initAttributes.call(this, attr);
652
 
            
653
 
            /**
654
 
             * The event that triggers the tab's activation.
655
 
             * @attribute activationEvent
656
 
             * @type String
657
 
             */
658
 
            this.setAttributeConfig('activationEvent', {
659
 
                value: attr.activationEvent || 'click'
660
 
            });        
661
 
 
662
 
            /**
663
 
             * The element that contains the tab's label.
664
 
             * @attribute labelEl
665
 
             * @type HTMLElement
666
 
             */
667
 
            this.setAttributeConfig(LABEL_EL, {
668
 
                value: attr[LABEL_EL] || this._getLabelEl(),
669
 
                method: function(value) {
670
 
                    value = Dom.get(value);
671
 
                    var current = this.get(LABEL_EL);
672
 
 
673
 
                    if (current) {
674
 
                        if (current == value) {
675
 
                            return false; // already set
676
 
                        }
677
 
                        
678
 
                        current.parentNode.replaceChild(value, current);
679
 
                        this.set(LABEL, value.innerHTML);
680
 
                    }
681
 
                } 
682
 
            });
683
 
 
684
 
            /**
685
 
             * The tab's label text (or innerHTML).
686
 
             * @attribute label
687
 
             * @type String
688
 
             */
689
 
            this.setAttributeConfig(LABEL, {
690
 
                value: attr.label || this._getLabel(),
691
 
                method: function(value) {
692
 
                    var labelEl = this.get(LABEL_EL);
693
 
                    if (!labelEl) { // create if needed
694
 
                        this.set(LABEL_EL, this._createLabelEl());
695
 
                    }
696
 
                    
697
 
                    labelEl.innerHTML = value;
698
 
                }
699
 
            });
700
 
            
701
 
            /**
702
 
             * The HTMLElement that contains the tab's content.
703
 
             * @attribute contentEl
704
 
             * @type HTMLElement
705
 
             */
706
 
            this.setAttributeConfig(CONTENT_EL, {
707
 
                value: attr[CONTENT_EL] || document.createElement('div'),
708
 
                method: function(value) {
709
 
                    value = Dom.get(value);
710
 
                    var current = this.get(CONTENT_EL);
711
 
 
712
 
                    if (current) {
713
 
                        if (current === value) {
714
 
                            return false; // already set
715
 
                        }
716
 
                        if (!this.get('selected')) {
717
 
                            Dom.addClass(value, 'yui-hidden');
718
 
                        }
719
 
                        current.parentNode.replaceChild(value, current);
720
 
                        this.set(CONTENT, value.innerHTML);
721
 
                    }
722
 
                }
723
 
            });
724
 
            
725
 
            /**
726
 
             * The tab's content.
727
 
             * @attribute content
728
 
             * @type String
729
 
             */
730
 
            this.setAttributeConfig(CONTENT, {
731
 
                value: attr[CONTENT],
732
 
                method: function(value) {
733
 
                    this.get(CONTENT_EL).innerHTML = value;
734
 
                }
735
 
            });
736
 
 
737
 
            /**
738
 
             * The tab's data source, used for loading content dynamically.
739
 
             * @attribute dataSrc
740
 
             * @type String
741
 
             */
742
 
            this.setAttributeConfig(DATA_SRC, {
743
 
                value: attr.dataSrc
744
 
            });
745
 
            
746
 
            /**
747
 
             * Whether or not content should be reloaded for every view.
748
 
             * @attribute cacheData
749
 
             * @type Boolean
750
 
             * @default false
751
 
             */
752
 
            this.setAttributeConfig(CACHE_DATA, {
753
 
                value: attr.cacheData || false,
754
 
                validator: Lang.isBoolean
755
 
            });
756
 
            
757
 
            /**
758
 
             * The method to use for the data request.
759
 
             * @attribute loadMethod
760
 
             * @type String
761
 
             * @default "GET"
762
 
             */
763
 
            this.setAttributeConfig(LOAD_METHOD, {
764
 
                value: attr.loadMethod || 'GET',
765
 
                validator: Lang.isString
766
 
            });
767
 
 
768
 
            /**
769
 
             * Whether or not any data has been loaded from the server.
770
 
             * @attribute dataLoaded
771
 
             * @type Boolean
772
 
             */        
773
 
            this.setAttributeConfig(DATA_LOADED, {
774
 
                value: false,
775
 
                validator: Lang.isBoolean,
776
 
                writeOnce: true
777
 
            });
778
 
            
779
 
            /**
780
 
             * Number if milliseconds before aborting and calling failure handler.
781
 
             * @attribute dataTimeout
782
 
             * @type Number
783
 
             * @default null
784
 
             */
785
 
            this.setAttributeConfig(DATA_TIMEOUT, {
786
 
                value: attr.dataTimeout || null,
787
 
                validator: Lang.isNumber
788
 
            });
789
 
            
790
 
            /**
791
 
             * Arguments to pass when POST method is used 
792
 
             * @attribute postData
793
 
             * @default null
794
 
             */
795
 
            this.setAttributeConfig(POST_DATA, {
796
 
                value: attr.postData || null
797
 
            });
798
 
 
799
 
            /**
800
 
             * Whether or not the tab is currently active.
801
 
             * If a dataSrc is set for the tab, the content will be loaded from
802
 
             * the given source.
803
 
             * @attribute active
804
 
             * @type Boolean
805
 
             */
806
 
            this.setAttributeConfig('active', {
807
 
                value: attr.active || this.hasClass(this.ACTIVE_CLASSNAME),
808
 
                method: function(value) {
809
 
                    if (value === true) {
810
 
                        this.addClass(this.ACTIVE_CLASSNAME);
811
 
                        this.set('title', this.ACTIVE_TITLE);
812
 
                    } else {
813
 
                        this.removeClass(this.ACTIVE_CLASSNAME);
814
 
                        this.set('title', '');
815
 
                    }
816
 
                },
817
 
                validator: function(value) {
818
 
                    return Lang.isBoolean(value) && !this.get(DISABLED) ;
819
 
                }
820
 
            });
821
 
            
822
 
            /**
823
 
             * Whether or not the tab is disabled.
824
 
             * @attribute disabled
825
 
             * @type Boolean
826
 
             */
827
 
            this.setAttributeConfig(DISABLED, {
828
 
                value: attr.disabled || this.hasClass(this.DISABLED_CLASSNAME),
829
 
                method: function(value) {
830
 
                    if (value === true) {
831
 
                        Dom.addClass(this.get(ELEMENT), this.DISABLED_CLASSNAME);
832
 
                    } else {
833
 
                        Dom.removeClass(this.get(ELEMENT), this.DISABLED_CLASSNAME);
834
 
                    }
835
 
                },
836
 
                validator: Lang.isBoolean
837
 
            });
838
 
            
839
 
            /**
840
 
             * The href of the tab's anchor element.
841
 
             * @attribute href
842
 
             * @type String
843
 
             * @default '#'
844
 
             */
845
 
            this.setAttributeConfig('href', {
846
 
                value: attr.href ||
847
 
                        this.getElementsByTagName('a')[0].getAttribute('href', 2) || '#',
848
 
                method: function(value) {
849
 
                    this.getElementsByTagName('a')[0].href = value;
850
 
                },
851
 
                validator: Lang.isString
852
 
            });
853
 
            
854
 
            /**
855
 
             * The Whether or not the tab's content is visible.
856
 
             * @attribute contentVisible
857
 
             * @type Boolean
858
 
             * @default false
859
 
             */
860
 
            this.setAttributeConfig('contentVisible', {
861
 
                value: attr.contentVisible,
862
 
                method: function(value) {
863
 
                    if (value) {
864
 
                        Dom.removeClass(this.get(CONTENT_EL), this.HIDDEN_CLASSNAME);
865
 
                        
866
 
                        if ( this.get(DATA_SRC) ) {
867
 
                         // load dynamic content unless already loading or loaded and caching
868
 
                            if ( !this._loading && !(this.get(DATA_LOADED) && this.get(CACHE_DATA)) ) {
869
 
                                this._dataConnect();
870
 
                            }
871
 
                        }
872
 
                    } else {
873
 
                        Dom.addClass(this.get(CONTENT_EL), this.HIDDEN_CLASSNAME);
874
 
                    }
875
 
                },
876
 
                validator: Lang.isBoolean
877
 
            });
878
 
        },
879
 
        
880
 
        _dataConnect: function() {
881
 
            if (!Y.Connect) {
882
 
                return false;
883
 
            }
884
 
 
885
 
            Dom.addClass(this.get(CONTENT_EL).parentNode, this.LOADING_CLASSNAME);
886
 
            this._loading = true; 
887
 
            this.dataConnection = Y.Connect.asyncRequest(
888
 
                this.get(LOAD_METHOD),
889
 
                this.get(DATA_SRC), 
890
 
                {
891
 
                    success: function(o) {
892
 
                        this.loadHandler.success.call(this, o);
893
 
                        this.set(DATA_LOADED, true);
894
 
                        this.dataConnection = null;
895
 
                        Dom.removeClass(this.get(CONTENT_EL).parentNode,
896
 
                                this.LOADING_CLASSNAME);
897
 
                        this._loading = false;
898
 
                    },
899
 
                    failure: function(o) {
900
 
                        this.loadHandler.failure.call(this, o);
901
 
                        this.dataConnection = null;
902
 
                        Dom.removeClass(this.get(CONTENT_EL).parentNode,
903
 
                                this.LOADING_CLASSNAME);
904
 
                        this._loading = false;
905
 
                    },
906
 
                    scope: this,
907
 
                    timeout: this.get(DATA_TIMEOUT)
908
 
                },
909
 
 
910
 
                this.get(POST_DATA)
911
 
            );
912
 
        },
913
 
        _createTabElement: function(attr) {
914
 
            var el = document.createElement('li'),
915
 
                a = document.createElement('a'),
916
 
                label = attr.label || null,
917
 
                labelEl = attr.labelEl || null;
918
 
            
919
 
            a.href = attr.href || '#'; // TODO: Use Dom.setAttribute?
920
 
            el.appendChild(a);
921
 
            
922
 
            if (labelEl) { // user supplied labelEl
923
 
                if (!label) { // user supplied label
924
 
                    label = this._getLabel();
925
 
                }
926
 
            } else {
927
 
                labelEl = this._createLabelEl();
928
 
            }
929
 
            
930
 
            a.appendChild(labelEl);
931
 
            
932
 
            return el;
933
 
        },
934
 
 
935
 
        _getLabelEl: function() {
936
 
            return this.getElementsByTagName(this.LABEL_TAGNAME)[0];
937
 
        },
938
 
 
939
 
        _createLabelEl: function() {
940
 
            var el = document.createElement(this.LABEL_TAGNAME);
941
 
            return el;
942
 
        },
943
 
    
944
 
        
945
 
        _getLabel: function() {
946
 
            var el = this.get(LABEL_EL);
947
 
                
948
 
                if (!el) {
949
 
                    return undefined;
950
 
                }
951
 
            
952
 
            return el.innerHTML;
953
 
        },
954
 
 
955
 
        _onActivate: function(e, tabview) {
956
 
            var tab = this,
957
 
                silent = false;
958
 
            
959
 
 
960
 
            Y.Event.preventDefault(e);
961
 
            if (tab === tabview.get(ACTIVE_TAB)) {
962
 
                silent = true; // dont fire activeTabChange if already active
963
 
            }
964
 
            tabview.set(ACTIVE_TAB, tab, silent);
965
 
        }
966
 
    });
967
 
    
968
 
    
969
 
    /**
970
 
     * Fires when a tab is removed from the tabview
971
 
     * @event remove
972
 
     * @type CustomEvent
973
 
     * @param {Event} An event object with fields for "type" ("remove")
974
 
     * and "tabview" (the tabview instance it was removed from) 
975
 
     */
976
 
    
977
 
    YAHOO.widget.Tab = Tab;
978
 
})();
979
 
 
980
 
YAHOO.register("tabview", YAHOO.widget.TabView, {version: "2.7.0", build: "1799"});