1// Copyright 2013 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5/** 6 * A TabView provides the ability to create tabs and switch between tabs. It's 7 * responsible for creating the DOM and managing the visibility of each tab. 8 * The first added tab is active by default and the others hidden. 9 */ 10var TabView = (function() { 11 'use strict'; 12 13 /** 14 * @constructor 15 * @param {Element} root The root DOM element containing the tabs. 16 */ 17 function TabView(root) { 18 this.root_ = root; 19 this.ACTIVE_TAB_HEAD_CLASS_ = 'active-tab-head'; 20 this.ACTIVE_TAB_BODY_CLASS_ = 'active-tab-body'; 21 this.TAB_HEAD_CLASS_ = 'tab-head'; 22 this.TAB_BODY_CLASS_ = 'tab-body'; 23 24 /** 25 * A mapping for an id to the tab elements. 26 * @type {!Object<string, !TabDom>} 27 * @private 28 */ 29 this.tabElements_ = {}; 30 31 this.headBar_ = null; 32 this.activeTabId_ = null; 33 this.initializeHeadBar_(); 34 } 35 36 // Creates a simple object containing the tab head and body elements. 37 function TabDom(h, b) { 38 this.head = h; 39 this.body = b; 40 } 41 42 TabView.prototype = { 43 /** 44 * Adds a tab with the specified id and title. 45 * @param {string} id 46 * @param {string} title 47 * @return {!Element} The tab body element. 48 */ 49 addTab: function(id, title) { 50 if (this.tabElements_[id]) 51 throw 'Tab already exists: ' + id; 52 53 var head = document.createElement('div'); 54 head.className = this.TAB_HEAD_CLASS_; 55 head.textContent = id; 56 head.title = title; 57 this.headBar_.appendChild(head); 58 head.addEventListener('click', this.switchTab_.bind(this, id)); 59 60 var body = document.createElement('div'); 61 body.className = this.TAB_BODY_CLASS_; 62 body.id = id; 63 this.root_.appendChild(body); 64 65 this.tabElements_[id] = new TabDom(head, body); 66 67 if (!this.activeTabId_) { 68 this.switchTab_(id); 69 } 70 return this.tabElements_[id].body; 71 }, 72 73 /** Removes the tab. @param {string} id */ 74 removeTab: function(id) { 75 if (!this.tabElements_[id]) 76 return; 77 this.tabElements_[id].head.parentNode.removeChild( 78 this.tabElements_[id].head); 79 this.tabElements_[id].body.parentNode.removeChild( 80 this.tabElements_[id].body); 81 82 delete this.tabElements_[id]; 83 if (this.activeTabId_ == id) { 84 this.switchTab_(Object.keys(this.tabElements_)[0]); 85 } 86 }, 87 88 /** 89 * Switches the specified tab into view. 90 * 91 * @param {string} activeId The id the of the tab that should be switched to 92 * active state. 93 * @private 94 */ 95 switchTab_: function(activeId) { 96 if (this.activeTabId_ && this.tabElements_[this.activeTabId_]) { 97 this.tabElements_[this.activeTabId_].body.classList.remove( 98 this.ACTIVE_TAB_BODY_CLASS_); 99 this.tabElements_[this.activeTabId_].head.classList.remove( 100 this.ACTIVE_TAB_HEAD_CLASS_); 101 } 102 this.activeTabId_ = activeId; 103 if (this.tabElements_[activeId]) { 104 this.tabElements_[activeId].body.classList.add( 105 this.ACTIVE_TAB_BODY_CLASS_); 106 this.tabElements_[activeId].head.classList.add( 107 this.ACTIVE_TAB_HEAD_CLASS_); 108 } 109 }, 110 111 /** Initializes the bar containing the tab heads. */ 112 initializeHeadBar_: function() { 113 this.headBar_ = document.createElement('div'); 114 this.root_.appendChild(this.headBar_); 115 this.headBar_.style.textAlign = 'center'; 116 }, 117 }; 118 return TabView; 119})(); 120