76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glassvar Lang = Y.Lang,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _queries = Y.TabviewBase._queries,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _classNames = Y.TabviewBase._classNames,
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass getClassName = Y.ClassNameManager.getClassName;
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass/**
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * Provides Tab instances for use with TabView
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @param config {Object} Object literal specifying tabview configuration properties.
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass *
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @class Tab
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @constructor
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @extends Widget
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass * @uses WidgetChild
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass */
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav GlassY.Tab = Y.Base.create('tab', Y.Widget, [Y.WidgetChild], {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass BOUNDING_TEMPLATE: '<li class="' + _classNames.tab + '"></li>',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass CONTENT_TEMPLATE: '<a class="' + _classNames.tabLabel + '"></a>',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass PANEL_TEMPLATE: '<div class="' + _classNames.tabPanel + '"></div>',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _uiSetSelectedPanel: function(selected) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.get('panelNode').toggleClass(_classNames.selectedPanel, selected);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterTabSelectedChange: function(event) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._uiSetSelectedPanel(event.newVal);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _afterParentChange: function(e) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!e.newVal) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._remove();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass } else {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._add();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass _initAria: function() {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass var anchor = this.get('contentBox'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass id = anchor.get('id'),
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass panel = this.get('panelNode');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass if (!id) {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass id = Y.guid();
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass anchor.set('id', id);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass }
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Apply the ARIA roles, states and properties to each tab
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass anchor.set('role', 'tab');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass anchor.get('parentNode').set('role', 'presentation');
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass // Apply the ARIA roles, states and properties to each panel
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass panel.setAttrs({
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass role: 'tabpanel',
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass 'aria-labelledby': id
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass });
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass syncUI: function() {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.set('label', this.get('label'));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.set('content', this.get('content'));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this._uiSetSelectedPanel(this.get('selected'));
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass bindUI: function() {
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.after('selectedChange', this._afterTabSelectedChange);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass this.after('parentChange', this._afterParentChange);
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass },
76ca635d61eb3f9fb7c9d788a44fa8b1690aa138Dav Glass
renderUI: function() {
this._renderPanel();
this._initAria();
},
_renderPanel: function() {
this.get('parent').get('panelNode')
.appendChild(this.get('panelNode'));
},
_add: function() {
var parent = this.get('parent').get('contentBox'),
list = parent.get('listNode'),
panel = parent.get('panelNode');
if (list) {
list.appendChild(this.get('boundingBox'));
}
if (panel) {
panel.appendChild(this.get('panelNode'));
}
},
_remove: function() {
this.get('boundingBox').remove();
this.get('panelNode').remove();
},
_onActivate: function(e) {
if (e.target === this) {
// Prevent the browser from navigating to the URL specified by the
// anchor's href attribute.
e.domEvent.preventDefault();
e.target.set('selected', 1);
}
},
initializer: function() {
this.publish(this.get('triggerEvent'), {
defaultFn: this._onActivate
});
},
_defLabelSetter: function(label) {
this.get('contentBox').setContent(label);
return label;
},
_defContentSetter: function(content) {
this.get('panelNode').setContent(content);
return content;
},
_defContentGetter: function(content) {
return this.get('panelNode').getContent();
},
// find panel by ID mapping from label href
_defPanelNodeValueFn: function() {
var href = this.get('contentBox').get('href') || '',
parent = this.get('parent'),
hashIndex = href.indexOf('#'),
panel;
href = href.substr(hashIndex);
if (href.charAt(0) === '#') { // in-page nav, find by ID
panel = Y.one(href);
if (panel) {
panel.addClass(_classNames.tabPanel);
}
}
// use the one found by id, or else try matching indices
if (!panel && parent) {
panel = parent.get('panelNode')
.get('children').item(this.get('index'));
}
if (!panel) { // create if none found
panel = Y.Node.create(this.PANEL_TEMPLATE);
}
return panel;
}
}, {
ATTRS: {
/**
* @attribute triggerEvent
* @default "click"
* @type String
*/
triggerEvent: {
value: 'click'
},
/**
* @attribute label
* @type HTML
*/
label: {
setter: '_defLabelSetter',
validator: Lang.isString
},
/**
* @attribute content
* @type HTML
*/
content: {
setter: '_defContentSetter',
getter: '_defContentGetter'
},
/**
* @attribute panelNode
* @type Y.Node
*/
panelNode: {
setter: function(node) {
node = Y.one(node);
if (node) {
node.addClass(_classNames.tabPanel);
}
return node;
},
valueFn: '_defPanelNodeValueFn'
},
tabIndex: {
value: null,
validator: '_validTabIndex'
}
},
HTML_PARSER: {
selected: function(contentBox) {
var ret = (this.get('boundingBox').hasClass(_classNames.selectedTab)) ?
1 : 0;
return ret;
}
}
});