[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
1 /* 2 YUI 3.17.2 (build 9c3c78e) 3 Copyright 2014 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(contentBox) { 64 var tablist = contentBox.one(Y.TabviewBase._queries.tabviewList); 65 66 if (tablist) { 67 tablist.setAttrs({ 68 //'aria-labelledby': 69 role: 'tablist' 70 }); 71 } 72 }, 73 74 bindUI: function() { 75 // Use the Node Focus Manager to add keyboard support: 76 // Pressing the left and right arrow keys will move focus 77 // among each of the tabs. 78 79 this.get('contentBox').plug(Y.Plugin.NodeFocusManager, { 80 descendants: DOT + Y.TabviewBase._classNames.tabLabel, 81 keys: { next: 'down:39', // Right arrow 82 previous: 'down:37' }, // Left arrow 83 circular: true 84 }); 85 86 this.after('render', this._setDefSelection); 87 this.after('addChild', this._afterChildAdded); 88 this.after('removeChild', this._afterChildRemoved); 89 }, 90 91 renderUI: function() { 92 var contentBox = this.get('contentBox'); 93 this._renderListBox(contentBox); 94 this._renderPanelBox(contentBox); 95 this._childrenContainer = this.get('listNode'); 96 this._renderTabs(contentBox); 97 this._initAria(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.17.2', { 434 "requires": [ 435 "widget", 436 "widget-parent", 437 "widget-child", 438 "tabview-base", 439 "node-pluginhost", 440 "node-focusmanager" 441 ], 442 "skinnable": true 443 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |