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;