blob: 9abdc87b5aa228ba914f7db643e9577ecef18ec5 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
* Controller and View for switching between tabs.
*
* The View part of TabSwitcherView displays the contents of the currently
* selected tab (only one tab can be active at a time).
*
* The controller part of TabSwitcherView hooks up a dropdown menu (i.e. HTML
* SELECT) to control switching between tabs.
*/
var TabSwitcherView = (function() {
'use strict';
// We inherit from View.
var superClass = View;
/**
* @constructor
*
* @param {DOMSelectNode} dropdownMenu The menu for switching between tabs.
* The TabSwitcherView will attach an onchange event to
* the dropdown menu, and control the selected index.
* @param {?Function} opt_onTabSwitched Optional callback to run when the
* active tab changes. Called as
* opt_onTabSwitched(oldTabId, newTabId).
*/
function TabSwitcherView(dropdownMenu, opt_onTabSwitched) {
assertFirstConstructorCall(TabSwitcherView);
this.tabIdToView_ = {};
this.activeTabId_ = null;
this.dropdownMenu_ = dropdownMenu;
this.dropdownMenu_.onchange = this.onMenuSelectionChanged_.bind(this);
this.onTabSwitched_ = opt_onTabSwitched;
superClass.call(this);
}
TabSwitcherView.prototype = {
// Inherit the superclass's methods.
__proto__: superClass.prototype,
// ---------------------------------------------
// Override methods in View
// ---------------------------------------------
setGeometry: function(left, top, width, height) {
superClass.prototype.setGeometry.call(this, left, top, width, height);
// Position each of the tabs content areas.
for (var tabId in this.tabIdToView_) {
var view = this.tabIdToView_[tabId];
view.setGeometry(left, top, width, height);
}
},
show: function(isVisible) {
superClass.prototype.show.call(this, isVisible);
var activeView = this.getActiveTabView();
if (activeView)
activeView.show(isVisible);
},
// ---------------------------------------------
/**
* Adds a new tab (initially hidden).
*
* @param {string} tabId The ID to refer to the tab by.
* @param {!View} view The tab's actual contents.
* @param {string} name The name for the menu item that selects the tab.
*/
addTab: function(tabId, view, name) {
if (!tabId) {
throw Error('Must specify a non-false tabId');
}
this.tabIdToView_[tabId] = view;
// Tab content views start off hidden.
view.show(false);
// Add it to the dropdown menu.
var menuItem = addNode(this.dropdownMenu_, 'option');
menuItem.value = tabId;
menuItem.textContent = name;
},
showMenuItem: function(tabId, isVisible) {
var wasActive = this.activeTabId_ == tabId;
// Hide the menuitem from the list. Note it needs to be 'disabled' to
// prevent it being selectable from keyboard.
var menuitem = this.getMenuItemNode_(tabId);
setNodeDisplay(menuitem, isVisible);
menuitem.disabled = !isVisible;
if (wasActive && !isVisible) {
// If the active tab is being hidden in the dropdown menu, then
// switch to the first tab which is still visible.
for (var i = 0; i < this.dropdownMenu_.options.length; ++i) {
var option = this.dropdownMenu_.options[i];
if (option.style.display != 'none') {
this.switchToTab(option.value);
break;
}
}
}
},
getAllTabViews: function() {
return this.tabIdToView_;
},
getTabView: function(tabId) {
return this.tabIdToView_[tabId];
},
getActiveTabView: function() {
return this.tabIdToView_[this.activeTabId_];
},
getActiveTabId: function() {
return this.activeTabId_;
},
/**
* Changes the currently active tab to |tabId|. This has several effects:
* (1) Replace the tab contents view with that of the new tab.
* (2) Update the dropdown menu's current selection.
* (3) Invoke the optional onTabSwitched callback.
*/
switchToTab: function(tabId) {
var newView = this.getTabView(tabId);
if (!newView) {
throw Error('Invalid tabId');
}
var oldTabId = this.activeTabId_;
this.activeTabId_ = tabId;
this.dropdownMenu_.value = tabId;
// Hide the previously visible tab contents.
if (oldTabId)
this.getTabView(oldTabId).show(false);
newView.show(this.isVisible());
if (this.onTabSwitched_)
this.onTabSwitched_(oldTabId, tabId);
},
getMenuItemNode_: function(tabId) {
for (var i = 0; i < this.dropdownMenu_.options.length; ++i) {
var option = this.dropdownMenu_.options[i];
if (option.value == tabId) {
return option;
}
}
return null;
},
onMenuSelectionChanged_: function(event) {
var tabId = this.dropdownMenu_.value;
this.switchToTab(tabId);
},
};
return TabSwitcherView;
})();