src/cm/media/js/lib/yui/yui_3.10.3/build/tabview/tabview-debug.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     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('tabview', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11  * The TabView module
       
    12  *
       
    13  * @module tabview
       
    14  */
       
    15 
       
    16 var DOT = '.',
       
    17 
       
    18     /**
       
    19      * Provides a tabbed widget interface
       
    20      * @param config {Object} Object literal specifying tabview configuration properties.
       
    21      *
       
    22      * @class TabView
       
    23      * @constructor
       
    24      * @extends Widget
       
    25      * @uses WidgetParent
       
    26      */
       
    27     TabView = Y.Base.create('tabView', Y.Widget, [Y.WidgetParent], {
       
    28 
       
    29     _afterChildAdded: function() {
       
    30         this.get('contentBox').focusManager.refresh();
       
    31     },
       
    32 
       
    33     _defListNodeValueFn: function() {
       
    34         var node = Y.Node.create(this.LIST_TEMPLATE);
       
    35 
       
    36         node.addClass(Y.TabviewBase._classNames.tabviewList);
       
    37 
       
    38         return node;
       
    39     },
       
    40 
       
    41     _defPanelNodeValueFn: function() {
       
    42         var node = Y.Node.create(this.PANEL_TEMPLATE);
       
    43 
       
    44         node.addClass(Y.TabviewBase._classNames.tabviewPanel);
       
    45 
       
    46         return node;
       
    47     },
       
    48 
       
    49     _afterChildRemoved: function(e) { // update the selected tab when removed
       
    50         var i = e.index,
       
    51             selection = this.get('selection');
       
    52 
       
    53         if (!selection) { // select previous item if selection removed
       
    54             selection = this.item(i - 1) || this.item(0);
       
    55             if (selection) {
       
    56                 selection.set('selected', 1);
       
    57             }
       
    58         }
       
    59 
       
    60         this.get('contentBox').focusManager.refresh();
       
    61     },
       
    62 
       
    63     _initAria: function() {
       
    64         var contentBox = this.get('contentBox'),
       
    65             tablist = contentBox.one(Y.TabviewBase._queries.tabviewList);
       
    66 
       
    67         if (tablist) {
       
    68             tablist.setAttrs({
       
    69                 //'aria-labelledby':
       
    70                 role: 'tablist'
       
    71             });
       
    72         }
       
    73     },
       
    74 
       
    75     bindUI: function() {
       
    76         //  Use the Node Focus Manager to add keyboard support:
       
    77         //  Pressing the left and right arrow keys will move focus
       
    78         //  among each of the tabs.
       
    79 
       
    80         this.get('contentBox').plug(Y.Plugin.NodeFocusManager, {
       
    81                         descendants: DOT + Y.TabviewBase._classNames.tabLabel,
       
    82                         keys: { next: 'down:39', // Right arrow
       
    83                                 previous: 'down:37' },  // Left arrow
       
    84                         circular: true
       
    85                     });
       
    86 
       
    87         this.after('render', this._setDefSelection);
       
    88         this.after('addChild', this._afterChildAdded);
       
    89         this.after('removeChild', this._afterChildRemoved);
       
    90     },
       
    91 
       
    92     renderUI: function() {
       
    93         var contentBox = this.get('contentBox');
       
    94         this._renderListBox(contentBox);
       
    95         this._renderPanelBox(contentBox);
       
    96         this._childrenContainer = this.get('listNode');
       
    97         this._renderTabs(contentBox);
       
    98     },
       
    99 
       
   100     _setDefSelection: function() {
       
   101         //  If no tab is selected, select the first tab.
       
   102         var selection = this.get('selection') || this.item(0);
       
   103 
       
   104         this.some(function(tab) {
       
   105             if (tab.get('selected')) {
       
   106                 selection = tab;
       
   107                 return true;
       
   108             }
       
   109         });
       
   110         if (selection) {
       
   111             // TODO: why both needed? (via widgetParent/Child)?
       
   112             this.set('selection', selection);
       
   113             selection.set('selected', 1);
       
   114         }
       
   115     },
       
   116 
       
   117     _renderListBox: function(contentBox) {
       
   118         var node = this.get('listNode');
       
   119         if (!node.inDoc()) {
       
   120             contentBox.append(node);
       
   121         }
       
   122     },
       
   123 
       
   124     _renderPanelBox: function(contentBox) {
       
   125         var node = this.get('panelNode');
       
   126         if (!node.inDoc()) {
       
   127             contentBox.append(node);
       
   128         }
       
   129     },
       
   130 
       
   131     _renderTabs: function(contentBox) {
       
   132         var _classNames = Y.TabviewBase._classNames,
       
   133             _queries = Y.TabviewBase._queries,
       
   134             tabs = contentBox.all(_queries.tab),
       
   135             panelNode = this.get('panelNode'),
       
   136             panels = (panelNode) ? this.get('panelNode').get('children') : null,
       
   137             tabview = this;
       
   138 
       
   139         if (tabs) { // add classNames and fill in Tab fields from markup when possible
       
   140             tabs.addClass(_classNames.tab);
       
   141             contentBox.all(_queries.tabLabel).addClass(_classNames.tabLabel);
       
   142             contentBox.all(_queries.tabPanel).addClass(_classNames.tabPanel);
       
   143 
       
   144             tabs.each(function(node, i) {
       
   145                 var panelNode = (panels) ? panels.item(i) : null;
       
   146                 tabview.add({
       
   147                     boundingBox: node,
       
   148                     contentBox: node.one(DOT + _classNames.tabLabel),
       
   149                     panelNode: panelNode
       
   150                 });
       
   151             });
       
   152         }
       
   153     }
       
   154 }, {
       
   155     ATTRS: {
       
   156         defaultChildType: {
       
   157             value: 'Tab'
       
   158         },
       
   159 
       
   160         listNode: {
       
   161             setter: function(node) {
       
   162                 node = Y.one(node);
       
   163                 if (node) {
       
   164                     node.addClass(Y.TabviewBase._classNames.tabviewList);
       
   165                 }
       
   166                 return node;
       
   167             },
       
   168 
       
   169             valueFn: '_defListNodeValueFn'
       
   170         },
       
   171 
       
   172         panelNode: {
       
   173             setter: function(node) {
       
   174                 node = Y.one(node);
       
   175                 if (node) {
       
   176                     node.addClass(Y.TabviewBase._classNames.tabviewPanel);
       
   177                 }
       
   178                 return node;
       
   179             },
       
   180 
       
   181             valueFn: '_defPanelNodeValueFn'
       
   182         },
       
   183 
       
   184         tabIndex: {
       
   185             value: null
       
   186             //validator: '_validTabIndex'
       
   187         }
       
   188     },
       
   189 
       
   190     HTML_PARSER: {
       
   191         listNode: function(srcNode) {
       
   192             return srcNode.one(Y.TabviewBase._queries.tabviewList);
       
   193         },
       
   194         panelNode: function(srcNode) {
       
   195             return srcNode.one(Y.TabviewBase._queries.tabviewPanel);
       
   196         }
       
   197     },
       
   198 
       
   199     // Static for legacy support.
       
   200     LIST_TEMPLATE: '<ul></ul>',
       
   201     PANEL_TEMPLATE: '<div></div>'
       
   202 });
       
   203 
       
   204 // Map to static values by default.
       
   205 TabView.prototype.LIST_TEMPLATE = TabView.LIST_TEMPLATE;
       
   206 TabView.prototype.PANEL_TEMPLATE = TabView.PANEL_TEMPLATE;
       
   207 
       
   208 Y.TabView = TabView;
       
   209 /**
       
   210  * Provides Tab instances for use with TabView
       
   211  * @param config {Object} Object literal specifying tabview configuration properties.
       
   212  *
       
   213  * @class Tab
       
   214  * @constructor
       
   215  * @extends Widget
       
   216  * @uses WidgetChild
       
   217  */
       
   218 Y.Tab = Y.Base.create('tab', Y.Widget, [Y.WidgetChild], {
       
   219     BOUNDING_TEMPLATE: '<li></li>',
       
   220     CONTENT_TEMPLATE: '<a></a>',
       
   221     PANEL_TEMPLATE: '<div></div>',
       
   222 
       
   223     _uiSetSelectedPanel: function(selected) {
       
   224         this.get('panelNode').toggleClass(Y.TabviewBase._classNames.selectedPanel, selected);
       
   225     },
       
   226 
       
   227     _afterTabSelectedChange: function(event) {
       
   228        this._uiSetSelectedPanel(event.newVal);
       
   229     },
       
   230 
       
   231     _afterParentChange: function(e) {
       
   232         if (!e.newVal) {
       
   233             this._remove();
       
   234         } else {
       
   235             this._add();
       
   236         }
       
   237     },
       
   238 
       
   239     _initAria: function() {
       
   240         var anchor = this.get('contentBox'),
       
   241             id = anchor.get('id'),
       
   242             panel = this.get('panelNode');
       
   243 
       
   244         if (!id) {
       
   245             id = Y.guid();
       
   246             anchor.set('id', id);
       
   247         }
       
   248         //  Apply the ARIA roles, states and properties to each tab
       
   249         anchor.set('role', 'tab');
       
   250         anchor.get('parentNode').set('role', 'presentation');
       
   251 
       
   252         //  Apply the ARIA roles, states and properties to each panel
       
   253         panel.setAttrs({
       
   254             role: 'tabpanel',
       
   255             'aria-labelledby': id
       
   256         });
       
   257     },
       
   258 
       
   259     syncUI: function() {
       
   260         var _classNames = Y.TabviewBase._classNames;
       
   261 
       
   262         this.get('boundingBox').addClass(_classNames.tab);
       
   263         this.get('contentBox').addClass(_classNames.tabLabel);
       
   264         this.set('label', this.get('label'));
       
   265         this.set('content', this.get('content'));
       
   266         this._uiSetSelectedPanel(this.get('selected'));
       
   267     },
       
   268 
       
   269     bindUI: function() {
       
   270        this.after('selectedChange', this._afterTabSelectedChange);
       
   271        this.after('parentChange', this._afterParentChange);
       
   272     },
       
   273 
       
   274     renderUI: function() {
       
   275         this._renderPanel();
       
   276         this._initAria();
       
   277     },
       
   278 
       
   279     _renderPanel: function() {
       
   280         this.get('parent').get('panelNode')
       
   281             .appendChild(this.get('panelNode'));
       
   282     },
       
   283 
       
   284     _add: function() {
       
   285         var parent = this.get('parent').get('contentBox'),
       
   286             list = parent.get('listNode'),
       
   287             panel = parent.get('panelNode');
       
   288 
       
   289         if (list) {
       
   290             list.appendChild(this.get('boundingBox'));
       
   291         }
       
   292 
       
   293         if (panel) {
       
   294             panel.appendChild(this.get('panelNode'));
       
   295         }
       
   296     },
       
   297 
       
   298     _remove: function() {
       
   299         this.get('boundingBox').remove();
       
   300         this.get('panelNode').remove();
       
   301     },
       
   302 
       
   303     _onActivate: function(e) {
       
   304          if (e.target === this) {
       
   305              //  Prevent the browser from navigating to the URL specified by the
       
   306              //  anchor's href attribute.
       
   307              e.domEvent.preventDefault();
       
   308              e.target.set('selected', 1);
       
   309          }
       
   310     },
       
   311 
       
   312     initializer: function() {
       
   313        this.publish(this.get('triggerEvent'), {
       
   314            defaultFn: this._onActivate
       
   315        });
       
   316     },
       
   317 
       
   318     _defLabelGetter: function() {
       
   319         return this.get('contentBox').getHTML();
       
   320     },
       
   321 
       
   322     _defLabelSetter: function(label) {
       
   323         var labelNode = this.get('contentBox');
       
   324         if (labelNode.getHTML() !== label) { // Avoid rewriting existing label.
       
   325             labelNode.setHTML(label);
       
   326         }
       
   327         return label;
       
   328     },
       
   329 
       
   330     _defContentSetter: function(content) {
       
   331         var panel = this.get('panelNode');
       
   332         if (panel.getHTML() !== content) { // Avoid rewriting existing content.
       
   333             panel.setHTML(content);
       
   334         }
       
   335         return content;
       
   336     },
       
   337 
       
   338     _defContentGetter: function() {
       
   339         return this.get('panelNode').getHTML();
       
   340     },
       
   341 
       
   342     // find panel by ID mapping from label href
       
   343     _defPanelNodeValueFn: function() {
       
   344         var _classNames = Y.TabviewBase._classNames,
       
   345             href = this.get('contentBox').get('href') || '',
       
   346             parent = this.get('parent'),
       
   347             hashIndex = href.indexOf('#'),
       
   348             panel;
       
   349 
       
   350         href = href.substr(hashIndex);
       
   351 
       
   352         if (href.charAt(0) === '#') { // in-page nav, find by ID
       
   353             panel = Y.one(href);
       
   354             if (panel) {
       
   355                 panel.addClass(_classNames.tabPanel);
       
   356             }
       
   357         }
       
   358 
       
   359         // use the one found by id, or else try matching indices
       
   360         if (!panel && parent) {
       
   361             panel = parent.get('panelNode')
       
   362                     .get('children').item(this.get('index'));
       
   363         }
       
   364 
       
   365         if (!panel) { // create if none found
       
   366             panel = Y.Node.create(this.PANEL_TEMPLATE);
       
   367             panel.addClass(_classNames.tabPanel);
       
   368         }
       
   369         return panel;
       
   370     }
       
   371 }, {
       
   372     ATTRS: {
       
   373         /**
       
   374          * @attribute triggerEvent
       
   375          * @default "click"
       
   376          * @type String
       
   377          */
       
   378         triggerEvent: {
       
   379             value: 'click'
       
   380         },
       
   381 
       
   382         /**
       
   383          * @attribute label
       
   384          * @type HTML
       
   385          */
       
   386         label: {
       
   387             setter: '_defLabelSetter',
       
   388             getter: '_defLabelGetter'
       
   389         },
       
   390 
       
   391         /**
       
   392          * @attribute content
       
   393          * @type HTML
       
   394          */
       
   395         content: {
       
   396             setter: '_defContentSetter',
       
   397             getter: '_defContentGetter'
       
   398         },
       
   399 
       
   400         /**
       
   401          * @attribute panelNode
       
   402          * @type Y.Node
       
   403          */
       
   404         panelNode: {
       
   405             setter: function(node) {
       
   406                 node = Y.one(node);
       
   407                 if (node) {
       
   408                     node.addClass(Y.TabviewBase._classNames.tabPanel);
       
   409                 }
       
   410                 return node;
       
   411             },
       
   412             valueFn: '_defPanelNodeValueFn'
       
   413         },
       
   414 
       
   415         tabIndex: {
       
   416             value: null,
       
   417             validator: '_validTabIndex'
       
   418         }
       
   419 
       
   420     },
       
   421 
       
   422     HTML_PARSER: {
       
   423         selected: function() {
       
   424             var ret = (this.get('boundingBox').hasClass(Y.TabviewBase._classNames.selectedTab)) ?
       
   425                         1 : 0;
       
   426             return ret;
       
   427         }
       
   428     }
       
   429 
       
   430 });
       
   431 
       
   432 
       
   433 }, '3.10.3', {
       
   434     "requires": [
       
   435         "widget",
       
   436         "widget-parent",
       
   437         "widget-child",
       
   438         "tabview-base",
       
   439         "node-pluginhost",
       
   440         "node-focusmanager"
       
   441     ],
       
   442     "skinnable": true
       
   443 });