| // 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; |
| })(); |