mirror of
https://github.com/videojs/video.js.git
synced 2024-12-25 02:42:10 +02:00
@dmlap switched global options back to an object at videojs.options. closes #2461
This commit is contained in:
parent
4fd59c89db
commit
fecf3a0f8a
@ -93,6 +93,7 @@ CHANGELOG
|
||||
* @misteroneill pass vtt.js option to tech ([view](https://github.com/videojs/video.js/pull/2448))
|
||||
* @forbesjo updated the sauce labs config and browser versions ([view](https://github.com/videojs/video.js/pull/2450))
|
||||
* @mmcc made sure controls respect muted attribute ([view](https://github.com/videojs/video.js/pull/2408))
|
||||
* @dmlap switched global options back to an object at videojs.options ([view](https://github.com/videojs/video.js/pull/2461))
|
||||
|
||||
--------------------
|
||||
|
||||
|
@ -1,54 +0,0 @@
|
||||
/**
|
||||
* @file global-options.js
|
||||
*/
|
||||
import document from 'global/document';
|
||||
import window from 'global/window';
|
||||
let navigator = window.navigator;
|
||||
|
||||
/*
|
||||
* Global Player instance options, surfaced from Player.prototype.options_
|
||||
* options = Player.prototype.options_
|
||||
* All options should use string keys so they avoid
|
||||
* renaming by closure compiler
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
export default {
|
||||
// Default order of fallback technology
|
||||
'techOrder': ['html5','flash'],
|
||||
// techOrder: ['flash','html5'],
|
||||
|
||||
'html5': {},
|
||||
'flash': {},
|
||||
|
||||
// defaultVolume: 0.85,
|
||||
'defaultVolume': 0.00, // The freakin seaguls are driving me crazy!
|
||||
|
||||
// default inactivity timeout
|
||||
'inactivityTimeout': 2000,
|
||||
|
||||
// default playback rates
|
||||
'playbackRates': [],
|
||||
// Add playback rate selection by adding rates
|
||||
// 'playbackRates': [0.5, 1, 1.5, 2],
|
||||
|
||||
// Included control sets
|
||||
'children': {
|
||||
'mediaLoader': {},
|
||||
'posterImage': {},
|
||||
'textTrackDisplay': {},
|
||||
'loadingSpinner': {},
|
||||
'bigPlayButton': {},
|
||||
'controlBar': {},
|
||||
'errorDisplay': {},
|
||||
'textTrackSettings': {}
|
||||
},
|
||||
|
||||
'language': document.getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en',
|
||||
|
||||
// locales and their language translations
|
||||
'languages': {},
|
||||
|
||||
// Default message to show when a video cannot be played.
|
||||
'notSupportedMessage': 'No compatible source was found for this video.'
|
||||
};
|
@ -17,7 +17,6 @@ import { createTimeRange } from './utils/time-ranges.js';
|
||||
import { bufferedPercent } from './utils/buffer.js';
|
||||
import FullscreenApi from './fullscreen-api.js';
|
||||
import MediaError from './media-error.js';
|
||||
import globalOptions from './global-options.js';
|
||||
import safeParseTuple from 'safe-json-parse/tuple';
|
||||
import assign from 'object.assign';
|
||||
import mergeOptions from './utils/merge-options.js';
|
||||
@ -91,7 +90,6 @@ class Player extends Component {
|
||||
// Run base component initializing with new options
|
||||
super(null, options, ready);
|
||||
|
||||
|
||||
// if the global option object was accidentally blown away by
|
||||
// someone, bail early with an informative error
|
||||
if (!this.options_ ||
|
||||
@ -108,7 +106,7 @@ class Player extends Component {
|
||||
this.tagAttributes = tag && Dom.getElAttributes(tag);
|
||||
|
||||
// Update current language
|
||||
this.language(options.language || globalOptions.language);
|
||||
this.language(this.options_.language);
|
||||
|
||||
// Update Supported Languages
|
||||
if (options.languages) {
|
||||
@ -120,7 +118,7 @@ class Player extends Component {
|
||||
});
|
||||
this.languages_ = languagesToLower;
|
||||
} else {
|
||||
this.languages_ = globalOptions.languages;
|
||||
this.languages_ = Player.prototype.options_.languages;
|
||||
}
|
||||
|
||||
// Cache for video property values.
|
||||
@ -151,7 +149,7 @@ class Player extends Component {
|
||||
// as well so they don't need to reach back into the player for options later.
|
||||
// We also need to do another copy of this.options_ so we don't end up with
|
||||
// an infinite loop.
|
||||
let playerOptionsCopy = mergeOptions({}, this.options_);
|
||||
let playerOptionsCopy = mergeOptions(this.options_);
|
||||
|
||||
// Load plugins
|
||||
if (options.plugins) {
|
||||
@ -2403,7 +2401,7 @@ class Player extends Component {
|
||||
* @method languages
|
||||
*/
|
||||
languages() {
|
||||
return mergeOptions(globalOptions.languages, this.languages_);
|
||||
return mergeOptions(Player.prototype.options_.languages, this.languages_);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2488,17 +2486,54 @@ class Player extends Component {
|
||||
*/
|
||||
Player.players = {};
|
||||
|
||||
let navigator = window.navigator;
|
||||
/*
|
||||
* Player instance options, surfaced using options
|
||||
* options = Player.prototype.options_
|
||||
* Make changes in options, not here.
|
||||
* All options should use string keys so they avoid
|
||||
* renaming by closure compiler
|
||||
*
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
Player.prototype.options_ = globalOptions;
|
||||
Player.prototype.options_ = {
|
||||
// Default order of fallback technology
|
||||
techOrder: ['html5','flash'],
|
||||
// techOrder: ['flash','html5'],
|
||||
|
||||
html5: {},
|
||||
flash: {},
|
||||
|
||||
// defaultVolume: 0.85,
|
||||
defaultVolume: 0.00, // The freakin seaguls are driving me crazy!
|
||||
|
||||
// default inactivity timeout
|
||||
inactivityTimeout: 2000,
|
||||
|
||||
// default playback rates
|
||||
playbackRates: [],
|
||||
// Add playback rate selection by adding rates
|
||||
// 'playbackRates': [0.5, 1, 1.5, 2],
|
||||
|
||||
// Included control sets
|
||||
children: {
|
||||
mediaLoader: {},
|
||||
posterImage: {},
|
||||
textTrackDisplay: {},
|
||||
loadingSpinner: {},
|
||||
bigPlayButton: {},
|
||||
controlBar: {},
|
||||
errorDisplay: {},
|
||||
textTrackSettings: {}
|
||||
},
|
||||
|
||||
language: document.getElementsByTagName('html')[0].getAttribute('lang') || navigator.languages && navigator.languages[0] || navigator.userLanguage || navigator.language || 'en',
|
||||
|
||||
// locales and their language translations
|
||||
languages: {},
|
||||
|
||||
// Default message to show when a video cannot be played.
|
||||
notSupportedMessage: 'No compatible source was found for this video.'
|
||||
};
|
||||
|
||||
/**
|
||||
* Fired when the player has initial duration and dimension information
|
||||
|
@ -11,38 +11,50 @@ function isPlain(obj) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge two options objects, recursively merging **only* * plain object
|
||||
* properties. Previously `deepMerge`.
|
||||
* Merge customizer. video.js simply overwrites non-simple objects
|
||||
* (like arrays) instead of attempting to overlay them.
|
||||
* @see https://lodash.com/docs#merge
|
||||
*/
|
||||
const customizer = function(destination, source) {
|
||||
// If we're not working with a plain object, copy the value as is
|
||||
// If source is an array, for instance, it will replace destination
|
||||
if (!isPlain(source)) {
|
||||
return source;
|
||||
}
|
||||
|
||||
// If the new value is a plain object but the first object value is not
|
||||
// we need to create a new object for the first object to merge with.
|
||||
// This makes it consistent with how merge() works by default
|
||||
// and also protects from later changes the to first object affecting
|
||||
// the second object's values.
|
||||
if (!isPlain(destination)) {
|
||||
return mergeOptions(source);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Merge one or more options objects, recursively merging **only**
|
||||
* plain object properties. Previously `deepMerge`.
|
||||
*
|
||||
* @param {Object} object The destination object
|
||||
* @param {...Object} source One or more objects to merge into the first
|
||||
* @returns {Object} The updated first object
|
||||
* @param {...Object} source One or more objects to merge
|
||||
* @returns {Object} a new object that is the union of all
|
||||
* provided objects
|
||||
* @function mergeOptions
|
||||
*/
|
||||
export default function mergeOptions(object={}) {
|
||||
export default function mergeOptions() {
|
||||
// contruct the call dynamically to handle the variable number of
|
||||
// objects to merge
|
||||
let args = Array.prototype.slice.call(arguments);
|
||||
|
||||
// Allow for infinite additional object args to merge
|
||||
Array.prototype.slice.call(arguments, 1).forEach(function(source){
|
||||
// unshift an empty object into the front of the call as the target
|
||||
// of the merge
|
||||
args.unshift({});
|
||||
|
||||
// Recursively merge only plain objects
|
||||
// All other values will be directly copied
|
||||
merge(object, source, function(a, b) {
|
||||
// customize conflict resolution to match our historical merge behavior
|
||||
args.push(customizer);
|
||||
|
||||
// If we're not working with a plain object, copy the value as is
|
||||
if (!isPlain(b)) {
|
||||
return b;
|
||||
}
|
||||
merge.apply(null, args);
|
||||
|
||||
// If the new value is a plain object but the first object value is not
|
||||
// we need to create a new object for the first object to merge with.
|
||||
// This makes it consistent with how merge() works by default
|
||||
// and also protects from later changes the to first object affecting
|
||||
// the second object's values.
|
||||
if (!isPlain(a)) {
|
||||
return mergeOptions({}, b);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return object;
|
||||
// return the mutated result object
|
||||
return args[0];
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import document from 'global/document';
|
||||
import * as setup from './setup';
|
||||
import Component from './component';
|
||||
import EventTarget from './event-target';
|
||||
import globalOptions from './global-options.js';
|
||||
import Player from './player';
|
||||
import plugin from './plugins.js';
|
||||
import mergeOptions from '../../src/js/utils/merge-options.js';
|
||||
@ -62,7 +61,7 @@ var videojs = function(id, options, ready){
|
||||
}
|
||||
|
||||
// If a player instance has already been created for this ID return it.
|
||||
if (Player.players[id]) {
|
||||
if (videojs.getPlayers()[id]) {
|
||||
|
||||
// If options or ready funtion are passed, warn
|
||||
if (options) {
|
||||
@ -70,10 +69,10 @@ var videojs = function(id, options, ready){
|
||||
}
|
||||
|
||||
if (ready) {
|
||||
Player.players[id].ready(ready);
|
||||
videojs.getPlayers()[id].ready(ready);
|
||||
}
|
||||
|
||||
return Player.players[id];
|
||||
return videojs.getPlayers()[id];
|
||||
|
||||
// Otherwise get element for ID
|
||||
} else {
|
||||
@ -107,44 +106,17 @@ setup.autoSetupTimeout(1, videojs);
|
||||
videojs.VERSION = '__VERSION__';
|
||||
|
||||
/**
|
||||
* Get the global options object
|
||||
* The global options object. These are the settings that take effect
|
||||
* if no overrides are specified when the player is created.
|
||||
*
|
||||
* @return {Object} The global options object
|
||||
* @mixes videojs
|
||||
* @method getGlobalOptions
|
||||
*/
|
||||
videojs.getGlobalOptions = () => globalOptions;
|
||||
|
||||
/**
|
||||
* For backward compatibility, expose global options.
|
||||
*
|
||||
* @deprecated
|
||||
* @memberOf videojs
|
||||
* @property {Object|Proxy} options
|
||||
*/
|
||||
videojs.options = createDeprecationProxy(globalOptions, {
|
||||
get: 'Access to videojs.options is deprecated; use videojs.getGlobalOptions instead',
|
||||
set: 'Modification of videojs.options is deprecated; use videojs.setGlobalOptions instead'
|
||||
});
|
||||
|
||||
/**
|
||||
* Set options that will apply to every player
|
||||
* ```js
|
||||
* videojs.setGlobalOptions({
|
||||
* autoplay: true
|
||||
* });
|
||||
* videojs.options.autoplay = true
|
||||
* // -> all players will autoplay by default
|
||||
* ```
|
||||
* NOTE: This will do a deep merge with the new options,
|
||||
* not overwrite the entire global options object.
|
||||
*
|
||||
* @return {Object} The updated global options object
|
||||
* @mixes videojs
|
||||
* @method setGlobalOptions
|
||||
* @type {Object}
|
||||
*/
|
||||
videojs.setGlobalOptions = function(newOptions) {
|
||||
return mergeOptions(globalOptions, newOptions);
|
||||
};
|
||||
videojs.options = Player.prototype.options_;
|
||||
|
||||
/**
|
||||
* Get an object with the currently created players, keyed by player ID
|
||||
@ -377,7 +349,7 @@ videojs.plugin = plugin;
|
||||
*/
|
||||
videojs.addLanguage = function(code, data){
|
||||
code = ('' + code).toLowerCase();
|
||||
return merge(globalOptions.languages, { [code]: data })[code];
|
||||
return merge(videojs.options.languages, { [code]: data })[code];
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1,6 +1,5 @@
|
||||
import Player from '../../src/js/player.js';
|
||||
import videojs from '../../src/js/video.js';
|
||||
import globalOptions from '../../src/js/global-options.js';
|
||||
import * as Dom from '../../src/js/utils/dom.js';
|
||||
import * as browser from '../../src/js/utils/browser.js';
|
||||
import log from '../../src/js/utils/log.js';
|
||||
@ -58,36 +57,36 @@ test('should create player instance that inherits from component and dispose it'
|
||||
ok(player.el() === null, 'element disposed');
|
||||
});
|
||||
|
||||
// technically, all uses of videojs.options should be replaced with
|
||||
// Player.prototype.options_ in this file and a equivalent test using
|
||||
// videojs.options should be made in video.test.js. Keeping this here
|
||||
// until we make that move.
|
||||
test('should accept options from multiple sources and override in correct order', function(){
|
||||
// For closure compiler to work, all reference to the prop have to be the same type
|
||||
// As in options['attr'] or options.attr. Compiler will minimize each separately.
|
||||
// Since we're using setAttribute which requires a string, we have to use the string
|
||||
// version of the key for all version.
|
||||
|
||||
// Set a global option
|
||||
globalOptions['attr'] = 1;
|
||||
videojs.options.attr = 1;
|
||||
|
||||
var tag0 = TestHelpers.makeTag();
|
||||
var player0 = new Player(tag0);
|
||||
let tag0 = TestHelpers.makeTag();
|
||||
let player0 = new Player(tag0);
|
||||
|
||||
ok(player0.options_['attr'] === 1, 'global option was set');
|
||||
equal(player0.options_.attr, 1, 'global option was set');
|
||||
player0.dispose();
|
||||
|
||||
// Set a tag level option
|
||||
var tag1 = TestHelpers.makeTag();
|
||||
tag1.setAttribute('attr', 'asdf'); // Attributes must be set as strings
|
||||
let tag2 = TestHelpers.makeTag();
|
||||
tag2.setAttribute('attr', 'asdf'); // Attributes must be set as strings
|
||||
|
||||
var player1 = new Player(tag1);
|
||||
ok(player1.options_['attr'] === 'asdf', 'Tag options overrode global options');
|
||||
player1.dispose();
|
||||
let player2 = new Player(tag2);
|
||||
equal(player2.options_.attr, 'asdf', 'Tag options overrode global options');
|
||||
player2.dispose();
|
||||
|
||||
// Set a tag level option
|
||||
var tag2 = TestHelpers.makeTag();
|
||||
tag2.setAttribute('attr', 'asdf');
|
||||
let tag3 = TestHelpers.makeTag();
|
||||
tag3.setAttribute('attr', 'asdf');
|
||||
|
||||
var player2 = new Player(tag2, { 'attr': 'fdsa' });
|
||||
ok(player2.options_['attr'] === 'fdsa', 'Init options overrode tag and global options');
|
||||
player2.dispose();
|
||||
let player3 = new Player(tag3, { 'attr': 'fdsa' });
|
||||
equal(player3.options_.attr, 'fdsa', 'Init options overrode tag and global options');
|
||||
player3.dispose();
|
||||
});
|
||||
|
||||
test('should get tag, source, and track settings', function(){
|
||||
@ -739,14 +738,14 @@ test('should be scrubbing while seeking', function(){
|
||||
});
|
||||
|
||||
test('should throw on startup no techs are specified', function() {
|
||||
const techOrder = globalOptions.techOrder;
|
||||
const techOrder = videojs.options.techOrder;
|
||||
|
||||
globalOptions.techOrder = null;
|
||||
videojs.options.techOrder = null;
|
||||
q.throws(function() {
|
||||
videojs(TestHelpers.makeTag());
|
||||
}, 'a falsey techOrder should throw');
|
||||
|
||||
globalOptions.techOrder = techOrder;
|
||||
videojs.options.techOrder = techOrder;
|
||||
});
|
||||
|
||||
test('should have a sensible toJSON that is equivalent to player.options', function() {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import videojs from '../../src/js/video.js';
|
||||
import TestHelpers from './test-helpers.js';
|
||||
import Player from '../../src/js/player.js';
|
||||
import globalOptions from '../../src/js/global-options.js';
|
||||
import log from '../../src/js/utils/log.js';
|
||||
import document from 'global/document';
|
||||
|
||||
@ -25,7 +24,7 @@ test('should return a video player instance', function(){
|
||||
var player = videojs('test_vid_id');
|
||||
ok(player, 'created player from tag');
|
||||
ok(player.id() === 'test_vid_id');
|
||||
ok(Player.players['test_vid_id'] === player, 'added player to global reference');
|
||||
ok(videojs.getPlayers()['test_vid_id'] === player, 'added player to global reference');
|
||||
|
||||
var playerAgain = videojs('test_vid_id');
|
||||
ok(player === playerAgain, 'did not create a second player from same tag');
|
||||
@ -42,9 +41,9 @@ test('should add the value to the languages object', function() {
|
||||
data = {'Hello': 'Hola'};
|
||||
result = videojs.addLanguage(code, data);
|
||||
|
||||
ok(globalOptions.languages[code], 'should exist');
|
||||
equal(globalOptions.languages['es']['Hello'], 'Hola', 'should match');
|
||||
deepEqual(result['Hello'], globalOptions.languages['es']['Hello'], 'should also match');
|
||||
ok(videojs.options.languages[code], 'should exist');
|
||||
equal(videojs.options.languages['es']['Hello'], 'Hola', 'should match');
|
||||
deepEqual(result['Hello'], videojs.options.languages['es']['Hello'], 'should also match');
|
||||
});
|
||||
|
||||
test('should add the value to the languages object with lower case lang code', function() {
|
||||
@ -54,9 +53,9 @@ test('should add the value to the languages object with lower case lang code', f
|
||||
data = {'Hello': 'Guten Tag'};
|
||||
result = videojs.addLanguage(code, data);
|
||||
|
||||
ok(globalOptions['languages'][code.toLowerCase()], 'should exist');
|
||||
equal(globalOptions['languages'][code.toLowerCase()]['Hello'], 'Guten Tag', 'should match');
|
||||
deepEqual(result, globalOptions['languages'][code.toLowerCase()], 'should also match');
|
||||
ok(videojs.options['languages'][code.toLowerCase()], 'should exist');
|
||||
equal(videojs.options['languages'][code.toLowerCase()]['Hello'], 'Guten Tag', 'should match');
|
||||
deepEqual(result, videojs.options['languages'][code.toLowerCase()], 'should also match');
|
||||
});
|
||||
|
||||
test('should expose plugin registry function', function() {
|
||||
|
Loading…
Reference in New Issue
Block a user