Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: Create a base time display class, and use it #4633

Merged
merged 1 commit into from
Oct 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 16 additions & 60 deletions src/js/control-bar/time-controls/current-time-display.js
Original file line number Diff line number Diff line change
@@ -1,72 +1,24 @@
/**
* @file current-time-display.js
*/
import document from 'global/document';
import TimeDisplay from './time-display';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';

/**
* Displays the current time
*
* @extends Component
*/
class CurrentTimeDisplay extends Component {
class CurrentTimeDisplay extends TimeDisplay {

/**
* Creates an instance of this class.
* Builds the default DOM `className`.
*
* @param {Player} player
* The `Player` that this class should be attached to.
*
* @param {Object} [options]
* The key/value store of player options.
* @return {string}
* The DOM `className` for this object.
*/
constructor(player, options) {
super(player, options);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, 'timeupdate', this.throttledUpdateContent);
}

/**
* Create the `Component`'s DOM element
*
* @return {Element}
* The element that was created.
*/
createEl() {
const el = super.createEl('div', {
className: 'vjs-current-time vjs-time-control vjs-control'
});

this.contentEl_ = Dom.createEl('div', {
className: 'vjs-current-time-display'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize('Current Time')
}));

this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}

/**
* Updates the "current time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(` ${this.formattedTime_ || '0:00'}`);
this.contentEl_.appendChild(this.textNode_);
buildCSSClass() {
return 'vjs-current-time';
}

/**
Expand All @@ -80,15 +32,19 @@ class CurrentTimeDisplay extends Component {
updateContent(event) {
// Allows for smooth scrubbing, when player can't keep up.
const time = (this.player_.scrubbing()) ? this.player_.getCache().currentTime : this.player_.currentTime();
const formattedTime = formatTime(time, this.player_.duration());

if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.requestAnimationFrame(this.updateTextNode_);
}
this.updateFormattedTime_(time);
}

}

/**
* The text that should display over the `CurrentTimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
CurrentTimeDisplay.prototype.controlText_ = 'Current Time';

Component.registerComponent('CurrentTimeDisplay', CurrentTimeDisplay);
export default CurrentTimeDisplay;
65 changes: 18 additions & 47 deletions src/js/control-bar/time-controls/duration-display.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
/**
* @file duration-display.js
*/
import document from 'global/document';
import TimeDisplay from './time-display';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';

/**
* Displays the duration
*
* @extends Component
*/
class DurationDisplay extends Component {
class DurationDisplay extends TimeDisplay {

/**
* Creates an instance of this class.
Expand All @@ -26,57 +23,24 @@ class DurationDisplay extends Component {
constructor(player, options) {
super(player, options);

this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);

this.on(player, [
'durationchange',

// Also listen for timeupdate and loadedmetadata because removing those
// Also listen for timeupdate (in the parent) and loadedmetadata because removing those
// listeners could have broken dependent applications/libraries. These
// can likely be removed for 7.0.
'loadedmetadata',
'timeupdate'
'loadedmetadata'
], this.throttledUpdateContent);
}

/**
* Create the `Component`'s DOM element
* Builds the default DOM `className`.
*
* @return {Element}
* The element that was created.
* @return {string}
* The DOM `className` for this object.
*/
createEl() {
const el = super.createEl('div', {
className: 'vjs-duration vjs-time-control vjs-control'
});

this.contentEl_ = Dom.createEl('div', {
className: 'vjs-duration-display'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize('Duration Time')
}));

this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}

/**
* Updates the "current time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(` ${this.formattedTime_ || '0:00'}`);
this.contentEl_.appendChild(this.textNode_);
buildCSSClass() {
return 'vjs-duration';
}

/**
Expand All @@ -95,11 +59,18 @@ class DurationDisplay extends Component {

if (duration && this.duration_ !== duration) {
this.duration_ = duration;
this.formattedTime_ = formatTime(duration);
this.requestAnimationFrame(this.updateTextNode_);
this.updateFormattedTime_(duration);
}
}
}

/**
* The text that should display over the `DurationDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
DurationDisplay.prototype.controlText_ = 'Duration Time';

Component.registerComponent('DurationDisplay', DurationDisplay);
export default DurationDisplay;
70 changes: 20 additions & 50 deletions src/js/control-bar/time-controls/remaining-time-display.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
/**
* @file remaining-time-display.js
*/
import document from 'global/document';
import TimeDisplay from './time-display';
import Component from '../../component.js';
import * as Dom from '../../utils/dom.js';
import {bind, throttle} from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js';

/**
* Displays the time left in the video
*
* @extends Component
*/
class RemainingTimeDisplay extends Component {
class RemainingTimeDisplay extends TimeDisplay {

/**
* Creates an instance of this class.
Expand All @@ -25,48 +21,17 @@ class RemainingTimeDisplay extends Component {
*/
constructor(player, options) {
super(player, options);
this.throttledUpdateContent = throttle(bind(this, this.updateContent), 25);
this.on(player, ['timeupdate', 'durationchange'], this.throttledUpdateContent);
this.on(player, 'durationchange', this.throttledUpdateContent);
}

/**
* Create the `Component`'s DOM element
* Builds the default DOM `className`.
*
* @return {Element}
* The element that was created.
* @return {string}
* The DOM `className` for this object.
*/
createEl() {
const el = super.createEl('div', {
className: 'vjs-remaining-time vjs-time-control vjs-control'
});

this.contentEl_ = Dom.createEl('div', {
className: 'vjs-remaining-time-display'
}, {
// tell screen readers not to automatically read the time as it changes
'aria-live': 'off'
}, Dom.createEl('span', {
className: 'vjs-control-text',
textContent: this.localize('Remaining Time')
}));

this.updateTextNode_();
el.appendChild(this.contentEl_);
return el;
}

/**
* Updates the "remaining time" text node with new content using the
* contents of the `formattedTime_` property.
*
* @private
*/
updateTextNode_() {
if (this.textNode_) {
this.contentEl_.removeChild(this.textNode_);
}
this.textNode_ = document.createTextNode(` -${this.formattedTime_ || '0:00'}`);
this.contentEl_.appendChild(this.textNode_);
buildCSSClass() {
return 'vjs-remaining-time';
}

/**
Expand All @@ -79,16 +44,21 @@ class RemainingTimeDisplay extends Component {
* @listens Player#durationchange
*/
updateContent(event) {
if (this.player_.duration()) {
const formattedTime = formatTime(this.player_.remainingTime());

if (formattedTime !== this.formattedTime_) {
this.formattedTime_ = formattedTime;
this.requestAnimationFrame(this.updateTextNode_);
}
if (!this.player_.duration()) {
return;
}

this.updateFormattedTime_(this.player_.remainingTime());
}
}

/**
* The text that should display over the `RemainingTimeDisplay`s controls. Added to for localization.
*
* @type {string}
* @private
*/
RemainingTimeDisplay.prototype.controlText_ = 'Remaining Time';

Component.registerComponent('RemainingTimeDisplay', RemainingTimeDisplay);
export default RemainingTimeDisplay;
Loading