summaryrefslogtreecommitdiff
path: root/javascript/videojs/src/js/title-bar.js
blob: 1b59cb840fa8aba3c1901599be054095c190401b (plain)
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
import Component from './component';
import * as Dom from './utils/dom';
import * as Guid from './utils/guid';
import * as Obj from './utils/obj';

/**
 * Displays an element over the player which contains an optional title and
 * description for the current content.
 *
 * Much of the code for this component originated in the now obsolete
 * videojs-dock plugin: https://github.com/brightcove/videojs-dock/
 *
 * @extends Component
 */
class TitleBar extends Component {

  constructor(player, options) {
    super(player, options);
    this.on('statechanged', (e) => this.updateDom_());
    this.updateDom_();
  }

  /**
   * Create the `TitleBar`'s DOM element
   *
   * @return {Element}
   *         The element that was created.
   */
  createEl() {
    this.els = {
      title: Dom.createEl('div', {
        className: 'vjs-title-bar-title',
        id: `vjs-title-bar-title-${Guid.newGUID()}`
      }),
      description: Dom.createEl('div', {
        className: 'vjs-title-bar-description',
        id: `vjs-title-bar-description-${Guid.newGUID()}`
      })
    };

    return Dom.createEl('div', {
      className: 'vjs-title-bar'
    }, {}, Obj.values(this.els));
  }

  /**
   * Updates the DOM based on the component's state object.
   */
  updateDom_() {
    const tech = this.player_.tech_;
    const techEl = tech && tech.el_;
    const techAriaAttrs = {
      title: 'aria-labelledby',
      description: 'aria-describedby'
    };

    ['title', 'description'].forEach(k => {
      const value = this.state[k];
      const el = this.els[k];
      const techAriaAttr = techAriaAttrs[k];

      Dom.emptyEl(el);

      if (value) {
        Dom.textContent(el, value);
      }

      // If there is a tech element available, update its ARIA attributes
      // according to whether a title and/or description have been provided.
      if (techEl) {
        techEl.removeAttribute(techAriaAttr);

        if (value) {
          techEl.setAttribute(techAriaAttr, el.id);
        }
      }
    });

    if (this.state.title || this.state.description) {
      this.show();
    } else {
      this.hide();
    }
  }

  /**
   * Update the contents of the title bar component with new title and
   * description text.
   *
   * If both title and description are missing, the title bar will be hidden.
   *
   * If either title or description are present, the title bar will be visible.
   *
   * NOTE: Any previously set value will be preserved. To unset a previously
   * set value, you must pass an empty string or null.
   *
   * For example:
   *
   * ```
   * update({title: 'foo', description: 'bar'}) // title: 'foo', description: 'bar'
   * update({description: 'bar2'}) // title: 'foo', description: 'bar2'
   * update({title: ''}) // title: '', description: 'bar2'
   * update({title: 'foo', description: null}) // title: 'foo', description: null
   * ```
   *
   * @param  {Object} [options={}]
   *         An options object. When empty, the title bar will be hidden.
   *
   * @param  {string} [options.title]
   *         A title to display in the title bar.
   *
   * @param  {string} [options.description]
   *         A description to display in the title bar.
   */
  update(options) {
    this.setState(options);
  }

  /**
   * Dispose the component.
   */
  dispose() {
    const tech = this.player_.tech_;
    const techEl = tech && tech.el_;

    if (techEl) {
      techEl.removeAttribute('aria-labelledby');
      techEl.removeAttribute('aria-describedby');
    }

    super.dispose();
    this.els = null;
  }
}

Component.registerComponent('TitleBar', TitleBar);

export default TitleBar;