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