mirror of
https://github.com/videojs/video.js.git
synced 2025-03-05 15:16:06 +02:00
feat: videojs.getTech
works with TitleCase
or camelCase
names (#4010)
* Fixes #3986 * update `techOptions` to look for `TitleCase`/`camelCase` user tech options * remove deprecated usage of Tech as Component * add a unit test to verify that registerTech works * change defaultTech_ to defaultTechOrder_
This commit is contained in:
parent
fcb5aa8383
commit
a8f2e43274
@ -806,14 +806,17 @@ class Player extends Component {
|
||||
this.unloadTech_();
|
||||
}
|
||||
|
||||
const titleTechName = toTitleCase(techName);
|
||||
const camelTechName = techName.charAt(0).toLowerCase() + techName.slice(1);
|
||||
|
||||
// get rid of the HTML5 video tag as soon as we are using another tech
|
||||
if (techName !== 'Html5' && this.tag) {
|
||||
if (titleTechName !== 'Html5' && this.tag) {
|
||||
Tech.getTech('Html5').disposeMediaElement(this.tag);
|
||||
this.tag.player = null;
|
||||
this.tag = null;
|
||||
}
|
||||
|
||||
this.techName_ = techName;
|
||||
this.techName_ = titleTechName;
|
||||
|
||||
// Turn off API access because we're loading a new tech that might load asynchronously
|
||||
this.isReady_ = false;
|
||||
@ -823,7 +826,7 @@ class Player extends Component {
|
||||
source,
|
||||
'nativeControlsForTouch': this.options_.nativeControlsForTouch,
|
||||
'playerId': this.id(),
|
||||
'techId': `${this.id()}_${techName}_api`,
|
||||
'techId': `${this.id()}_${titleTechName}_api`,
|
||||
'autoplay': this.options_.autoplay,
|
||||
'preload': this.options_.preload,
|
||||
'loop': this.options_.loop,
|
||||
@ -840,6 +843,8 @@ class Player extends Component {
|
||||
techOptions[props.getterName] = this[props.privateName];
|
||||
});
|
||||
|
||||
assign(techOptions, this.options_[titleTechName]);
|
||||
assign(techOptions, this.options_[camelTechName]);
|
||||
assign(techOptions, this.options_[techName.toLowerCase()]);
|
||||
|
||||
if (this.tag) {
|
||||
@ -851,14 +856,13 @@ class Player extends Component {
|
||||
}
|
||||
|
||||
// Initialize tech instance
|
||||
let TechComponent = Tech.getTech(techName);
|
||||
const TechClass = Tech.getTech(techName);
|
||||
|
||||
// Support old behavior of techs being registered as components.
|
||||
// Remove once that deprecated behavior is removed.
|
||||
if (!TechComponent) {
|
||||
TechComponent = Component.getComponent(techName);
|
||||
if (!TechClass) {
|
||||
throw new Error(`No Tech named '${titleTechName}' exists! '${titleTechName}' should be registered using videojs.registerTech()'`);
|
||||
}
|
||||
this.tech_ = new TechComponent(techOptions);
|
||||
|
||||
this.tech_ = new TechClass(techOptions);
|
||||
|
||||
// player.triggerReady is always async, so don't need this to be async
|
||||
this.tech_.ready(Fn.bind(this, this.handleTechReady_), true);
|
||||
@ -895,7 +899,7 @@ class Player extends Component {
|
||||
|
||||
// Add the tech element in the DOM if it was not already there
|
||||
// Make sure to not insert the original video element if using Html5
|
||||
if (this.tech_.el().parentNode !== this.el() && (techName !== 'Html5' || !this.tag)) {
|
||||
if (this.tech_.el().parentNode !== this.el() && (titleTechName !== 'Html5' || !this.tag)) {
|
||||
Dom.prependTo(this.tech_.el(), this.el());
|
||||
}
|
||||
|
||||
@ -2102,7 +2106,7 @@ class Player extends Component {
|
||||
|
||||
// Loop through each playback technology in the options order
|
||||
for (let i = 0, j = this.options_.techOrder; i < j.length; i++) {
|
||||
const techName = toTitleCase(j[i]);
|
||||
const techName = j[i];
|
||||
let tech = Tech.getTech(techName);
|
||||
|
||||
// Support old behavior of techs being registered as components.
|
||||
@ -2146,12 +2150,8 @@ class Player extends Component {
|
||||
// current platform
|
||||
const techs =
|
||||
this.options_.techOrder
|
||||
.map(toTitleCase)
|
||||
.map((techName) => {
|
||||
// `Component.getComponent(...)` is for support of old behavior of techs
|
||||
// being registered as components.
|
||||
// Remove once that deprecated behavior is removed.
|
||||
return [techName, Tech.getTech(techName) || Component.getComponent(techName)];
|
||||
return [techName, Tech.getTech(techName)];
|
||||
})
|
||||
.filter(([techName, tech]) => {
|
||||
// Check if the current tech is defined before continuing
|
||||
@ -2356,7 +2356,7 @@ class Player extends Component {
|
||||
* and calls `reset` on the tech`.
|
||||
*/
|
||||
reset() {
|
||||
this.loadTech_(toTitleCase(this.options_.techOrder[0]), null);
|
||||
this.loadTech_(this.options_.techOrder[0], null);
|
||||
this.techCall_('reset');
|
||||
}
|
||||
|
||||
@ -3254,7 +3254,7 @@ const navigator = window.navigator;
|
||||
*/
|
||||
Player.prototype.options_ = {
|
||||
// Default order of fallback technology
|
||||
techOrder: Tech.defaultTechs_,
|
||||
techOrder: Tech.defaultTechOrder_,
|
||||
|
||||
html5: {},
|
||||
flash: {},
|
||||
|
@ -13,6 +13,7 @@ import window from 'global/window';
|
||||
import document from 'global/document';
|
||||
import {isPlain} from '../utils/obj';
|
||||
import * as TRACK_TYPES from '../tracks/track-types';
|
||||
import toTitleCase from '../utils/to-title-case';
|
||||
|
||||
/**
|
||||
* An Object containing a structure like: `{src: 'url', type: 'mimetype'}` or string
|
||||
@ -806,10 +807,12 @@ class Tech extends Component {
|
||||
throw new Error('Techs must have a static canPlaySource method on them');
|
||||
}
|
||||
|
||||
name = toTitleCase(name);
|
||||
|
||||
Tech.techs_[name] = tech;
|
||||
if (name !== 'Tech') {
|
||||
// camel case the techName for use in techOrder
|
||||
Tech.defaultTechs_.push(name.charAt(0).toLowerCase() + name.slice(1));
|
||||
Tech.defaultTechOrder_.push(name);
|
||||
}
|
||||
return tech;
|
||||
}
|
||||
@ -818,12 +821,18 @@ class Tech extends Component {
|
||||
* Get a `Tech` from the shared list by name.
|
||||
*
|
||||
* @param {string} name
|
||||
* Name of the component to get
|
||||
* `camelCase` or `TitleCase` name of the Tech to get
|
||||
*
|
||||
* @return {Tech|undefined}
|
||||
* The `Tech` or undefined if there was no tech with the name requsted.
|
||||
*/
|
||||
static getTech(name) {
|
||||
if (!name) {
|
||||
return;
|
||||
}
|
||||
|
||||
name = toTitleCase(name);
|
||||
|
||||
if (Tech.techs_ && Tech.techs_[name]) {
|
||||
return Tech.techs_[name];
|
||||
}
|
||||
@ -1185,6 +1194,6 @@ Tech.registerTech('Tech', Tech);
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
Tech.defaultTechs_ = [];
|
||||
Tech.defaultTechOrder_ = [];
|
||||
|
||||
export default Tech;
|
||||
|
@ -1272,7 +1272,7 @@ QUnit.test('player#reset loads the Html5 tech and then techCalls reset', functio
|
||||
|
||||
Player.prototype.reset.call(testPlayer);
|
||||
|
||||
assert.equal(loadedTech, 'Html5', 'we loaded the html5 tech');
|
||||
assert.equal(loadedTech, 'html5', 'we loaded the html5 tech');
|
||||
assert.equal(loadedSource, null, 'with a null source');
|
||||
assert.equal(techCallMethod, 'reset', 'we then reset the tech');
|
||||
});
|
||||
@ -1297,7 +1297,7 @@ QUnit.test('player#reset loads the first item in the techOrder and then techCall
|
||||
|
||||
Player.prototype.reset.call(testPlayer);
|
||||
|
||||
assert.equal(loadedTech, 'Flash', 'we loaded the Flash tech');
|
||||
assert.equal(loadedTech, 'flash', 'we loaded the Flash tech');
|
||||
assert.equal(loadedSource, null, 'with a null source');
|
||||
assert.equal(techCallMethod, 'reset', 'we then reset the tech');
|
||||
});
|
||||
@ -1478,6 +1478,9 @@ QUnit.test('techCall runs through middleware if allowedSetter', function(assert)
|
||||
});
|
||||
|
||||
QUnit.test('src selects tech based on middleware', function(assert) {
|
||||
const oldTechs = Tech.techs_;
|
||||
const oldDefaultTechOrder = Tech.defaultTechOrder_;
|
||||
|
||||
class FooTech extends Html5 {}
|
||||
class BarTech extends Html5 {}
|
||||
|
||||
@ -1538,6 +1541,10 @@ QUnit.test('src selects tech based on middleware', function(assert) {
|
||||
player.dispose();
|
||||
delete Tech.techs_.FooTech;
|
||||
delete Tech.techs_.BarTech;
|
||||
|
||||
Tech.defaultTechOrder_ = oldDefaultTechOrder;
|
||||
Tech.techs_ = oldTechs;
|
||||
|
||||
});
|
||||
|
||||
QUnit.test('options: plugins', function(assert) {
|
||||
|
@ -27,6 +27,23 @@ QUnit.module('Media Tech', {
|
||||
}
|
||||
});
|
||||
|
||||
QUnit.test('Tech.registerTech and Tech.getTech', function(assert) {
|
||||
const MyTech = extendFn(Tech);
|
||||
const oldTechs = Tech.techs_;
|
||||
const oldDefaultTechOrder = Tech.defaultTechOrder_;
|
||||
|
||||
Tech.registerTech('MyTech', MyTech);
|
||||
|
||||
assert.ok(Tech.techs_.MyTech, 'Tech is stored in the global list');
|
||||
assert.notEqual(Tech.defaultTechOrder_.indexOf('MyTech'), -1, 'Tech is stored in the defaultTechOrder array');
|
||||
assert.strictEqual(Tech.getTech('myTech'), MyTech, 'can get a tech using `camelCase` name');
|
||||
assert.strictEqual(Tech.getTech('MyTech'), MyTech, 'can get a tech using `titleCase` name');
|
||||
|
||||
// reset techs and defaultTechOrder
|
||||
Tech.techs_ = oldTechs;
|
||||
Tech.defaultTechOrder_ = oldDefaultTechOrder;
|
||||
});
|
||||
|
||||
QUnit.test('should synthesize timeupdate events by default', function(assert) {
|
||||
let timeupdates = 0;
|
||||
const tech = new Tech();
|
||||
|
Loading…
x
Reference in New Issue
Block a user