diff options
Diffstat (limited to 'javascript/videojs/src/js/control-bar/time-controls/time-display.js')
| -rw-r--r-- | javascript/videojs/src/js/control-bar/time-controls/time-display.js | 164 |
1 files changed, 164 insertions, 0 deletions
diff --git a/javascript/videojs/src/js/control-bar/time-controls/time-display.js b/javascript/videojs/src/js/control-bar/time-controls/time-display.js new file mode 100644 index 0000000..2fa558d --- /dev/null +++ b/javascript/videojs/src/js/control-bar/time-controls/time-display.js @@ -0,0 +1,164 @@ +/** + * @file time-display.js + */ +import document from 'global/document'; +import Component from '../../component.js'; +import * as Dom from '../../utils/dom.js'; +import {formatTime} from '../../utils/time.js'; +import log from '../../utils/log.js'; + +/** @import Player from '../../player' */ + +/** + * Displays time information about the video + * + * @extends Component + */ +class TimeDisplay extends Component { + + /** + * Creates an instance of this class. + * + * @param {Player} player + * The `Player` that this class should be attached to. + * + * @param {Object} [options] + * The key/value store of player options. + */ + constructor(player, options) { + super(player, options); + + this.on(player, ['timeupdate', 'ended', 'seeking'], (e) => this.update(e)); + this.updateTextNode_(); + } + + /** + * Create the `Component`'s DOM element + * + * @return {Element} + * The element that was created. + */ + createEl() { + const className = this.buildCSSClass(); + const el = super.createEl('div', { + className: `${className} vjs-time-control vjs-control` + }); + const span = Dom.createEl('span', { + className: 'vjs-control-text', + textContent: `${this.localize(this.labelText_)}\u00a0` + }, { + role: 'presentation' + }); + + el.appendChild(span); + + this.contentEl_ = Dom.createEl('span', { + className: `${className}-display` + }, { + // span elements have no implicit role, but some screen readers (notably VoiceOver) + // treat them as a break between items in the DOM when using arrow keys + // (or left-to-right swipes on iOS) to read contents of a page. Using + // role='presentation' causes VoiceOver to NOT treat this span as a break. + role: 'presentation' + }); + + el.appendChild(this.contentEl_); + return el; + } + + dispose() { + this.contentEl_ = null; + this.textNode_ = null; + + super.dispose(); + } + + /** + * Updates the displayed time according to the `updateContent` function which is defined in the child class. + * + * @param {Event} [event] + * The `timeupdate`, `ended` or `seeking` (if enableSmoothSeeking is true) event that caused this function to be called. + */ + update(event) { + if (!this.player_.options_.enableSmoothSeeking && event.type === 'seeking') { + return; + } + + this.updateContent(event); + } + + /** + * Updates the time display text node with a new time + * + * @param {number} [time=0] the time to update to + * + * @private + */ + updateTextNode_(time = 0) { + time = formatTime(time); + + if (this.formattedTime_ === time) { + return; + } + + this.formattedTime_ = time; + + this.requestNamedAnimationFrame('TimeDisplay#updateTextNode_', () => { + if (!this.contentEl_) { + return; + } + + let oldNode = this.textNode_; + + if (oldNode && this.contentEl_.firstChild !== oldNode) { + oldNode = null; + + log.warn('TimeDisplay#updateTextnode_: Prevented replacement of text node element since it was no longer a child of this node. Appending a new node instead.'); + } + + this.textNode_ = document.createTextNode(this.formattedTime_); + + if (!this.textNode_) { + return; + } + + if (oldNode) { + this.contentEl_.replaceChild(this.textNode_, oldNode); + } else { + this.contentEl_.appendChild(this.textNode_); + } + }); + } + + /** + * To be filled out in the child class, should update the displayed time + * in accordance with the fact that the current time has changed. + * + * @param {Event} [event] + * The `timeupdate` event that caused this to run. + * + * @listens Player#timeupdate + */ + updateContent(event) {} +} + +/** + * The text that is added to the `TimeDisplay` for screen reader users. + * + * @type {string} + * @private + */ +TimeDisplay.prototype.labelText_ = 'Time'; + +/** + * The text that should display over the `TimeDisplay`s controls. Added to for localization. + * + * @type {string} + * @protected + * + * @deprecated in v7; controlText_ is not used in non-active display Components + */ +TimeDisplay.prototype.controlText_ = 'Time'; + +Component.registerComponent('TimeDisplay', TimeDisplay); +export default TimeDisplay; |
