1
0
mirror of https://github.com/videojs/video.js.git synced 2024-12-21 01:39:04 +02:00

more moving of utils

This commit is contained in:
Pat O'Neill 2022-05-13 14:12:19 -04:00
parent f641c0f6d3
commit d2300bcef4
32 changed files with 240 additions and 412 deletions

View File

@ -4,7 +4,6 @@
import ClickableComponent from './clickable-component.js'; import ClickableComponent from './clickable-component.js';
import Component from './component'; import Component from './component';
import log from './utils/log.js'; import log from './utils/log.js';
import {assign} from './utils/obj';
import keycode from 'keycode'; import keycode from 'keycode';
import {createEl} from './utils/dom.js'; import {createEl} from './utils/dom.js';
@ -34,12 +33,12 @@ class Button extends ClickableComponent {
createEl(tag, props = {}, attributes = {}) { createEl(tag, props = {}, attributes = {}) {
tag = 'button'; tag = 'button';
props = assign({ props = Object.assign({
className: this.buildCSSClass() className: this.buildCSSClass()
}, props); }, props);
// Add attributes for button element // Add attributes for button element
attributes = assign({ attributes = Object.assign({
// Necessary since the default button type is "submit" // Necessary since the default button type is "submit"
type: 'button' type: 'button'

View File

@ -4,7 +4,6 @@
import Component from './component'; import Component from './component';
import * as Dom from './utils/dom.js'; import * as Dom from './utils/dom.js';
import log from './utils/log.js'; import log from './utils/log.js';
import {assign} from './utils/obj';
import keycode from 'keycode'; import keycode from 'keycode';
/** /**
@ -68,7 +67,7 @@ class ClickableComponent extends Component {
* The element that gets created. * The element that gets created.
*/ */
createEl(tag = 'div', props = {}, attributes = {}) { createEl(tag = 'div', props = {}, attributes = {}) {
props = assign({ props = Object.assign({
className: this.buildCSSClass(), className: this.buildCSSClass(),
tabIndex: 0 tabIndex: 0
}, props); }, props);
@ -78,7 +77,7 @@ class ClickableComponent extends Component {
} }
// Add ARIA attributes for clickable element which is not a native HTML button // Add ARIA attributes for clickable element which is not a native HTML button
attributes = assign({ attributes = Object.assign({
role: 'button' role: 'button'
}, attributes); }, attributes);

View File

@ -3,7 +3,7 @@
*/ */
import Component from '../../component.js'; import Component from '../../component.js';
import * as Dom from '../../utils/dom.js'; import * as Dom from '../../utils/dom.js';
import clamp from '../../utils/clamp'; import {clamp} from '../../utils/num';
import document from 'global/document'; import document from 'global/document';
// get the percent width of a time compared to the total end // get the percent width of a time compared to the total end

View File

@ -3,7 +3,7 @@
*/ */
import Component from '../../component.js'; import Component from '../../component.js';
import * as Dom from '../../utils/dom.js'; import * as Dom from '../../utils/dom.js';
import clamp from '../../utils/clamp.js'; import {clamp} from '../../utils/num';
import {bind, throttle, UPDATE_REFRESH_INTERVAL} from '../../utils/fn.js'; import {bind, throttle, UPDATE_REFRESH_INTERVAL} from '../../utils/fn.js';
import {silencePromise} from '../../utils/promise'; import {silencePromise} from '../../utils/promise';

View File

@ -6,7 +6,7 @@ import Component from '../../component.js';
import {IS_IOS, IS_ANDROID} from '../../utils/browser.js'; import {IS_IOS, IS_ANDROID} from '../../utils/browser.js';
import * as Dom from '../../utils/dom.js'; import * as Dom from '../../utils/dom.js';
import * as Fn from '../../utils/fn.js'; import * as Fn from '../../utils/fn.js';
import formatTime from '../../utils/format-time.js'; import {formatTime} from '../../utils/time';
import {silencePromise} from '../../utils/promise'; import {silencePromise} from '../../utils/promise';
import keycode from 'keycode'; import keycode from 'keycode';
import document from 'global/document'; import document from 'global/document';

View File

@ -3,7 +3,7 @@
*/ */
import Component from '../../component'; import Component from '../../component';
import * as Dom from '../../utils/dom.js'; import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js'; import { formatTime } from '../../utils/time';
import * as Fn from '../../utils/fn.js'; import * as Fn from '../../utils/fn.js';
/** /**

View File

@ -4,7 +4,7 @@
import document from 'global/document'; import document from 'global/document';
import Component from '../../component.js'; import Component from '../../component.js';
import * as Dom from '../../utils/dom.js'; import * as Dom from '../../utils/dom.js';
import formatTime from '../../utils/format-time.js'; import { formatTime } from '../../utils/time';
import log from '../../utils/log.js'; import log from '../../utils/log.js';
/** /**

View File

@ -4,7 +4,7 @@
import Slider from '../../slider/slider.js'; import Slider from '../../slider/slider.js';
import Component from '../../component.js'; import Component from '../../component.js';
import * as Dom from '../../utils/dom.js'; import * as Dom from '../../utils/dom.js';
import clamp from '../../utils/clamp.js'; import {clamp} from '../../utils/num';
import {IS_IOS, IS_ANDROID} from '../../utils/browser.js'; import {IS_IOS, IS_ANDROID} from '../../utils/browser.js';
// Required children // Required children

View File

@ -1,7 +1,7 @@
/** /**
* @file media-error.js * @file media-error.js
*/ */
import {assign, isObject} from './utils/obj'; import {isObject} from './utils/obj';
/** /**
* A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class. * A Custom `MediaError` class which mimics the standard HTML5 `MediaError` class.
@ -41,7 +41,7 @@ function MediaError(value) {
this.code = value.code; this.code = value.code;
} }
assign(this, value); Object.assign(this, value);
} }
if (!this.message) { if (!this.message) {

View File

@ -3,7 +3,6 @@
*/ */
import ClickableComponent from '../clickable-component.js'; import ClickableComponent from '../clickable-component.js';
import Component from '../component.js'; import Component from '../component.js';
import {assign} from '../utils/obj';
import {MenuKeys} from './menu-keys.js'; import {MenuKeys} from './menu-keys.js';
import keycode from 'keycode'; import keycode from 'keycode';
import {createEl} from '../utils/dom.js'; import {createEl} from '../utils/dom.js';
@ -64,7 +63,7 @@ class MenuItem extends ClickableComponent {
// The control is textual, not just an icon // The control is textual, not just an icon
this.nonIconControl = true; this.nonIconControl = true;
const el = super.createEl('li', assign({ const el = super.createEl('li', Object.assign({
className: 'vjs-menu-item', className: 'vjs-menu-item',
tabIndex: -1 tabIndex: -1
}, props), attrs); }, props), attrs);

View File

@ -6,7 +6,6 @@ import window from 'global/window';
import * as Dom from '../utils/dom'; import * as Dom from '../utils/dom';
import * as Events from '../utils/events'; import * as Events from '../utils/events';
import * as Fn from '../utils/fn'; import * as Fn from '../utils/fn';
import * as Obj from '../utils/obj';
import EventTarget from '../event-target'; import EventTarget from '../event-target';
import DomData from '../utils/dom-data'; import DomData from '../utils/dom-data';
import log from '../utils/log'; import log from '../utils/log';
@ -489,7 +488,7 @@ function evented(target, options = {}) {
target.eventBusEl_ = Dom.createEl('span', {className: 'vjs-event-bus'}); target.eventBusEl_ = Dom.createEl('span', {className: 'vjs-event-bus'});
} }
Obj.assign(target, EventedMixin); Object.assign(target, EventedMixin);
if (target.eventedCallbacks) { if (target.eventedCallbacks) {
target.eventedCallbacks.forEach((callback) => { target.eventedCallbacks.forEach((callback) => {

View File

@ -103,11 +103,11 @@ const StatefulMixin = {
* Returns the `target`. * Returns the `target`.
*/ */
function stateful(target, defaultState) { function stateful(target, defaultState) {
Obj.assign(target, StatefulMixin); Object.assign(target, StatefulMixin);
// This happens after the mixing-in because we need to replace the `state` // This happens after the mixing-in because we need to replace the `state`
// added in that step. // added in that step.
target.state = Obj.assign({}, target.state, defaultState); target.state = Object.assign({}, target.state, defaultState);
// Auto-bind the `handleStateChanged` method of the target object if it exists. // Auto-bind the `handleStateChanged` method of the target object if it exists.
if (typeof target.handleStateChanged === 'function' && isEvented(target)) { if (typeof target.handleStateChanged === 'function' && isEvented(target)) {

View File

@ -17,7 +17,7 @@ import * as browser from './utils/browser.js';
import {IE_VERSION, IS_CHROME, IS_WINDOWS} from './utils/browser.js'; import {IE_VERSION, IS_CHROME, IS_WINDOWS} from './utils/browser.js';
import log, { createLogger } from './utils/log.js'; import log, { createLogger } from './utils/log.js';
import {toTitleCase, titleCaseEquals} from './utils/str.js'; import {toTitleCase, titleCaseEquals} from './utils/str.js';
import { createTimeRange } from './utils/time-ranges.js'; import { createTimeRanges } from './utils/time';
import { bufferedPercent } from './utils/buffer.js'; import { bufferedPercent } from './utils/buffer.js';
import * as stylesheet from './utils/stylesheet.js'; import * as stylesheet from './utils/stylesheet.js';
import FullscreenApi from './fullscreen-api.js'; import FullscreenApi from './fullscreen-api.js';
@ -32,7 +32,7 @@ import {ALL as TRACK_TYPES} from './tracks/track-types';
import filterSource from './utils/filter-source'; import filterSource from './utils/filter-source';
import {getMimetype, findMimetype} from './utils/mimetypes'; import {getMimetype, findMimetype} from './utils/mimetypes';
import {hooks} from './utils/hooks'; import {hooks} from './utils/hooks';
import {assign, merge, isObject} from './utils/obj'; import {merge, isObject} from './utils/obj';
import keycode from 'keycode'; import keycode from 'keycode';
// The following imports are used only to ensure that the corresponding modules // The following imports are used only to ensure that the corresponding modules
@ -310,7 +310,7 @@ class Player extends Component {
// which overrides globally set options. // which overrides globally set options.
// This latter part coincides with the load order // This latter part coincides with the load order
// (tag must exist before Player) // (tag must exist before Player)
options = assign(Player.getTagSettings(tag), options); options = Object.assign(Player.getTagSettings(tag), options);
// Delay the initialization of children because we need to set up // Delay the initialization of children because we need to set up
// player properties first, and can't use `this` before `super()` // player properties first, and can't use `this` before `super()`
@ -1185,9 +1185,9 @@ class Player extends Component {
techOptions[props.getterName] = this[props.privateName]; techOptions[props.getterName] = this[props.privateName];
}); });
assign(techOptions, this.options_[titleTechName]); Object.assign(techOptions, this.options_[titleTechName]);
assign(techOptions, this.options_[camelTechName]); Object.assign(techOptions, this.options_[camelTechName]);
assign(techOptions, this.options_[techName.toLowerCase()]); Object.assign(techOptions, this.options_[techName.toLowerCase()]);
if (this.tag) { if (this.tag) {
techOptions.tag = this.tag; techOptions.tag = this.tag;
@ -2487,7 +2487,7 @@ class Player extends Component {
* been played. * been played.
*/ */
played() { played() {
return this.techGet_('played') || createTimeRange(0, 0); return this.techGet_('played') || createTimeRanges(0, 0);
} }
/** /**
@ -2650,7 +2650,7 @@ class Player extends Component {
let buffered = this.techGet_('buffered'); let buffered = this.techGet_('buffered');
if (!buffered || !buffered.length) { if (!buffered || !buffered.length) {
buffered = createTimeRange(0, 0); buffered = createTimeRanges(0, 0);
} }
return buffered; return buffered;
@ -4796,18 +4796,18 @@ class Player extends Component {
// Used as a getter. // Used as a getter.
if (breakpoints === undefined) { if (breakpoints === undefined) {
return assign(this.breakpoints_); return Object.assign(this.breakpoints_);
} }
this.breakpoint_ = ''; this.breakpoint_ = '';
this.breakpoints_ = assign({}, DEFAULT_BREAKPOINTS, breakpoints); this.breakpoints_ = Object.assign({}, DEFAULT_BREAKPOINTS, breakpoints);
// When breakpoint definitions change, we need to update the currently // When breakpoint definitions change, we need to update the currently
// selected breakpoint. // selected breakpoint.
this.updateCurrentBreakpoint_(); this.updateCurrentBreakpoint_();
// Clone the breakpoints before returning. // Clone the breakpoints before returning.
return assign(this.breakpoints_); return Object.assign(this.breakpoints_);
} }
/** /**
@ -5037,10 +5037,10 @@ class Player extends Component {
if (err) { if (err) {
log.error(err); log.error(err);
} }
assign(tagOptions, data); Object.assign(tagOptions, data);
} }
assign(baseOptions, tagOptions); Object.assign(baseOptions, tagOptions);
// Get tag children settings // Get tag children settings
if (tag.hasChildNodes()) { if (tag.hasChildNodes()) {

View File

@ -3,9 +3,8 @@
*/ */
import Component from '../component.js'; import Component from '../component.js';
import * as Dom from '../utils/dom.js'; import * as Dom from '../utils/dom.js';
import {assign} from '../utils/obj';
import {IS_CHROME} from '../utils/browser.js'; import {IS_CHROME} from '../utils/browser.js';
import clamp from '../utils/clamp.js'; import {clamp} from '../utils/num';
import keycode from 'keycode'; import keycode from 'keycode';
/** /**
@ -126,11 +125,11 @@ class Slider extends Component {
createEl(type, props = {}, attributes = {}) { createEl(type, props = {}, attributes = {}) {
// Add the slider element class to all sub classes // Add the slider element class to all sub classes
props.className = props.className + ' vjs-slider'; props.className = props.className + ' vjs-slider';
props = assign({ props = Object.assign({
tabIndex: 0 tabIndex: 0
}, props); }, props);
attributes = assign({ attributes = Object.assign({
'role': 'slider', 'role': 'slider',
'aria-valuenow': 0, 'aria-valuenow': 0,
'aria-valuemin': 0, 'aria-valuemin': 0,

View File

@ -8,7 +8,7 @@ import log from '../utils/log.js';
import * as browser from '../utils/browser.js'; import * as browser from '../utils/browser.js';
import document from 'global/document'; import document from 'global/document';
import window from 'global/window'; import window from 'global/window';
import {assign, merge} from '../utils/obj'; import {merge} from '../utils/obj';
import {toTitleCase} from '../utils/str.js'; import {toTitleCase} from '../utils/str.js';
import {NORMAL as TRACK_TYPES, REMOTE} from '../tracks/track-types'; import {NORMAL as TRACK_TYPES, REMOTE} from '../tracks/track-types';
import setupSourceset from './setup-sourceset'; import setupSourceset from './setup-sourceset';
@ -392,7 +392,7 @@ class Html5 extends Tech {
Dom.setAttributes( Dom.setAttributes(
el, el,
assign(attributes, { Object.assign(attributes, {
id: this.options_.techId, id: this.options_.techId,
class: 'vjs-tech' class: 'vjs-tech'
}) })

View File

@ -2,7 +2,6 @@
* @file middleware.js * @file middleware.js
* @module middleware * @module middleware
*/ */
import { assign } from '../utils/obj.js';
import {toTitleCase} from '../utils/str.js'; import {toTitleCase} from '../utils/str.js';
const middlewares = {}; const middlewares = {};
@ -301,7 +300,7 @@ function setSourceHelper(src = {}, middleware = [], next, player, acc = [], last
return setSourceHelper(src, mwrest, next, player, acc, lastRun); return setSourceHelper(src, mwrest, next, player, acc, lastRun);
} }
mw.setSource(assign({}, src), function(err, _src) { mw.setSource(Object.assign({}, src), function(err, _src) {
// something happened, try the next middleware on the current level // something happened, try the next middleware on the current level
// make sure to use the old src // make sure to use the old src

View File

@ -5,7 +5,7 @@
import Component from '../component'; import Component from '../component';
import * as Fn from '../utils/fn.js'; import * as Fn from '../utils/fn.js';
import log from '../utils/log.js'; import log from '../utils/log.js';
import { createTimeRange } from '../utils/time-ranges.js'; import { createTimeRanges } from '../utils/time';
import { bufferedPercent } from '../utils/buffer.js'; import { bufferedPercent } from '../utils/buffer.js';
import MediaError from '../media-error.js'; import MediaError from '../media-error.js';
import window from 'global/window'; import window from 'global/window';
@ -279,7 +279,7 @@ class Tech extends Component {
* The time range object that was created. * The time range object that was created.
*/ */
buffered() { buffered() {
return createTimeRange(0, 0); return createTimeRanges(0, 0);
} }
/** /**
@ -486,9 +486,9 @@ class Tech extends Component {
*/ */
played() { played() {
if (this.hasStarted_) { if (this.hasStarted_) {
return createTimeRange(0, 0); return createTimeRanges(0, 0);
} }
return createTimeRange(); return createTimeRanges();
} }
/** /**

View File

@ -2,7 +2,7 @@
* @file buffer.js * @file buffer.js
* @module buffer * @module buffer
*/ */
import { createTimeRange } from './time-ranges.js'; import { createTimeRanges } from './time';
/** /**
* Compute the percentage of the media that has been buffered. * Compute the percentage of the media that has been buffered.
@ -26,7 +26,7 @@ export function bufferedPercent(buffered, duration) {
} }
if (!buffered || !buffered.length) { if (!buffered || !buffered.length) {
buffered = createTimeRange(0, 0); buffered = createTimeRanges(0, 0);
} }
for (let i = 0; i < buffered.length; i++) { for (let i = 0; i < buffered.length; i++) {

View File

@ -1,94 +0,0 @@
/**
* @file format-time.js
* @module format-time
*/
/**
* Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in
* seconds) will force a number of leading zeros to cover the length of the
* guide.
*
* @private
* @param {number} seconds
* Number of seconds to be turned into a string
*
* @param {number} guide
* Number (in seconds) to model the string after
*
* @return {string}
* Time formatted as H:MM:SS or M:SS
*/
const defaultImplementation = function(seconds, guide) {
seconds = seconds < 0 ? 0 : seconds;
let s = Math.floor(seconds % 60);
let m = Math.floor(seconds / 60 % 60);
let h = Math.floor(seconds / 3600);
const gm = Math.floor(guide / 60 % 60);
const gh = Math.floor(guide / 3600);
// handle invalid times
if (isNaN(seconds) || seconds === Infinity) {
// '-' is false for all relational operators (e.g. <, >=) so this setting
// will add the minimum number of fields specified by the guide
h = m = s = '-';
}
// Check if we need to show hours
h = (h > 0 || gh > 0) ? h + ':' : '';
// If hours are showing, we may need to add a leading zero.
// Always show at least one digit of minutes.
m = (((h || gm >= 10) && m < 10) ? '0' + m : m) + ':';
// Check if leading zero is need for seconds
s = (s < 10) ? '0' + s : s;
return h + m + s;
};
// Internal pointer to the current implementation.
let implementation = defaultImplementation;
/**
* Replaces the default formatTime implementation with a custom implementation.
*
* @param {Function} customImplementation
* A function which will be used in place of the default formatTime
* implementation. Will receive the current time in seconds and the
* guide (in seconds) as arguments.
*/
export function setFormatTime(customImplementation) {
implementation = customImplementation;
}
/**
* Resets formatTime to the default implementation.
*/
export function resetFormatTime() {
implementation = defaultImplementation;
}
/**
* Delegates to either the default time formatting function or a custom
* function supplied via `setFormatTime`.
*
* Formats seconds as a time string (H:MM:SS or M:SS). Supplying a
* guide (in seconds) will force a number of leading zeros to cover the
* length of the guide.
*
* @static
* @example formatTime(125, 600) === "02:05"
* @param {number} seconds
* Number of seconds to be turned into a string
*
* @param {number} guide
* Number (in seconds) to model the string after
*
* @return {string}
* Time formatted as H:MM:SS or M:SS
*/
function formatTime(seconds, guide = seconds) {
return implementation(seconds, guide);
}
export default formatTime;

View File

@ -12,10 +12,8 @@
* @return {number} * @return {number}
* the clamped number * the clamped number
*/ */
const clamp = function(number, min, max) { export const clamp = function(number, min, max) {
number = Number(number); number = Number(number);
return Math.min(max, Math.max(min, isNaN(number) ? min : number)); return Math.min(max, Math.max(min, isNaN(number) ? min : number));
}; };
export default clamp;

View File

@ -80,31 +80,6 @@ export function reduce(object, fn, initial = 0) {
return keys(object).reduce((accum, key) => fn(accum, object[key], key), initial); return keys(object).reduce((accum, key) => fn(accum, object[key], key), initial);
} }
/**
* Object.assign-style object shallow merge/extend.
*
* @param {Object} target
* @param {Object} ...sources
* @return {Object}
*/
export function assign(target, ...sources) {
if (Object.assign) {
return Object.assign(target, ...sources);
}
sources.forEach(source => {
if (!source) {
return;
}
each(source, (value, key) => {
target[key] = value;
});
});
return target;
}
/** /**
* Returns whether a value is an object of any kind - including DOM nodes, * Returns whether a value is an object of any kind - including DOM nodes,
* arrays, regular expressions, etc. Not functions, though. * arrays, regular expressions, etc. Not functions, though.

View File

@ -1,12 +1,100 @@
/** /**
* @file time-ranges.js * @file time.js
* @module time-ranges * @module time
*/ */
import window from 'global/window'; import window from 'global/window';
/**
* Format seconds as a time string, H:MM:SS or M:SS. Supplying a guide (in
* seconds) will force a number of leading zeros to cover the length of the
* guide.
*
* @private
* @param {number} seconds
* Number of seconds to be turned into a string
*
* @param {number} guide
* Number (in seconds) to model the string after
*
* @return {string}
* Time formatted as H:MM:SS or M:SS
*/
const defaultImplementation = function(seconds, guide) {
seconds = seconds < 0 ? 0 : seconds;
let s = Math.floor(seconds % 60);
let m = Math.floor(seconds / 60 % 60);
let h = Math.floor(seconds / 3600);
const gm = Math.floor(guide / 60 % 60);
const gh = Math.floor(guide / 3600);
// handle invalid times
if (isNaN(seconds) || seconds === Infinity) {
// '-' is false for all relational operators (e.g. <, >=) so this setting
// will add the minimum number of fields specified by the guide
h = m = s = '-';
}
// Check if we need to show hours
h = (h > 0 || gh > 0) ? h + ':' : '';
// If hours are showing, we may need to add a leading zero.
// Always show at least one digit of minutes.
m = (((h || gm >= 10) && m < 10) ? '0' + m : m) + ':';
// Check if leading zero is need for seconds
s = (s < 10) ? '0' + s : s;
return h + m + s;
};
// Internal pointer to the current implementation.
let implementation = defaultImplementation;
/**
* Replaces the default formatTime implementation with a custom implementation.
*
* @param {Function} customImplementation
* A function which will be used in place of the default formatTime
* implementation. Will receive the current time in seconds and the
* guide (in seconds) as arguments.
*/
export function setFormatTime(customImplementation) {
implementation = customImplementation;
}
/**
* Resets formatTime to the default implementation.
*/
export function resetFormatTime() {
implementation = defaultImplementation;
}
/**
* Delegates to either the default time formatting function or a custom
* function supplied via `setFormatTime`.
*
* Formats seconds as a time string (H:MM:SS or M:SS). Supplying a
* guide (in seconds) will force a number of leading zeros to cover the
* length of the guide.
*
* @static
* @example formatTime(125, 600) === "02:05"
* @param {number} seconds
* Number of seconds to be turned into a string
*
* @param {number} guide
* Number (in seconds) to model the string after
*
* @return {string}
* Time formatted as H:MM:SS or M:SS
*/
export function formatTime(seconds, guide = seconds) {
return implementation(seconds, guide);
}
/** /**
* Returns the time for the specified index at the start or end * Returns the time for the specified index at the start or end
* of a TimeRange object. * of a TimeRanges object.
* *
* @typedef {Function} TimeRangeIndex * @typedef {Function} TimeRangeIndex
* *
@ -23,15 +111,15 @@ import window from 'global/window';
/** /**
* An object that contains ranges of time. * An object that contains ranges of time.
* *
* @typedef {Object} TimeRange * @typedef {Object} TimeRanges
* *
* @property {number} length * @property {number} length
* The number of time ranges represented by this object. * The number of time ranges represented by this object.
* *
* @property {module:time-ranges~TimeRangeIndex} start * @property {module:time~TimeRangeIndex} start
* Returns the time offset at which a specified time range begins. * Returns the time offset at which a specified time range begins.
* *
* @property {module:time-ranges~TimeRangeIndex} end * @property {module:time~TimeRangeIndex} end
* Returns the time offset at which a specified time range ends. * Returns the time offset at which a specified time range ends.
* *
* @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges * @see https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges
@ -60,7 +148,7 @@ function rangeCheck(fnName, index, maxIndex) {
/** /**
* Get the time for the specified index at the start or end * Get the time for the specified index at the start or end
* of a TimeRange object. * of a TimeRanges object.
* *
* @private * @private
* @param {string} fnName * @param {string} fnName
@ -123,7 +211,7 @@ function createTimeRangesObj(ranges) {
} }
/** /**
* Create a `TimeRange` object which mimics an * Create a `TimeRanges` object which mimics an
* {@link https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges|HTML5 TimeRanges instance}. * {@link https://developer.mozilla.org/en-US/docs/Web/API/TimeRanges|HTML5 TimeRanges instance}.
* *
* @param {number|Array[]} start * @param {number|Array[]} start
@ -142,5 +230,3 @@ export function createTimeRanges(start, end) {
} }
return createTimeRangesObj([[start, end]]); return createTimeRangesObj([[start, end]]);
} }
export { createTimeRanges as createTimeRange };

View File

@ -82,7 +82,7 @@ export const parseUrl = function(url) {
}; };
/** /**
* Get absolute version of relative URL. Used to tell Flash the correct URL. * Get absolute version of relative URL.
* *
* @function * @function
* @param {string} url * @param {string} url

View File

@ -6,7 +6,6 @@ import {version} from '../../package.json';
import window from 'global/window'; import window from 'global/window';
// Include core functions and classes // Include core functions and classes
import extend from './extend';
import * as setup from './setup'; import * as setup from './setup';
import * as stylesheet from './utils/stylesheet'; import * as stylesheet from './utils/stylesheet';
import Component from './component'; import Component from './component';
@ -18,16 +17,17 @@ import AudioTrack from './tracks/audio-track';
import VideoTrack from './tracks/video-track'; import VideoTrack from './tracks/video-track';
// Include utilities // Include utilities
import { createTimeRange } from './utils/time-ranges';
import formatTime, { setFormatTime, resetFormatTime } from './utils/format-time';
import log, { createLogger } from './utils/log'; import log, { createLogger } from './utils/log';
import deprecate from './utils/deprecate';
// The browser and DOM utilities are the only ones that are exported wholesale
// on the videojs function. All others are exported selectively/explicitly.
import * as browser from './utils/browser'; import * as browser from './utils/browser';
import clamp from './utils/clamp';
import computedStyle from './utils/computed-style';
import * as dom from './utils/dom'; import * as dom from './utils/dom';
import * as events from './utils/events';
import * as fn from './utils/fn'; import computedStyle from './utils/computed-style';
import deprecate from './utils/deprecate';
import { any, off, on, one, trigger } from './utils/events';
import { debounce, throttle } from './utils/fn';
import { import {
hooks_, hooks_,
@ -37,10 +37,12 @@ import {
removeHook removeHook
} from './utils/hooks'; } from './utils/hooks';
import * as obj from './utils/obj'; import { clamp } from './utils/num';
import * as promise from './utils/promise'; import { each, reduce, isObject, isPlain, merge } from './utils/obj';
import * as str from './utils/str'; import { isPromise, silencePromise } from './utils/promise';
import * as url from './utils/url'; import { toLowerCase, toTitleCase, titleCaseEquals } from './utils/str';
import { createTimeRanges, formatTime, resetFormatTime, setFormatTime } from './utils/time';
import { parseUrl, getAbsoluteURL, getFileExtension, isCrossOrigin } from './utils/url';
import xhr from '@videojs/xhr'; import xhr from '@videojs/xhr';
@ -106,9 +108,9 @@ const normalizeId = (id) => id.indexOf('#') === 0 ? id.slice(1) : id;
* @borrows EventTarget as EventTarget * @borrows EventTarget as EventTarget
* @borrows module:extend~extend as extend * @borrows module:extend~extend as extend
* @borrows module:fn.bind as bind * @borrows module:fn.bind as bind
* @borrows module:format-time.formatTime as formatTime * @borrows module:time.formatTime as formatTime
* @borrows module:format-time.resetFormatTime as resetFormatTime * @borrows module:time.resetFormatTime as resetFormatTime
* @borrows module:format-time.setFormatTime as setFormatTime * @borrows module:time.setFormatTime as setFormatTime
* @borrows module:middleware.use as use * @borrows module:middleware.use as use
* @borrows Player.players as players * @borrows Player.players as players
* @borrows Plugin.registerPlugin as registerPlugin * @borrows Plugin.registerPlugin as registerPlugin
@ -119,8 +121,8 @@ const normalizeId = (id) => id.indexOf('#') === 0 ? id.slice(1) : id;
* @borrows Tech.getTech as getTech * @borrows Tech.getTech as getTech
* @borrows Tech.registerTech as registerTech * @borrows Tech.registerTech as registerTech
* @borrows TextTrack as TextTrack * @borrows TextTrack as TextTrack
* @borrows module:time-ranges.createTimeRanges as createTimeRange * @borrows module:time.createTimeRanges as createTimeRanges
* @borrows module:time-ranges.createTimeRanges as createTimeRanges * @borrows module:time.createTimeRanges as createTimeRanges
* @borrows module:url.isCrossOrigin as isCrossOrigin * @borrows module:url.isCrossOrigin as isCrossOrigin
* @borrows module:url.parseUrl as parseUrl * @borrows module:url.parseUrl as parseUrl
* @borrows VideoTrack as VideoTrack * @borrows VideoTrack as VideoTrack
@ -171,14 +173,14 @@ function videojs(id, options, ready) {
options = options || {}; options = options || {};
hooks('beforesetup').forEach((hookFunction) => { hooks('beforesetup').forEach((hookFunction) => {
const opts = hookFunction(el, obj.merge(options)); const opts = hookFunction(el, merge(options));
if (!obj.isObject(opts) || Array.isArray(opts)) { if (!isObject(opts) || Array.isArray(opts)) {
log.error('please return an object in beforesetup hooks'); log.error('please return an object in beforesetup hooks');
return; return;
} }
options = obj.merge(options, opts); options = merge(options, opts);
}); });
// We get the current "Player" component here in case an integration has // We get the current "Player" component here in case an integration has
@ -374,7 +376,7 @@ Object.defineProperty(videojs.middleware, 'TERMINATOR', {
videojs.addLanguage = function(code, data) { videojs.addLanguage = function(code, data) {
code = ('' + code).toLowerCase(); code = ('' + code).toLowerCase();
videojs.options.languages = obj.merge( videojs.options.languages = merge(
videojs.options.languages, videojs.options.languages,
{[code]: data} {[code]: data}
); );
@ -419,16 +421,14 @@ videojs.dom = dom;
* @type {Object} * @type {Object}
* @see {@link module:fn|fn} * @see {@link module:fn|fn}
*/ */
videojs.fn = fn; videojs.fn = { debounce, throttle };
/** /**
* An object containing number-related functions. * An object containing number-related functions.
* *
* @type {Object} * @type {Object}
*/ */
videojs.num = { videojs.num = { clamp };
clamp
};
/** /**
* A reference to the {@link module:obj|object utility module} as an object. * A reference to the {@link module:obj|object utility module} as an object.
@ -436,7 +436,7 @@ videojs.num = {
* @type {Object} * @type {Object}
* @see {@link module:obj|obj} * @see {@link module:obj|obj}
*/ */
videojs.obj = obj; videojs.obj = { each, reduce, isObject, isPlain, merge };
/** /**
* A reference to the {@link module:promise|promise utility module} as an object. * A reference to the {@link module:promise|promise utility module} as an object.
@ -444,7 +444,7 @@ videojs.obj = obj;
* @type {Object} * @type {Object}
* @see {@link module:promise|promise} * @see {@link module:promise|promise}
*/ */
videojs.promise = promise; videojs.promise = { isPromise, silencePromise };
/** /**
* A reference to the {@link module:str|string utility module} as an object. * A reference to the {@link module:str|string utility module} as an object.
@ -452,19 +452,14 @@ videojs.promise = promise;
* @type {Object} * @type {Object}
* @see {@link module:str|str} * @see {@link module:str|str}
*/ */
videojs.str = str; videojs.str = { toLowerCase, toTitleCase, titleCaseEquals };
/** /**
* An object containing time-related functions. * An object containing time-related functions.
* *
* @type {Object} * @type {Object}
*/ */
videojs.time = { videojs.time = { createTimeRanges, formatTime, resetFormatTime, setFormatTime };
createTimeRange,
format: formatTime,
setFormat: setFormatTime,
resetFormat: resetFormatTime
};
/** /**
* A reference to the {@link module:url|URL utility module} as an object. * A reference to the {@link module:url|URL utility module} as an object.
@ -472,7 +467,7 @@ videojs.time = {
* @type {Object} * @type {Object}
* @see {@link module:url|url} * @see {@link module:url|url}
*/ */
videojs.url = url; videojs.url = { parseUrl, getAbsoluteURL, getFileExtension, isCrossOrigin };
/** /**
* Namespace for general utility functions. * Namespace for general utility functions.
@ -485,25 +480,23 @@ videojs.utils = {
}; };
// Deprecated global namespace functions // Deprecated global namespace functions
videojs.extend = deprecate('videojs.extend is deprecated as of 8.0. Please use native ES6 classes instead.', extend); videojs.createTimeRanges = deprecate('videojs.createTimeRanges is deprecated as of 8.0. Please use videojs.time.createTimeRanges instead.', createTimeRanges);
videojs.mergeOptions = deprecate('videojs.mergeOptions is deprecated as of 8.0. Please use videojs.obj.merge instead.', obj.merge); videojs.createTimeRanges = deprecate('videojs.createTimeRanges is deprecated as of 8.0. Please use videojs.time.createTimeRanges instead.', createTimeRanges);
videojs.bind = deprecate('videojs.bind is deprecated as of 8.0. Please use native Function.prototype.bind instead.', fn.bind);
videojs.createTimeRange = deprecate('videojs.createTimeRange is deprecated as of 8.0. Please use videojs.time.createTimeRange instead.', createTimeRange);
videojs.createTimeRanges = deprecate('videojs.createTimeRanges is deprecated as of 8.0. Please use videojs.time.createTimeRange instead.', createTimeRange);
videojs.formatTime = deprecate('videojs.formatTime is deprecated as of 8.0. Please use videojs.time.format instead.', formatTime); videojs.formatTime = deprecate('videojs.formatTime is deprecated as of 8.0. Please use videojs.time.format instead.', formatTime);
videojs.setFormatTime = deprecate('videojs.setFormatTime is deprecated as of 8.0. Please use videojs.time.setFormat instead.', setFormatTime); videojs.setFormatTime = deprecate('videojs.setFormatTime is deprecated as of 8.0. Please use videojs.time.setFormat instead.', setFormatTime);
videojs.resetFormatTime = deprecate('videojs.resetFormatTime is deprecated as of 8.0. Please use videojs.time.resetFormat instead.', resetFormatTime); videojs.resetFormatTime = deprecate('videojs.resetFormatTime is deprecated as of 8.0. Please use videojs.time.resetFormat instead.', resetFormatTime);
videojs.computedStyle = deprecate('videojs.computedStyle is deprecated as of 8.0. Please use videojs.utils.computedStyle instead.', computedStyle); videojs.computedStyle = deprecate('videojs.computedStyle is deprecated as of 8.0. Please use videojs.utils.computedStyle instead.', computedStyle);
videojs.defineLazyProperty = deprecate('videojs.defineLazyProperty is deprecated as of 8.0. Please use videojs.utils.defineLazyProperty instead.', defineLazyProperty); videojs.defineLazyProperty = deprecate('videojs.defineLazyProperty is deprecated as of 8.0. Please use videojs.utils.defineLazyProperty instead.', defineLazyProperty);
videojs.isPromise = deprecate('videojs.isPromise is deprecated as of 8.0. Please use videojs.promise.isPromise instead.', promise.isPromise); videojs.isPromise = deprecate('videojs.isPromise is deprecated as of 8.0. Please use videojs.promise.isPromise instead.', isPromise);
videojs.silencePromise = deprecate('videojs.silencePromise is deprecated as of 8.0. Please use videojs.promise.silencePromise instead.', promise.silencePromise); videojs.silencePromise = deprecate('videojs.silencePromise is deprecated as of 8.0. Please use videojs.promise.silencePromise instead.', silencePromise);
videojs.parseUrl = deprecate('videojs.parseUrl is deprecated as of 8.0. Please use videojs.url.parseUrl instead.', url.parseUrl); videojs.parseUrl = deprecate('videojs.parseUrl is deprecated as of 8.0. Please use videojs.url.parseUrl instead.', parseUrl);
videojs.isCrossOrigin = deprecate('videojs.isCrossOrigin is deprecated as of 8.0. Please use videojs.url.isCrossOrigin instead.', url.isCrossOrigin); videojs.isCrossOrigin = deprecate('videojs.isCrossOrigin is deprecated as of 8.0. Please use videojs.url.isCrossOrigin instead.', isCrossOrigin);
videojs.on = events.on; videojs.any = any;
videojs.one = events.one; videojs.off = off;
videojs.off = events.off; videojs.on = on;
videojs.trigger = events.trigger; videojs.one = one;
videojs.trigger = trigger;
videojs.EventTarget = EventTarget; videojs.EventTarget = EventTarget;
videojs.TextTrack = TextTrack; videojs.TextTrack = TextTrack;

View File

@ -1,6 +1,6 @@
/* eslint-env qunit */ /* eslint-env qunit */
import TestHelpers from './test-helpers.js'; import TestHelpers from './test-helpers.js';
import {createTimeRanges} from '../../src/js/utils/time-ranges.js'; import {createTimeRanges} from '../../src/js/utils/time';
import sinon from 'sinon'; import sinon from 'sinon';
QUnit.module('LiveTracker', () => { QUnit.module('LiveTracker', () => {

View File

@ -1,9 +1,8 @@
/* eslint-env qunit */ /* eslint-env qunit */
import sinon from 'sinon'; import sinon from 'sinon';
import TestHelpers from './test-helpers'; import TestHelpers from './test-helpers';
import {assign} from '../../src/js/utils/obj';
const getExpectedBreakpoints = (o) => assign({}, { const getExpectedBreakpoints = (o) => Object.assign({}, {
tiny: 210, tiny: 210,
xsmall: 320, xsmall: 320,
small: 425, small: 425,

View File

@ -2,7 +2,7 @@
import TestHelpers from './test-helpers.js'; import TestHelpers from './test-helpers.js';
import sinon from 'sinon'; import sinon from 'sinon';
import computedStyle from '../../src/js/utils/computed-style.js'; import computedStyle from '../../src/js/utils/computed-style.js';
import { createTimeRange } from '../../src/js/utils/time-ranges.js'; import { createTimeRanges } from '../../src/js/utils/time';
QUnit.module('SeekToLive', { QUnit.module('SeekToLive', {
beforeEach() { beforeEach() {
@ -17,7 +17,7 @@ QUnit.module('SeekToLive', {
this.player.paused = () => false; this.player.paused = () => false;
this.player.hasStarted = () => true; this.player.hasStarted = () => true;
this.player.options_.liveui = true; this.player.options_.liveui = true;
this.player.seekable = () => createTimeRange(0, 45); this.player.seekable = () => createTimeRanges(0, 45);
this.player.currentTime = () => this.player.liveTracker.liveCurrentTime(); this.player.currentTime = () => this.player.liveTracker.liveCurrentTime();
this.player.duration(Infinity); this.player.duration(Infinity);
}; };
@ -35,7 +35,7 @@ QUnit.test('liveui enabled, can switch between at and behind live edge ', functi
assert.ok(this.seekToLive.hasClass('vjs-at-live-edge'), 'has at live edge class'); assert.ok(this.seekToLive.hasClass('vjs-at-live-edge'), 'has at live edge class');
this.player.currentTime = () => 0; this.player.currentTime = () => 0;
this.player.seekable = () => createTimeRange(0, 38); this.player.seekable = () => createTimeRanges(0, 38);
this.clock.tick(30); this.clock.tick(30);
assert.notOk(this.seekToLive.hasClass('vjs-at-live-edge'), 'does not have at live edge class'); assert.notOk(this.seekToLive.hasClass('vjs-at-live-edge'), 'does not have at live edge class');
@ -84,7 +84,7 @@ QUnit.test('liveui disabled live window is never shown', function(assert) {
// liveui false // liveui false
this.player.options_.liveui = false; this.player.options_.liveui = false;
this.player.seekable = () => createTimeRange(0, 19); this.player.seekable = () => createTimeRanges(0, 19);
this.player.duration(Infinity); this.player.duration(Infinity);
assert.equal(this.getComputedDisplay(), 'none', 'is hidden'); assert.equal(this.getComputedDisplay(), 'none', 'is hidden');

View File

@ -1,7 +1,7 @@
// Fake a media playback tech controller so that player tests // Fake a media playback tech controller so that player tests
// can run without HTML5 which PhantomJS does not support. // can run without HTML5 which PhantomJS does not support.
import Tech from '../../../src/js/tech/tech.js'; import Tech from '../../../src/js/tech/tech.js';
import {createTimeRanges} from '../../../src/js/utils/time-ranges.js'; import {createTimeRanges} from '../../../src/js/utils/time';
/** /**
* @class * @class
*/ */

View File

@ -2,7 +2,7 @@
import Tech from '../../../src/js/tech/tech.js'; import Tech from '../../../src/js/tech/tech.js';
import Html5 from '../../../src/js/tech/html5.js'; import Html5 from '../../../src/js/tech/html5.js';
import Button from '../../../src/js/button.js'; import Button from '../../../src/js/button.js';
import { createTimeRange } from '../../../src/js/utils/time-ranges.js'; import { createTimeRanges } from '../../../src/js/utils/time';
import extend from '../../../src/js/extend.js'; import extend from '../../../src/js/extend.js';
import MediaError from '../../../src/js/media-error.js'; import MediaError from '../../../src/js/media-error.js';
import AudioTrack from '../../../src/js/tracks/audio-track'; import AudioTrack from '../../../src/js/tracks/audio-track';
@ -573,7 +573,7 @@ QUnit.test('delegates deferrables to the source handler', function(assert) {
const handler = { const handler = {
seekable() { seekable() {
seekableCount++; seekableCount++;
return createTimeRange(0, 0); return createTimeRanges(0, 0);
}, },
seeking() { seeking() {
seekingCount++; seekingCount++;
@ -624,7 +624,7 @@ QUnit.test('delegates only deferred deferrables to the source handler', function
const handler = { const handler = {
seekable() { seekable() {
seekableCount++; seekableCount++;
return createTimeRange(0, 0); return createTimeRanges(0, 0);
}, },
duration() { duration() {
durationCount++; durationCount++;

View File

@ -1,50 +0,0 @@
/* eslint-env qunit */
import formatTime, { setFormatTime, resetFormatTime } from '../../../src/js/utils/format-time.js';
QUnit.module('format-time standard implementation', {
afterEach: resetFormatTime()
});
QUnit.test('should format time as a string', function(assert) {
assert.ok(formatTime(1) === '0:01');
assert.ok(formatTime(10) === '0:10');
assert.ok(formatTime(60) === '1:00');
assert.ok(formatTime(600) === '10:00');
assert.ok(formatTime(3600) === '1:00:00');
assert.ok(formatTime(36000) === '10:00:00');
assert.ok(formatTime(360000) === '100:00:00');
// Using guide should provide extra leading zeros
assert.ok(formatTime(1, 1) === '0:01');
assert.ok(formatTime(1, 10) === '0:01');
assert.ok(formatTime(1, 60) === '0:01');
assert.ok(formatTime(1, 600) === '00:01');
assert.ok(formatTime(1, 3600) === '0:00:01');
// Don't do extra leading zeros for hours
assert.ok(formatTime(1, 36000) === '0:00:01');
assert.ok(formatTime(1, 360000) === '0:00:01');
// Do not display negative time
assert.ok(formatTime(-1) === '0:00');
assert.ok(formatTime(-1, 3600) === '0:00:00');
});
QUnit.test('should format invalid times as dashes', function(assert) {
assert.equal(formatTime(Infinity, 90), '-:-');
assert.equal(formatTime(NaN), '-:-');
assert.equal(formatTime(10, Infinity), '0:00:10');
assert.equal(formatTime(90, NaN), '1:30');
});
QUnit.test('setFormatTime', function(assert) {
setFormatTime((seconds, guide) => `custom:${seconds}:${guide}`);
assert.equal(formatTime(1, 2), 'custom:1:2', 'it should replace the default formatTime implementation');
});
QUnit.test('resetFormatTime ', function(assert) {
setFormatTime((seconds, guide) => `custom:${seconds}:${guide}`);
assert.equal(formatTime(1, 2), 'custom:1:2');
resetFormatTime();
assert.equal(formatTime(1), '0:01', 'it should reset formatTime to the default implementation');
});

View File

@ -106,119 +106,6 @@ QUnit.test('isPlain', function(assert) {
}); });
}); });
QUnit.module('utils/obj.assign', function() {
const assignTests = ['mocked'];
// we only run "normal" tests where Object.assign is used when
// Object.assign is supported
if (Object.assign) {
assignTests.push('unmocked');
}
assignTests.forEach(function(k) {
QUnit.module(`with ${k} Object.assign`, {
before() {
if (k === 'mocked') {
this.oldObjectAssign = Object.assign;
Object.assign = null;
}
},
after() {
if (this.oldObjectAssign) {
Object.assign = this.oldObjectAssign;
}
this.oldObjectAssign = null;
}
});
QUnit.test('override object', function(assert) {
const foo = {foo: 'yellow'};
assert.deepEqual(obj.assign(foo, {foo: 'blue'}), {foo: 'blue'}, 'obj.assign should return overriden result');
assert.deepEqual(foo, {foo: 'blue'}, 'foo should be modified directly');
});
QUnit.test('new object', function(assert) {
const foo = {foo: 'yellow'};
assert.deepEqual(obj.assign({}, foo, {foo: 'blue'}), {foo: 'blue'}, 'obj.assign should return result');
assert.deepEqual(foo, {foo: 'yellow'}, 'foo should not be modified');
});
QUnit.test('empty override', function(assert) {
const foo = {foo: 'yellow'};
assert.deepEqual(obj.assign(foo, {}), {foo: 'yellow'}, 'obj.assign should return result');
assert.deepEqual(foo, {foo: 'yellow'}, 'foo should not be modified');
});
QUnit.test('multiple override object', function(assert) {
const foo = {foo: 'foo'};
const bar = {foo: 'bar'};
const baz = {foo: 'baz'};
assert.deepEqual(obj.assign(foo, bar, baz), baz, 'obj.assign should return result');
assert.deepEqual(foo, baz, 'foo should be overridden');
});
QUnit.test('additive properties', function(assert) {
const foo = {};
const expected = {one: 1, two: 2, three: 3};
assert.deepEqual(obj.assign(foo, {one: 1}, {two: 2}, {three: 3}), expected, 'obj.assign should return result');
assert.deepEqual(foo, expected, 'foo should be equal to result');
});
QUnit.test('deep override', function(assert) {
const foo = {
foo: {
bar: {
baz: 'buzz'
}
},
blue: [55, 56],
red: 'nope'
};
const baz = {
foo: {
bar: {
baz: 'red'
}
},
blue: [57]
};
const expected = {
foo: {
bar: {
baz: 'red'
}
},
blue: [57],
red: 'nope'
};
assert.deepEqual(obj.assign(foo, baz), expected, 'obj.assign should return result');
assert.deepEqual(foo, expected, 'foo is overridden');
});
QUnit.test('negative tests', function(assert) {
const expected = {foo: 11};
assert.deepEqual(obj.assign({}, expected, undefined), expected, 'assign should undefined');
assert.deepEqual(obj.assign({}, expected, null), expected, 'assign should ignore null');
assert.deepEqual(obj.assign({}, expected, []), expected, 'assign should ignore Array');
assert.deepEqual(obj.assign({}, expected, ''), expected, 'assign should ignore string');
assert.deepEqual(obj.assign({}, expected, 11), expected, 'assign should ignore number');
assert.deepEqual(obj.assign({}, expected, new RegExp()), expected, 'assign should ignore RegExp');
assert.deepEqual(obj.assign({}, expected, new Date()), expected, 'assign should ignore Date');
assert.deepEqual(obj.assign({}, expected, true), expected, 'assign should ignore boolean');
assert.deepEqual(obj.assign({}, expected, () => {}), expected, 'assign should ignore function');
});
});
});
QUnit.test('utils/obj.merge', function(assert) { QUnit.test('utils/obj.merge', function(assert) {
const ob1 = { const ob1 = {
a: true, a: true,

View File

@ -1,17 +1,56 @@
/* eslint-env qunit */ /* eslint-env qunit */
import { createTimeRanges, createTimeRange } from '../../../src/js/utils/time-ranges.js';
import window from 'global/window'; import window from 'global/window';
import { createTimeRanges, formatTime, resetFormatTime, setFormatTime } from '../../../src/js/utils/time';
QUnit.module('time-ranges'); QUnit.module('time formatting', {
afterEach: resetFormatTime()
QUnit.test('should export the deprecated createTimeRange function', function(assert) {
assert.equal(
createTimeRange,
createTimeRanges,
'createTimeRange is an alias to createTimeRanges'
);
}); });
QUnit.test('should format time as a string', function(assert) {
assert.ok(formatTime(1) === '0:01');
assert.ok(formatTime(10) === '0:10');
assert.ok(formatTime(60) === '1:00');
assert.ok(formatTime(600) === '10:00');
assert.ok(formatTime(3600) === '1:00:00');
assert.ok(formatTime(36000) === '10:00:00');
assert.ok(formatTime(360000) === '100:00:00');
// Using guide should provide extra leading zeros
assert.ok(formatTime(1, 1) === '0:01');
assert.ok(formatTime(1, 10) === '0:01');
assert.ok(formatTime(1, 60) === '0:01');
assert.ok(formatTime(1, 600) === '00:01');
assert.ok(formatTime(1, 3600) === '0:00:01');
// Don't do extra leading zeros for hours
assert.ok(formatTime(1, 36000) === '0:00:01');
assert.ok(formatTime(1, 360000) === '0:00:01');
// Do not display negative time
assert.ok(formatTime(-1) === '0:00');
assert.ok(formatTime(-1, 3600) === '0:00:00');
});
QUnit.test('should format invalid times as dashes', function(assert) {
assert.equal(formatTime(Infinity, 90), '-:-');
assert.equal(formatTime(NaN), '-:-');
assert.equal(formatTime(10, Infinity), '0:00:10');
assert.equal(formatTime(90, NaN), '1:30');
});
QUnit.test('setFormatTime', function(assert) {
setFormatTime((seconds, guide) => `custom:${seconds}:${guide}`);
assert.equal(formatTime(1, 2), 'custom:1:2', 'it should replace the default formatTime implementation');
});
QUnit.test('resetFormatTime ', function(assert) {
setFormatTime((seconds, guide) => `custom:${seconds}:${guide}`);
assert.equal(formatTime(1, 2), 'custom:1:2');
resetFormatTime();
assert.equal(formatTime(1), '0:01', 'it should reset formatTime to the default implementation');
});
QUnit.module('time ranges');
QUnit.test('should create a fake single timerange', function(assert) { QUnit.test('should create a fake single timerange', function(assert) {
const tr = createTimeRanges(0, 10); const tr = createTimeRanges(0, 10);
@ -95,3 +134,4 @@ QUnit[testOrSkip]('Array.from works on our time ranges object', function(assert)
tr = createTimeRanges(0, 10); tr = createTimeRanges(0, 10);
assert.deepEqual(Array.from(tr), [[0, 10]], 'we got back a ranges representation'); assert.deepEqual(Array.from(tr), [[0, 10]], 'we got back a ranges representation');
}); });