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