1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117

content / browser / webrtc / resources / tab_view.js [blame]

// Copyright 2013 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Creates a simple object containing the tab head and body elements.
class TabDom {
  constructor(h, b) {
    this.head = h;
    this.body = b;
  }
}

/**
 * A TabView provides the ability to create tabs and switch between tabs. It's
 * responsible for creating the DOM and managing the visibility of each tab.
 * The first added tab is active by default and the others hidden.
 */
export class TabView {
  /**
   * @param {Element} root The root DOM element containing the tabs.
   */
  constructor(root) {
    this.root_ = root;
    this.ACTIVE_TAB_HEAD_CLASS_ = 'active-tab-head';
    this.ACTIVE_TAB_BODY_CLASS_ = 'active-tab-body';
    this.TAB_HEAD_CLASS_ = 'tab-head';
    this.TAB_BODY_CLASS_ = 'tab-body';

    /**
     * A mapping for an id to the tab elements.
     * @type {!Object<!TabDom>}
     * @private
     */
    this.tabElements_ = {};

    this.headBar_ = null;
    this.activeTabId_ = null;
    this.initializeHeadBar_();
  }

  /**
   * Adds a tab with the specified id and title.
   * @param {string} id
   * @param {string} title
   * @return {!Element} The tab body element.
   */
  addTab(id, title) {
    if (this.tabElements_[id]) {
      throw 'Tab already exists: ' + id;
    }

    const head = document.createElement('span');
    head.className = this.TAB_HEAD_CLASS_;
    head.textContent = title;
    head.title = title;
    this.headBar_.appendChild(head);
    head.addEventListener('click', this.switchTab_.bind(this, id));

    const body = document.createElement('div');
    body.className = this.TAB_BODY_CLASS_;
    body.id = id;
    this.root_.appendChild(body);

    this.tabElements_[id] = new TabDom(head, body);

    if (!this.activeTabId_) {
      this.switchTab_(id);
    }
    return this.tabElements_[id].body;
  }

  /** Removes the tab. @param {string} id */
  removeTab(id) {
    if (!this.tabElements_[id]) {
      return;
    }
    this.tabElements_[id].head.parentNode.removeChild(
        this.tabElements_[id].head);
    this.tabElements_[id].body.parentNode.removeChild(
        this.tabElements_[id].body);

    delete this.tabElements_[id];
    if (this.activeTabId_ === id) {
      this.switchTab_(Object.keys(this.tabElements_)[0]);
    }
  }

  /**
   * Switches the specified tab into view.
   *
   * @param {string} activeId The id the of the tab that should be switched to
   *     active state.
   * @private
   */
  switchTab_(activeId) {
    if (this.activeTabId_ && this.tabElements_[this.activeTabId_]) {
      this.tabElements_[this.activeTabId_].body.classList.remove(
          this.ACTIVE_TAB_BODY_CLASS_);
      this.tabElements_[this.activeTabId_].head.classList.remove(
          this.ACTIVE_TAB_HEAD_CLASS_);
    }
    this.activeTabId_ = activeId;
    if (this.tabElements_[activeId]) {
      this.tabElements_[activeId].body.classList.add(
          this.ACTIVE_TAB_BODY_CLASS_);
      this.tabElements_[activeId].head.classList.add(
          this.ACTIVE_TAB_HEAD_CLASS_);
    }
  }

  /** Initializes the bar containing the tab heads. */
  initializeHeadBar_() {
    this.headBar_ = document.createElement('div');
    this.root_.appendChild(this.headBar_);
    this.headBar_.style.textAlign = 'center';
  }
}