mirror of
https://github.com/videojs/video.js.git
synced 2025-02-08 12:05:47 +02:00
refactor(texttracksettings): DRYer code and remove massive HTML blob (#3679)
* DRYer code while keeping tests passing * Replace massive HTML blob with DOM methods * Create obj util and implement it
This commit is contained in:
parent
74cddcad73
commit
fb74c71ba6
@ -1,168 +1,220 @@
|
|||||||
/**
|
/**
|
||||||
* @file text-track-settings.js
|
* @file text-track-settings.js
|
||||||
*/
|
*/
|
||||||
import Component from '../component';
|
|
||||||
import * as Events from '../utils/events.js';
|
|
||||||
import * as Fn from '../utils/fn.js';
|
|
||||||
import log from '../utils/log.js';
|
|
||||||
import safeParseTuple from 'safe-json-parse/tuple';
|
|
||||||
import window from 'global/window';
|
import window from 'global/window';
|
||||||
|
import Component from '../component';
|
||||||
|
import {createEl} from '../utils/dom';
|
||||||
|
import * as Fn from '../utils/fn';
|
||||||
|
import * as Obj from '../utils/obj';
|
||||||
|
import log from '../utils/log';
|
||||||
|
|
||||||
function captionOptionsMenuTemplate(uniqueId, dialogLabelId, dialogDescriptionId) {
|
const LOCAL_STORAGE_KEY = 'vjs-text-track-settings';
|
||||||
const template = `
|
|
||||||
<div role="document">
|
|
||||||
<div role="heading" aria-level="1" id="${dialogLabelId}" class="vjs-control-text">Captions Settings Dialog</div>
|
|
||||||
<div id="${dialogDescriptionId}" class="vjs-control-text">Beginning of dialog window. Escape will cancel and close the window.</div>
|
|
||||||
<div class="vjs-tracksettings">
|
|
||||||
<div class="vjs-tracksettings-colors">
|
|
||||||
<fieldset class="vjs-fg-color vjs-tracksetting">
|
|
||||||
<legend>Text</legend>
|
|
||||||
<label class="vjs-label" for="captions-foreground-color-${uniqueId}">Color</label>
|
|
||||||
<select id="captions-foreground-color-${uniqueId}">
|
|
||||||
<option value="#FFF" selected>White</option>
|
|
||||||
<option value="#000">Black</option>
|
|
||||||
<option value="#F00">Red</option>
|
|
||||||
<option value="#0F0">Green</option>
|
|
||||||
<option value="#00F">Blue</option>
|
|
||||||
<option value="#FF0">Yellow</option>
|
|
||||||
<option value="#F0F">Magenta</option>
|
|
||||||
<option value="#0FF">Cyan</option>
|
|
||||||
</select>
|
|
||||||
<span class="vjs-text-opacity vjs-opacity">
|
|
||||||
<label class="vjs-label" for="captions-foreground-opacity-${uniqueId}">Transparency</label>
|
|
||||||
<select id="captions-foreground-opacity-${uniqueId}">
|
|
||||||
<option value="1" selected>Opaque</option>
|
|
||||||
<option value="0.5">Semi-Opaque</option>
|
|
||||||
</select>
|
|
||||||
</span>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset class="vjs-bg-color vjs-tracksetting">
|
|
||||||
<legend>Background</legend>
|
|
||||||
<label class="vjs-label" for="captions-background-color-${uniqueId}">Color</label>
|
|
||||||
<select id="captions-background-color-${uniqueId}">
|
|
||||||
<option value="#000" selected>Black</option>
|
|
||||||
<option value="#FFF">White</option>
|
|
||||||
<option value="#F00">Red</option>
|
|
||||||
<option value="#0F0">Green</option>
|
|
||||||
<option value="#00F">Blue</option>
|
|
||||||
<option value="#FF0">Yellow</option>
|
|
||||||
<option value="#F0F">Magenta</option>
|
|
||||||
<option value="#0FF">Cyan</option>
|
|
||||||
</select>
|
|
||||||
<span class="vjs-bg-opacity vjs-opacity">
|
|
||||||
<label class="vjs-label" for="captions-background-opacity-${uniqueId}">Transparency</label>
|
|
||||||
<select id="captions-background-opacity-${uniqueId}">
|
|
||||||
<option value="1" selected>Opaque</option>
|
|
||||||
<option value="0.5">Semi-Transparent</option>
|
|
||||||
<option value="0">Transparent</option>
|
|
||||||
</select>
|
|
||||||
</span>
|
|
||||||
</fieldset>
|
|
||||||
<fieldset class="window-color vjs-tracksetting">
|
|
||||||
<legend>Window</legend>
|
|
||||||
<label class="vjs-label" for="captions-window-color-${uniqueId}">Color</label>
|
|
||||||
<select id="captions-window-color-${uniqueId}">
|
|
||||||
<option value="#000" selected>Black</option>
|
|
||||||
<option value="#FFF">White</option>
|
|
||||||
<option value="#F00">Red</option>
|
|
||||||
<option value="#0F0">Green</option>
|
|
||||||
<option value="#00F">Blue</option>
|
|
||||||
<option value="#FF0">Yellow</option>
|
|
||||||
<option value="#F0F">Magenta</option>
|
|
||||||
<option value="#0FF">Cyan</option>
|
|
||||||
</select>
|
|
||||||
<span class="vjs-window-opacity vjs-opacity">
|
|
||||||
<label class="vjs-label" for="captions-window-opacity-${uniqueId}">Transparency</label>
|
|
||||||
<select id="captions-window-opacity-${uniqueId}">
|
|
||||||
<option value="0" selected>Transparent</option>
|
|
||||||
<option value="0.5">Semi-Transparent</option>
|
|
||||||
<option value="1">Opaque</option>
|
|
||||||
</select>
|
|
||||||
</span>
|
|
||||||
</fieldset>
|
|
||||||
</div> <!-- vjs-tracksettings-colors -->
|
|
||||||
<div class="vjs-tracksettings-font">
|
|
||||||
<div class="vjs-font-percent vjs-tracksetting">
|
|
||||||
<label class="vjs-label" for="captions-font-size-${uniqueId}">Font Size</label>
|
|
||||||
<select id="captions-font-size-${uniqueId}">
|
|
||||||
<option value="0.50">50%</option>
|
|
||||||
<option value="0.75">75%</option>
|
|
||||||
<option value="1.00" selected>100%</option>
|
|
||||||
<option value="1.25">125%</option>
|
|
||||||
<option value="1.50">150%</option>
|
|
||||||
<option value="1.75">175%</option>
|
|
||||||
<option value="2.00">200%</option>
|
|
||||||
<option value="3.00">300%</option>
|
|
||||||
<option value="4.00">400%</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="vjs-edge-style vjs-tracksetting">
|
|
||||||
<label class="vjs-label" for="captions-edge-style-${uniqueId}">Text Edge Style</label>
|
|
||||||
<select id="captions-edge-style-${uniqueId}">
|
|
||||||
<option value="none" selected>None</option>
|
|
||||||
<option value="raised">Raised</option>
|
|
||||||
<option value="depressed">Depressed</option>
|
|
||||||
<option value="uniform">Uniform</option>
|
|
||||||
<option value="dropshadow">Dropshadow</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="vjs-font-family vjs-tracksetting">
|
|
||||||
<label class="vjs-label" for="captions-font-family-${uniqueId}">Font Family</label>
|
|
||||||
<select id="captions-font-family-${uniqueId}">
|
|
||||||
<option value="proportionalSansSerif" selected>Proportional Sans-Serif</option>
|
|
||||||
<option value="monospaceSansSerif">Monospace Sans-Serif</option>
|
|
||||||
<option value="proportionalSerif">Proportional Serif</option>
|
|
||||||
<option value="monospaceSerif">Monospace Serif</option>
|
|
||||||
<option value="casual">Casual</option>
|
|
||||||
<option value="script">Script</option>
|
|
||||||
<option value="small-caps">Small Caps</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div> <!-- vjs-tracksettings-font -->
|
|
||||||
<div class="vjs-tracksettings-controls">
|
|
||||||
<button class="vjs-default-button">Defaults</button>
|
|
||||||
<button class="vjs-done-button">Done</button>
|
|
||||||
</div>
|
|
||||||
</div> <!-- vjs-tracksettings -->
|
|
||||||
</div> <!-- role="document" -->
|
|
||||||
`;
|
|
||||||
|
|
||||||
return template;
|
const COLOR_BLACK = ['#000', 'Black'];
|
||||||
}
|
const COLOR_BLUE = ['#00F', 'Blue'];
|
||||||
|
const COLOR_CYAN = ['#0FF', 'Cyan'];
|
||||||
|
const COLOR_GREEN = ['#0F0', 'Green'];
|
||||||
|
const COLOR_MAGENTA = ['#F0F', 'Magenta'];
|
||||||
|
const COLOR_RED = ['#F00', 'Red'];
|
||||||
|
const COLOR_WHITE = ['#FFF', 'White'];
|
||||||
|
const COLOR_YELLOW = ['#FF0', 'Yellow'];
|
||||||
|
|
||||||
function getSelectedOptionValue(target) {
|
const OPACITY_OPAQUE = ['1', 'Opaque'];
|
||||||
let selectedOption;
|
const OPACITY_SEMI = ['0.5', 'Semi-Transparent'];
|
||||||
|
const OPACITY_TRANS = ['0', 'Transparent'];
|
||||||
|
|
||||||
// not all browsers support selectedOptions, so, fallback to options
|
// Configuration for the various <select> elements in the DOM of this component.
|
||||||
if (target.selectedOptions) {
|
//
|
||||||
selectedOption = target.selectedOptions[0];
|
// Possible keys include:
|
||||||
} else if (target.options) {
|
//
|
||||||
selectedOption = target.options[target.options.selectedIndex];
|
// `default`:
|
||||||
|
// The default option index. Only needs to be provided if not zero.
|
||||||
|
// `parser`:
|
||||||
|
// A function which is used to parse the value from the selected option in
|
||||||
|
// a customized way.
|
||||||
|
// `selector`:
|
||||||
|
// The selector used to find the associated <select> element.
|
||||||
|
const selectConfigs = {
|
||||||
|
backgroundColor: {
|
||||||
|
selector: '.vjs-bg-color > select',
|
||||||
|
id: 'captions-background-color-%s',
|
||||||
|
label: 'Color',
|
||||||
|
options: [
|
||||||
|
COLOR_BLACK,
|
||||||
|
COLOR_WHITE,
|
||||||
|
COLOR_RED,
|
||||||
|
COLOR_GREEN,
|
||||||
|
COLOR_BLUE,
|
||||||
|
COLOR_YELLOW,
|
||||||
|
COLOR_MAGENTA,
|
||||||
|
COLOR_CYAN
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
backgroundOpacity: {
|
||||||
|
selector: '.vjs-bg-opacity > select',
|
||||||
|
id: 'captions-background-opacity-%s',
|
||||||
|
label: 'Transparency',
|
||||||
|
options: [
|
||||||
|
OPACITY_OPAQUE,
|
||||||
|
OPACITY_SEMI,
|
||||||
|
OPACITY_TRANS
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
color: {
|
||||||
|
selector: '.vjs-fg-color > select',
|
||||||
|
id: 'captions-foreground-color-%s',
|
||||||
|
label: 'Color',
|
||||||
|
options: [
|
||||||
|
COLOR_WHITE,
|
||||||
|
COLOR_BLACK,
|
||||||
|
COLOR_RED,
|
||||||
|
COLOR_GREEN,
|
||||||
|
COLOR_BLUE,
|
||||||
|
COLOR_YELLOW,
|
||||||
|
COLOR_MAGENTA,
|
||||||
|
COLOR_CYAN
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
edgeStyle: {
|
||||||
|
selector: '.vjs-edge-style > select',
|
||||||
|
id: '%s',
|
||||||
|
label: 'Text Edge Style',
|
||||||
|
options: [
|
||||||
|
['none', 'None'],
|
||||||
|
['raised', 'Raised'],
|
||||||
|
['depressed', 'Depressed'],
|
||||||
|
['uniform', 'Uniform'],
|
||||||
|
['dropshadow', 'Dropshadow']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
fontFamily: {
|
||||||
|
selector: '.vjs-font-family > select',
|
||||||
|
id: 'captions-font-family-%s',
|
||||||
|
label: 'Font Family',
|
||||||
|
options: [
|
||||||
|
['proportionalSansSerif', 'Proportional Sans-Serif'],
|
||||||
|
['monospaceSansSerif', 'Monospace Sans-Serif'],
|
||||||
|
['proportionalSerif', 'Proportional Serif'],
|
||||||
|
['monospaceSerif', 'Monospace Serif'],
|
||||||
|
['casual', 'Casual'],
|
||||||
|
['script', 'Script'],
|
||||||
|
['small-caps', 'Small Caps']
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
fontPercent: {
|
||||||
|
selector: '.vjs-font-percent > select',
|
||||||
|
id: 'captions-font-size-%s',
|
||||||
|
label: 'Font Size',
|
||||||
|
options: [
|
||||||
|
['0.50', '50%'],
|
||||||
|
['0.75', '75%'],
|
||||||
|
['1.00', '100%'],
|
||||||
|
['1.25', '125%'],
|
||||||
|
['1.50', '150%'],
|
||||||
|
['1.75', '175%'],
|
||||||
|
['2.00', '200%'],
|
||||||
|
['3.00', '300%'],
|
||||||
|
['4.00', '400%']
|
||||||
|
],
|
||||||
|
default: 2,
|
||||||
|
parser: (v) => v === '1.00' ? null : Number(v)
|
||||||
|
},
|
||||||
|
|
||||||
|
textOpacity: {
|
||||||
|
selector: '.vjs-text-opacity > select',
|
||||||
|
id: 'captions-foreground-opacity-%s',
|
||||||
|
label: 'Transparency',
|
||||||
|
options: [
|
||||||
|
OPACITY_OPAQUE,
|
||||||
|
OPACITY_SEMI
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
// Options for this object are defined below.
|
||||||
|
windowColor: {
|
||||||
|
selector: '.vjs-window-color > select',
|
||||||
|
id: 'captions-window-color-%s',
|
||||||
|
label: 'Color'
|
||||||
|
},
|
||||||
|
|
||||||
|
// Options for this object are defined below.
|
||||||
|
windowOpacity: {
|
||||||
|
selector: '.vjs-window-opacity > select',
|
||||||
|
id: 'captions-window-opacity-%s',
|
||||||
|
label: 'Transparency',
|
||||||
|
options: [
|
||||||
|
OPACITY_TRANS,
|
||||||
|
OPACITY_SEMI,
|
||||||
|
OPACITY_OPAQUE
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
selectConfigs.windowColor.options = selectConfigs.backgroundColor.options;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses out option values.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @param {String} value
|
||||||
|
* @param {Function} [parser]
|
||||||
|
* Optional function to adjust the value.
|
||||||
|
* @return {Mixed}
|
||||||
|
* Will be `undefined` if no value exists (or if given value is "none").
|
||||||
|
*/
|
||||||
|
function parseOptionValue(value, parser) {
|
||||||
|
if (parser) {
|
||||||
|
value = parser(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return selectedOption.value;
|
if (value && value !== 'none') {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setSelectedOption(target, value) {
|
/**
|
||||||
|
* Gets the value of the selected <option> element within a <select> element.
|
||||||
|
*
|
||||||
|
* @param {Object} config
|
||||||
|
* @param {Function} [parser]
|
||||||
|
* Optional function to adjust the value.
|
||||||
|
* @return {Mixed}
|
||||||
|
*/
|
||||||
|
function getSelectedOptionValue(el, parser) {
|
||||||
|
const value = el.options[el.options.selectedIndex].value;
|
||||||
|
|
||||||
|
return parseOptionValue(value, parser);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the selected <option> element within a <select> element based on a
|
||||||
|
* given value.
|
||||||
|
*
|
||||||
|
* @param {Object} el
|
||||||
|
* @param {String} value
|
||||||
|
* @param {Function} [parser]
|
||||||
|
* Optional function to adjust the value before comparing.
|
||||||
|
*/
|
||||||
|
function setSelectedOption(el, value, parser) {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let i;
|
for (let i = 0; i < el.options.length; i++) {
|
||||||
|
if (parseOptionValue(el.options[i].value, parser) === value) {
|
||||||
for (i = 0; i < target.options.length; i++) {
|
el.selectedIndex = i;
|
||||||
const option = target.options[i];
|
|
||||||
|
|
||||||
if (option.value === value) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
target.selectedIndex = i;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manipulate settings of texttracks
|
* Manipulate settings of text tracks
|
||||||
*
|
*
|
||||||
* @param {Object} player Main Player
|
* @param {Object} player Main Player
|
||||||
* @param {Object=} options Object of option names and values
|
* @param {Object=} options Object of option names and values
|
||||||
@ -173,46 +225,196 @@ class TextTrackSettings extends Component {
|
|||||||
|
|
||||||
constructor(player, options) {
|
constructor(player, options) {
|
||||||
super(player, options);
|
super(player, options);
|
||||||
|
this.setDefaults();
|
||||||
this.hide();
|
this.hide();
|
||||||
|
|
||||||
|
this.updateDisplay = Fn.bind(this, this.updateDisplay);
|
||||||
|
|
||||||
// Grab `persistTextTrackSettings` from the player options if not passed in child options
|
// Grab `persistTextTrackSettings` from the player options if not passed in child options
|
||||||
if (options.persistTextTrackSettings === undefined) {
|
if (options.persistTextTrackSettings === undefined) {
|
||||||
this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
|
this.options_.persistTextTrackSettings = this.options_.playerOptions.persistTextTrackSettings;
|
||||||
}
|
}
|
||||||
|
|
||||||
Events.on(this.$('.vjs-done-button'), 'click', Fn.bind(this, function() {
|
this.on(this.$('.vjs-done-button'), 'click', () => {
|
||||||
this.saveSettings();
|
this.saveSettings();
|
||||||
this.hide();
|
this.hide();
|
||||||
}));
|
});
|
||||||
|
|
||||||
Events.on(this.$('.vjs-default-button'), 'click', Fn.bind(this, function() {
|
this.on(this.$('.vjs-default-button'), 'click', () => {
|
||||||
this.$('.vjs-fg-color > select').selectedIndex = 0;
|
this.setDefaults();
|
||||||
this.$('.vjs-bg-color > select').selectedIndex = 0;
|
|
||||||
this.$('.window-color > select').selectedIndex = 0;
|
|
||||||
this.$('.vjs-text-opacity > select').selectedIndex = 0;
|
|
||||||
this.$('.vjs-bg-opacity > select').selectedIndex = 0;
|
|
||||||
this.$('.vjs-window-opacity > select').selectedIndex = 0;
|
|
||||||
this.$('.vjs-edge-style select').selectedIndex = 0;
|
|
||||||
this.$('.vjs-font-family select').selectedIndex = 0;
|
|
||||||
this.$('.vjs-font-percent select').selectedIndex = 2;
|
|
||||||
this.updateDisplay();
|
this.updateDisplay();
|
||||||
}));
|
});
|
||||||
|
|
||||||
Events.on(this.$('.vjs-fg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
|
Obj.each(selectConfigs, config => {
|
||||||
Events.on(this.$('.vjs-bg-color > select'), 'change', Fn.bind(this, this.updateDisplay));
|
this.on(this.$(config.selector), 'change', this.updateDisplay);
|
||||||
Events.on(this.$('.window-color > select'), 'change', Fn.bind(this, this.updateDisplay));
|
});
|
||||||
Events.on(this.$('.vjs-text-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
|
|
||||||
Events.on(this.$('.vjs-bg-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
|
|
||||||
Events.on(this.$('.vjs-window-opacity > select'), 'change', Fn.bind(this, this.updateDisplay));
|
|
||||||
Events.on(this.$('.vjs-font-percent select'), 'change', Fn.bind(this, this.updateDisplay));
|
|
||||||
Events.on(this.$('.vjs-edge-style select'), 'change', Fn.bind(this, this.updateDisplay));
|
|
||||||
Events.on(this.$('.vjs-font-family select'), 'change', Fn.bind(this, this.updateDisplay));
|
|
||||||
|
|
||||||
if (this.options_.persistTextTrackSettings) {
|
if (this.options_.persistTextTrackSettings) {
|
||||||
this.restoreSettings();
|
this.restoreSettings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a <select> element with configured options.
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Element}
|
||||||
|
* @method createElSelect_
|
||||||
|
*/
|
||||||
|
createElSelect_(key) {
|
||||||
|
const config = selectConfigs[key];
|
||||||
|
const id = config.id.replace('%s', this.id_);
|
||||||
|
|
||||||
|
return [
|
||||||
|
createEl('label', {
|
||||||
|
className: 'vjs-label',
|
||||||
|
textContent: config.label
|
||||||
|
}, {
|
||||||
|
for: id
|
||||||
|
}),
|
||||||
|
createEl('select', {id}, undefined, config.options.map(o => {
|
||||||
|
return createEl('option', {
|
||||||
|
textContent: this.localize(o[1]),
|
||||||
|
value: o[0]
|
||||||
|
});
|
||||||
|
}))
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create foreground color element for the component
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Element}
|
||||||
|
* @method createElFgColor_
|
||||||
|
*/
|
||||||
|
createElFgColor_() {
|
||||||
|
const legend = createEl('legend', {
|
||||||
|
textContent: this.localize('Text')
|
||||||
|
});
|
||||||
|
|
||||||
|
const select = this.createElSelect_('color');
|
||||||
|
|
||||||
|
const opacity = createEl('span', {
|
||||||
|
className: 'vjs-text-opacity vjs-opacity'
|
||||||
|
}, undefined, this.createElSelect_('textOpacity'));
|
||||||
|
|
||||||
|
return createEl('fieldset', {
|
||||||
|
className: 'vjs-fg-color vjs-tracksetting'
|
||||||
|
}, undefined, [legend].concat(select, opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create background color element for the component
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Element}
|
||||||
|
* @method createElBgColor_
|
||||||
|
*/
|
||||||
|
createElBgColor_() {
|
||||||
|
const legend = createEl('legend', {
|
||||||
|
textContent: this.localize('Background')
|
||||||
|
});
|
||||||
|
|
||||||
|
const select = this.createElSelect_('backgroundColor');
|
||||||
|
|
||||||
|
const opacity = createEl('span', {
|
||||||
|
className: 'vjs-bg-opacity vjs-opacity'
|
||||||
|
}, undefined, this.createElSelect_('backgroundOpacity'));
|
||||||
|
|
||||||
|
return createEl('fieldset', {
|
||||||
|
className: 'vjs-bg-color vjs-tracksetting'
|
||||||
|
}, undefined, [legend].concat(select, opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create window color element for the component
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Element}
|
||||||
|
* @method createElWinColor_
|
||||||
|
*/
|
||||||
|
createElWinColor_() {
|
||||||
|
const legend = createEl('legend', {
|
||||||
|
textContent: this.localize('Window')
|
||||||
|
});
|
||||||
|
|
||||||
|
const select = this.createElSelect_('windowColor');
|
||||||
|
|
||||||
|
const opacity = createEl('span', {
|
||||||
|
className: 'vjs-window-opacity vjs-opacity'
|
||||||
|
}, undefined, this.createElSelect_('windowOpacity'));
|
||||||
|
|
||||||
|
return createEl('fieldset', {
|
||||||
|
className: 'vjs-window-color vjs-tracksetting'
|
||||||
|
}, undefined, [legend].concat(select, opacity));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create color elements for the component
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Element}
|
||||||
|
* @method createElColors_
|
||||||
|
*/
|
||||||
|
createElColors_() {
|
||||||
|
return createEl('div', {
|
||||||
|
className: 'vjs-tracksettings-colors'
|
||||||
|
}, undefined, [
|
||||||
|
this.createElFgColor_(),
|
||||||
|
this.createElBgColor_(),
|
||||||
|
this.createElWinColor_()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create font elements for the component
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Element}
|
||||||
|
* @method createElFont_
|
||||||
|
*/
|
||||||
|
createElFont_() {
|
||||||
|
const fontPercent = createEl('div', {
|
||||||
|
className: 'vjs-font-percent vjs-tracksetting'
|
||||||
|
}, undefined, this.createElSelect_('fontPercent'));
|
||||||
|
|
||||||
|
const edgeStyle = createEl('div', {
|
||||||
|
className: 'vjs-edge-style vjs-tracksetting'
|
||||||
|
}, undefined, this.createElSelect_('edgeStyle'));
|
||||||
|
|
||||||
|
const fontFamily = createEl('div', {
|
||||||
|
className: 'vjs-font-family vjs-tracksetting'
|
||||||
|
}, undefined, this.createElSelect_('fontFamily'));
|
||||||
|
|
||||||
|
return createEl('div', {
|
||||||
|
className: 'vjs-tracksettings-font'
|
||||||
|
}, undefined, [fontPercent, edgeStyle, fontFamily]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create controls for the component
|
||||||
|
*
|
||||||
|
* @private
|
||||||
|
* @return {Element}
|
||||||
|
* @method createElControls_
|
||||||
|
*/
|
||||||
|
createElControls_() {
|
||||||
|
const defaultsButton = createEl('button', {
|
||||||
|
className: 'vjs-default-button',
|
||||||
|
textContent: this.localize('Defaults')
|
||||||
|
});
|
||||||
|
|
||||||
|
const doneButton = createEl('button', {
|
||||||
|
className: 'vjs-done-button',
|
||||||
|
textContent: 'Done'
|
||||||
|
});
|
||||||
|
|
||||||
|
return createEl('div', {
|
||||||
|
className: 'vjs-tracksettings-controls'
|
||||||
|
}, undefined, [defaultsButton, doneButton]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create the component's DOM element
|
* Create the component's DOM element
|
||||||
*
|
*
|
||||||
@ -220,99 +422,86 @@ class TextTrackSettings extends Component {
|
|||||||
* @method createEl
|
* @method createEl
|
||||||
*/
|
*/
|
||||||
createEl() {
|
createEl() {
|
||||||
const uniqueId = this.id_;
|
const settings = createEl('div', {
|
||||||
const dialogLabelId = 'TTsettingsDialogLabel-' + uniqueId;
|
className: 'vjs-tracksettings'
|
||||||
const dialogDescriptionId = 'TTsettingsDialogDescription-' + uniqueId;
|
}, undefined, [
|
||||||
|
this.createElColors_(),
|
||||||
|
this.createElFont_(),
|
||||||
|
this.createElControls_()
|
||||||
|
]);
|
||||||
|
|
||||||
return super.createEl('div', {
|
const heading = createEl('div', {
|
||||||
|
className: 'vjs-control-text',
|
||||||
|
id: `TTsettingsDialogLabel-${this.id_}`,
|
||||||
|
textContent: 'Caption Settings Dialog'
|
||||||
|
}, {
|
||||||
|
'aria-level': '1',
|
||||||
|
'role': 'heading'
|
||||||
|
});
|
||||||
|
|
||||||
|
const description = createEl('div', {
|
||||||
|
className: 'vjs-control-text',
|
||||||
|
id: `TTsettingsDialogDescription-${this.id_}`,
|
||||||
|
textContent: 'Beginning of dialog window. Escape will cancel and close the window.'
|
||||||
|
});
|
||||||
|
|
||||||
|
const doc = createEl('div', undefined, {
|
||||||
|
role: 'document'
|
||||||
|
}, [heading, description, settings]);
|
||||||
|
|
||||||
|
return createEl('div', {
|
||||||
className: 'vjs-caption-settings vjs-modal-overlay',
|
className: 'vjs-caption-settings vjs-modal-overlay',
|
||||||
innerHTML: captionOptionsMenuTemplate(uniqueId, dialogLabelId, dialogDescriptionId),
|
|
||||||
tabIndex: -1
|
tabIndex: -1
|
||||||
}, {
|
}, {
|
||||||
'role': 'dialog',
|
'role': 'dialog',
|
||||||
'aria-labelledby': dialogLabelId,
|
'aria-labelledby': heading.id,
|
||||||
'aria-describedby': dialogDescriptionId
|
'aria-describedby': description.id
|
||||||
|
}, doc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an object of text track settings (or null).
|
||||||
|
*
|
||||||
|
* @return {Object}
|
||||||
|
* An object with config values parsed from the DOM or localStorage.
|
||||||
|
* @method getValues
|
||||||
|
*/
|
||||||
|
getValues() {
|
||||||
|
return Obj.reduce(selectConfigs, (accum, config, key) => {
|
||||||
|
const value = getSelectedOptionValue(this.$(config.selector), config.parser);
|
||||||
|
|
||||||
|
if (value !== undefined) {
|
||||||
|
accum[key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return accum;
|
||||||
|
}, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets text track settings from an object of values.
|
||||||
|
*
|
||||||
|
* @param {Object} values
|
||||||
|
* An object with config values parsed from the DOM or localStorage.
|
||||||
|
* @method setValues
|
||||||
|
*/
|
||||||
|
setValues(values) {
|
||||||
|
Obj.each(selectConfigs, (config, key) => {
|
||||||
|
setSelectedOption(this.$(config.selector), values[key], config.parser);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get texttrack settings
|
* Sets all <select> elements to their default values.
|
||||||
* Settings are
|
|
||||||
* .vjs-edge-style
|
|
||||||
* .vjs-font-family
|
|
||||||
* .vjs-fg-color
|
|
||||||
* .vjs-text-opacity
|
|
||||||
* .vjs-bg-color
|
|
||||||
* .vjs-bg-opacity
|
|
||||||
* .window-color
|
|
||||||
* .vjs-window-opacity
|
|
||||||
*
|
*
|
||||||
* @return {Object}
|
* @method setDefaults
|
||||||
* @method getValues
|
|
||||||
*/
|
*/
|
||||||
getValues() {
|
setDefaults() {
|
||||||
const textEdge = getSelectedOptionValue(this.$('.vjs-edge-style select'));
|
Obj.each(selectConfigs, (config) => {
|
||||||
const fontFamily = getSelectedOptionValue(this.$('.vjs-font-family select'));
|
const index = config.hasOwnProperty('default') ? config.default : 0;
|
||||||
const fgColor = getSelectedOptionValue(this.$('.vjs-fg-color > select'));
|
|
||||||
const textOpacity = getSelectedOptionValue(this.$('.vjs-text-opacity > select'));
|
|
||||||
const bgColor = getSelectedOptionValue(this.$('.vjs-bg-color > select'));
|
|
||||||
const bgOpacity = getSelectedOptionValue(this.$('.vjs-bg-opacity > select'));
|
|
||||||
const windowColor = getSelectedOptionValue(this.$('.window-color > select'));
|
|
||||||
const windowOpacity = getSelectedOptionValue(this.$('.vjs-window-opacity > select'));
|
|
||||||
const fontPercent = window.parseFloat(getSelectedOptionValue(this.$('.vjs-font-percent > select')));
|
|
||||||
|
|
||||||
const result = {
|
this.$(config.selector).selectedIndex = index;
|
||||||
fontPercent,
|
});
|
||||||
fontFamily,
|
|
||||||
textOpacity,
|
|
||||||
windowColor,
|
|
||||||
windowOpacity,
|
|
||||||
backgroundOpacity: bgOpacity,
|
|
||||||
edgeStyle: textEdge,
|
|
||||||
color: fgColor,
|
|
||||||
backgroundColor: bgColor
|
|
||||||
};
|
|
||||||
|
|
||||||
for (const name in result) {
|
|
||||||
if (result[name] === '' || result[name] === 'none' || (name === 'fontPercent' && result[name] === 1.00)) {
|
|
||||||
delete result[name];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set texttrack settings
|
|
||||||
* Settings are
|
|
||||||
* .vjs-edge-style
|
|
||||||
* .vjs-font-family
|
|
||||||
* .vjs-fg-color
|
|
||||||
* .vjs-text-opacity
|
|
||||||
* .vjs-bg-color
|
|
||||||
* .vjs-bg-opacity
|
|
||||||
* .window-color
|
|
||||||
* .vjs-window-opacity
|
|
||||||
*
|
|
||||||
* @param {Object} values Object with texttrack setting values
|
|
||||||
* @method setValues
|
|
||||||
*/
|
|
||||||
setValues(values) {
|
|
||||||
setSelectedOption(this.$('.vjs-edge-style select'), values.edgeStyle);
|
|
||||||
setSelectedOption(this.$('.vjs-font-family select'), values.fontFamily);
|
|
||||||
setSelectedOption(this.$('.vjs-fg-color > select'), values.color);
|
|
||||||
setSelectedOption(this.$('.vjs-text-opacity > select'), values.textOpacity);
|
|
||||||
setSelectedOption(this.$('.vjs-bg-color > select'), values.backgroundColor);
|
|
||||||
setSelectedOption(this.$('.vjs-bg-opacity > select'), values.backgroundOpacity);
|
|
||||||
setSelectedOption(this.$('.window-color > select'), values.windowColor);
|
|
||||||
setSelectedOption(this.$('.vjs-window-opacity > select'), values.windowOpacity);
|
|
||||||
|
|
||||||
let fontPercent = values.fontPercent;
|
|
||||||
|
|
||||||
if (fontPercent) {
|
|
||||||
fontPercent = fontPercent.toFixed(2);
|
|
||||||
}
|
|
||||||
|
|
||||||
setSelectedOption(this.$('.vjs-font-percent > select'), fontPercent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -321,17 +510,12 @@ class TextTrackSettings extends Component {
|
|||||||
* @method restoreSettings
|
* @method restoreSettings
|
||||||
*/
|
*/
|
||||||
restoreSettings() {
|
restoreSettings() {
|
||||||
let err;
|
|
||||||
let values;
|
let values;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
[err, values] = safeParseTuple(window.localStorage.getItem('vjs-text-track-settings'));
|
values = JSON.parse(window.localStorage.getItem(LOCAL_STORAGE_KEY));
|
||||||
|
} catch (err) {
|
||||||
if (err) {
|
log.warn(err);
|
||||||
log.error(err);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
log.warn(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (values) {
|
if (values) {
|
||||||
@ -340,7 +524,7 @@ class TextTrackSettings extends Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save texttrack settings to local storage
|
* Save text track settings to local storage
|
||||||
*
|
*
|
||||||
* @method saveSettings
|
* @method saveSettings
|
||||||
*/
|
*/
|
||||||
@ -352,18 +536,18 @@ class TextTrackSettings extends Component {
|
|||||||
const values = this.getValues();
|
const values = this.getValues();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (Object.getOwnPropertyNames(values).length > 0) {
|
if (Object.keys(values).length) {
|
||||||
window.localStorage.setItem('vjs-text-track-settings', JSON.stringify(values));
|
window.localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(values));
|
||||||
} else {
|
} else {
|
||||||
window.localStorage.removeItem('vjs-text-track-settings');
|
window.localStorage.removeItem(LOCAL_STORAGE_KEY);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (err) {
|
||||||
log.warn(e);
|
log.warn(err);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update display of texttrack settings
|
* Update display of text track settings
|
||||||
*
|
*
|
||||||
* @method updateDisplay
|
* @method updateDisplay
|
||||||
*/
|
*/
|
||||||
|
@ -96,10 +96,11 @@ export function getEl(id) {
|
|||||||
* @param {String} [tagName='div'] Name of tag to be created.
|
* @param {String} [tagName='div'] Name of tag to be created.
|
||||||
* @param {Object} [properties={}] Element properties to be applied.
|
* @param {Object} [properties={}] Element properties to be applied.
|
||||||
* @param {Object} [attributes={}] Element attributes to be applied.
|
* @param {Object} [attributes={}] Element attributes to be applied.
|
||||||
|
* @param {String|Element|TextNode|Array|Function} [content] Contents for the element (see: `normalizeContent`)
|
||||||
* @return {Element}
|
* @return {Element}
|
||||||
* @function createEl
|
* @function createEl
|
||||||
*/
|
*/
|
||||||
export function createEl(tagName = 'div', properties = {}, attributes = {}) {
|
export function createEl(tagName = 'div', properties = {}, attributes = {}, content) {
|
||||||
const el = document.createElement(tagName);
|
const el = document.createElement(tagName);
|
||||||
|
|
||||||
Object.getOwnPropertyNames(properties).forEach(function(propName) {
|
Object.getOwnPropertyNames(properties).forEach(function(propName) {
|
||||||
@ -113,6 +114,11 @@ export function createEl(tagName = 'div', properties = {}, attributes = {}) {
|
|||||||
has been deprecated. Use the third argument instead.
|
has been deprecated. Use the third argument instead.
|
||||||
createEl(type, properties, attributes). Attempting to set ${propName} to ${val}.`);
|
createEl(type, properties, attributes). Attempting to set ${propName} to ${val}.`);
|
||||||
el.setAttribute(propName, val);
|
el.setAttribute(propName, val);
|
||||||
|
|
||||||
|
// Handle textContent since it's not supported everywhere and we have a
|
||||||
|
// method for it.
|
||||||
|
} else if (propName === 'textContent') {
|
||||||
|
textContent(el, val);
|
||||||
} else {
|
} else {
|
||||||
el[propName] = val;
|
el[propName] = val;
|
||||||
}
|
}
|
||||||
@ -122,6 +128,10 @@ export function createEl(tagName = 'div', properties = {}, attributes = {}) {
|
|||||||
el.setAttribute(attrName, attributes[attrName]);
|
el.setAttribute(attrName, attributes[attrName]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
appendContent(el, content);
|
||||||
|
}
|
||||||
|
|
||||||
return el;
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +149,7 @@ export function textContent(el, text) {
|
|||||||
} else {
|
} else {
|
||||||
el.textContent = text;
|
el.textContent = text;
|
||||||
}
|
}
|
||||||
|
return el;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
32
src/js/utils/obj.js
Normal file
32
src/js/utils/obj.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/**
|
||||||
|
* @file obj.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array-like iteration for objects.
|
||||||
|
*
|
||||||
|
* @param {Object} object
|
||||||
|
* @param {Function} fn
|
||||||
|
* A callback function which is called for each key in the object. It
|
||||||
|
* receives the value and key as arguments.
|
||||||
|
*/
|
||||||
|
export function each(object, fn) {
|
||||||
|
Object.keys(object).forEach(key => fn(object[key], key));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array-like reduce for objects.
|
||||||
|
*
|
||||||
|
* @param {Object} object
|
||||||
|
* @param {Function} fn
|
||||||
|
* A callback function which is called for each key in the object. It
|
||||||
|
* receives the accumulated value and the per-iteration value and key
|
||||||
|
* as arguments.
|
||||||
|
* @param {Mixed} [initial = 0]
|
||||||
|
* @return {Mixed}
|
||||||
|
*/
|
||||||
|
export function reduce(object, fn, initial = 0) {
|
||||||
|
return Object.keys(object).reduce(
|
||||||
|
(accum, key) => fn(accum, object[key], key),
|
||||||
|
initial);
|
||||||
|
}
|
@ -31,6 +31,7 @@ QUnit.test('should update settings', function(assert) {
|
|||||||
tracks,
|
tracks,
|
||||||
persistTextTrackSettings: true
|
persistTextTrackSettings: true
|
||||||
});
|
});
|
||||||
|
|
||||||
const newSettings = {
|
const newSettings = {
|
||||||
backgroundOpacity: '0.5',
|
backgroundOpacity: '0.5',
|
||||||
textOpacity: '0.5',
|
textOpacity: '0.5',
|
||||||
@ -44,43 +45,52 @@ QUnit.test('should update settings', function(assert) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
player.textTrackSettings.setValues(newSettings);
|
player.textTrackSettings.setValues(newSettings);
|
||||||
|
|
||||||
assert.deepEqual(player.textTrackSettings.getValues(),
|
assert.deepEqual(player.textTrackSettings.getValues(),
|
||||||
newSettings,
|
newSettings,
|
||||||
'values are updated');
|
'values are updated');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-fg-color > select').selectedIndex,
|
assert.equal(player.$('.vjs-fg-color > select').selectedIndex,
|
||||||
2,
|
2,
|
||||||
'fg-color is set to new value');
|
'fg-color is set to new value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-bg-color > select').selectedIndex,
|
assert.equal(player.$('.vjs-bg-color > select').selectedIndex,
|
||||||
1,
|
1,
|
||||||
'bg-color is set to new value');
|
'bg-color is set to new value');
|
||||||
assert.equal(player.$('.window-color > select').selectedIndex,
|
|
||||||
1,
|
assert.equal(player.$('.vjs-window-color > select').selectedIndex,
|
||||||
'window-color is set to new value');
|
1,
|
||||||
|
'window-color is set to new value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-text-opacity > select').selectedIndex,
|
assert.equal(player.$('.vjs-text-opacity > select').selectedIndex,
|
||||||
1,
|
1,
|
||||||
'text-opacity is set to new value');
|
'text-opacity is set to new value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-bg-opacity > select').selectedIndex,
|
assert.equal(player.$('.vjs-bg-opacity > select').selectedIndex,
|
||||||
1,
|
1,
|
||||||
'bg-opacity is set to new value');
|
'bg-opacity is set to new value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-window-opacity > select').selectedIndex,
|
assert.equal(player.$('.vjs-window-opacity > select').selectedIndex,
|
||||||
1,
|
1,
|
||||||
'window-opacity is set to new value');
|
'window-opacity is set to new value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-edge-style select').selectedIndex,
|
assert.equal(player.$('.vjs-edge-style select').selectedIndex,
|
||||||
1,
|
1,
|
||||||
'edge-style is set to new value');
|
'edge-style is set to new value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-font-family select').selectedIndex,
|
assert.equal(player.$('.vjs-font-family select').selectedIndex,
|
||||||
3,
|
3,
|
||||||
'font-family is set to new value');
|
'font-family is set to new value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-font-percent select').selectedIndex,
|
assert.equal(player.$('.vjs-font-percent select').selectedIndex,
|
||||||
3,
|
3,
|
||||||
'font-percent is set to new value');
|
'font-percent is set to new value');
|
||||||
|
|
||||||
Events.trigger(player.$('.vjs-done-button'), 'click');
|
Events.trigger(player.$('.vjs-done-button'), 'click');
|
||||||
assert.deepEqual(safeParseTuple(
|
|
||||||
window.localStorage.getItem('vjs-text-track-settings'))[1],
|
assert.deepEqual(safeParseTuple(window.localStorage.getItem('vjs-text-track-settings'))[1],
|
||||||
newSettings,
|
newSettings,
|
||||||
'values are saved');
|
'values are saved');
|
||||||
|
|
||||||
player.dispose();
|
player.dispose();
|
||||||
});
|
});
|
||||||
@ -93,7 +103,7 @@ QUnit.test('should restore default settings', function(assert) {
|
|||||||
|
|
||||||
player.$('.vjs-fg-color > select').selectedIndex = 1;
|
player.$('.vjs-fg-color > select').selectedIndex = 1;
|
||||||
player.$('.vjs-bg-color > select').selectedIndex = 1;
|
player.$('.vjs-bg-color > select').selectedIndex = 1;
|
||||||
player.$('.window-color > select').selectedIndex = 1;
|
player.$('.vjs-window-color > select').selectedIndex = 1;
|
||||||
player.$('.vjs-text-opacity > select').selectedIndex = 1;
|
player.$('.vjs-text-opacity > select').selectedIndex = 1;
|
||||||
player.$('.vjs-bg-opacity > select').selectedIndex = 1;
|
player.$('.vjs-bg-opacity > select').selectedIndex = 1;
|
||||||
player.$('.vjs-window-opacity > select').selectedIndex = 1;
|
player.$('.vjs-window-opacity > select').selectedIndex = 1;
|
||||||
@ -106,8 +116,8 @@ QUnit.test('should restore default settings', function(assert) {
|
|||||||
Events.trigger(player.$('.vjs-done-button'), 'click');
|
Events.trigger(player.$('.vjs-done-button'), 'click');
|
||||||
|
|
||||||
assert.deepEqual(player.textTrackSettings.getValues(),
|
assert.deepEqual(player.textTrackSettings.getValues(),
|
||||||
defaultSettings,
|
defaultSettings,
|
||||||
'values are defaulted');
|
'values are defaulted');
|
||||||
// TODO:
|
// TODO:
|
||||||
// MikeA: need to figure out how to modify saveSettings
|
// MikeA: need to figure out how to modify saveSettings
|
||||||
// to factor in defaults are no longer null
|
// to factor in defaults are no longer null
|
||||||
@ -116,32 +126,40 @@ QUnit.test('should restore default settings', function(assert) {
|
|||||||
// 'values are saved');
|
// 'values are saved');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-fg-color > select').selectedIndex,
|
assert.equal(player.$('.vjs-fg-color > select').selectedIndex,
|
||||||
0,
|
0,
|
||||||
'fg-color is set to default value');
|
'fg-color is set to default value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-bg-color > select').selectedIndex,
|
assert.equal(player.$('.vjs-bg-color > select').selectedIndex,
|
||||||
0,
|
0,
|
||||||
'bg-color is set to default value');
|
'bg-color is set to default value');
|
||||||
assert.equal(player.$('.window-color > select').selectedIndex,
|
|
||||||
0,
|
assert.equal(player.$('.vjs-window-color > select').selectedIndex,
|
||||||
'window-color is set to default value');
|
0,
|
||||||
|
'window-color is set to default value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-text-opacity > select').selectedIndex,
|
assert.equal(player.$('.vjs-text-opacity > select').selectedIndex,
|
||||||
0,
|
0,
|
||||||
'text-opacity is set to default value');
|
'text-opacity is set to default value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-bg-opacity > select').selectedIndex,
|
assert.equal(player.$('.vjs-bg-opacity > select').selectedIndex,
|
||||||
0,
|
0,
|
||||||
'bg-opacity is set to default value');
|
'bg-opacity is set to default value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-window-opacity > select').selectedIndex,
|
assert.equal(player.$('.vjs-window-opacity > select').selectedIndex,
|
||||||
0,
|
0,
|
||||||
'window-opacity is set to default value');
|
'window-opacity is set to default value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-edge-style select').selectedIndex,
|
assert.equal(player.$('.vjs-edge-style select').selectedIndex,
|
||||||
0,
|
0,
|
||||||
'edge-style is set to default value');
|
'edge-style is set to default value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-font-family select').selectedIndex,
|
assert.equal(player.$('.vjs-font-family select').selectedIndex,
|
||||||
0,
|
0,
|
||||||
'font-family is set to default value');
|
'font-family is set to default value');
|
||||||
|
|
||||||
assert.equal(player.$('.vjs-font-percent select').selectedIndex,
|
assert.equal(player.$('.vjs-font-percent select').selectedIndex,
|
||||||
2,
|
2,
|
||||||
'font-percent is set to default value');
|
'font-percent is set to default value');
|
||||||
|
|
||||||
player.dispose();
|
player.dispose();
|
||||||
});
|
});
|
||||||
|
@ -15,8 +15,8 @@ QUnit.test('should return the element with the ID', function(assert) {
|
|||||||
el1.id = 'test_id1';
|
el1.id = 'test_id1';
|
||||||
el2.id = 'test_id2';
|
el2.id = 'test_id2';
|
||||||
|
|
||||||
assert.ok(Dom.getEl('test_id1') === el1, 'found element for ID');
|
assert.strictEqual(Dom.getEl('test_id1'), el1, 'found element for ID');
|
||||||
assert.ok(Dom.getEl('#test_id2') === el2, 'found element for CSS ID');
|
assert.strictEqual(Dom.getEl('#test_id2'), el2, 'found element for CSS ID');
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should create an element', function(assert) {
|
QUnit.test('should create an element', function(assert) {
|
||||||
@ -27,10 +27,27 @@ QUnit.test('should create an element', function(assert) {
|
|||||||
'data-test': 'asdf'
|
'data-test': 'asdf'
|
||||||
});
|
});
|
||||||
|
|
||||||
assert.ok(div.nodeName === 'DIV');
|
assert.strictEqual(div.nodeName, 'DIV');
|
||||||
assert.ok(span.nodeName === 'SPAN');
|
assert.strictEqual(span.nodeName, 'SPAN');
|
||||||
assert.ok(span.getAttribute('data-test') === 'asdf');
|
assert.strictEqual(span.getAttribute('data-test'), 'asdf');
|
||||||
assert.ok(span.innerHTML === 'fdsa');
|
assert.strictEqual(span.innerHTML, 'fdsa');
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('should create an element, supporting textContent', function(assert) {
|
||||||
|
const span = Dom.createEl('span', {textContent: 'howdy'});
|
||||||
|
|
||||||
|
if (span.textContent) {
|
||||||
|
assert.strictEqual(span.textContent, 'howdy', 'works in browsers that support textContent');
|
||||||
|
} else {
|
||||||
|
assert.strictEqual(span.innerText, 'howdy', 'works in browsers that DO NOT support textContent');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('should create an element with content', function(assert) {
|
||||||
|
const span = Dom.createEl('span');
|
||||||
|
const div = Dom.createEl('div', undefined, undefined, span);
|
||||||
|
|
||||||
|
assert.strictEqual(div.firstChild, span);
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should insert an element first in another', function(assert) {
|
QUnit.test('should insert an element first in another', function(assert) {
|
||||||
@ -39,28 +56,28 @@ QUnit.test('should insert an element first in another', function(assert) {
|
|||||||
const parent = document.createElement('div');
|
const parent = document.createElement('div');
|
||||||
|
|
||||||
Dom.insertElFirst(el1, parent);
|
Dom.insertElFirst(el1, parent);
|
||||||
assert.ok(parent.firstChild === el1, 'inserts first into empty parent');
|
assert.strictEqual(parent.firstChild, el1, 'inserts first into empty parent');
|
||||||
|
|
||||||
Dom.insertElFirst(el2, parent);
|
Dom.insertElFirst(el2, parent);
|
||||||
assert.ok(parent.firstChild === el2, 'inserts first into parent with child');
|
assert.strictEqual(parent.firstChild, el2, 'inserts first into parent with child');
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('should get and remove data from an element', function(assert) {
|
QUnit.test('should get and remove data from an element', function(assert) {
|
||||||
const el = document.createElement('div');
|
const el = document.createElement('div');
|
||||||
const data = Dom.getElData(el);
|
const data = Dom.getElData(el);
|
||||||
|
|
||||||
assert.ok(typeof data === 'object', 'data object created');
|
assert.strictEqual(typeof data, 'object', 'data object created');
|
||||||
|
|
||||||
// Add data
|
// Add data
|
||||||
const testData = { asdf: 'fdsa' };
|
const testData = {asdf: 'fdsa'};
|
||||||
|
|
||||||
data.test = testData;
|
data.test = testData;
|
||||||
assert.ok(Dom.getElData(el).test === testData, 'data added');
|
assert.strictEqual(Dom.getElData(el).test, testData, 'data added');
|
||||||
|
|
||||||
// Remove all data
|
// Remove all data
|
||||||
Dom.removeElData(el);
|
Dom.removeElData(el);
|
||||||
|
|
||||||
assert.ok(!Dom.hasElData(el), 'cached item emptied');
|
assert.notOk(Dom.hasElData(el), 'cached item emptied');
|
||||||
});
|
});
|
||||||
|
|
||||||
QUnit.test('addElClass()', function(assert) {
|
QUnit.test('addElClass()', function(assert) {
|
||||||
|
58
test/unit/utils/obj.test.js
Normal file
58
test/unit/utils/obj.test.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/* eslint-env qunit */
|
||||||
|
import sinon from 'sinon';
|
||||||
|
import * as Obj from '../../../src/js/utils/obj';
|
||||||
|
|
||||||
|
QUnit.module('utils/obj');
|
||||||
|
|
||||||
|
QUnit.test('each', function(assert) {
|
||||||
|
const spy = sinon.spy();
|
||||||
|
|
||||||
|
Obj.each({
|
||||||
|
a: 1,
|
||||||
|
b: 'foo',
|
||||||
|
c: null
|
||||||
|
}, spy);
|
||||||
|
|
||||||
|
assert.strictEqual(spy.callCount, 3);
|
||||||
|
assert.ok(spy.calledWith(1, 'a'));
|
||||||
|
assert.ok(spy.calledWith('foo', 'b'));
|
||||||
|
assert.ok(spy.calledWith(null, 'c'));
|
||||||
|
|
||||||
|
Obj.each({}, spy);
|
||||||
|
assert.strictEqual(spy.callCount, 3, 'an empty object was not iterated over');
|
||||||
|
});
|
||||||
|
|
||||||
|
QUnit.test('reduce', function(assert) {
|
||||||
|
const first = Obj.reduce({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
c: 3,
|
||||||
|
d: 4
|
||||||
|
}, (accum, value) => accum + value);
|
||||||
|
|
||||||
|
assert.strictEqual(first, 10);
|
||||||
|
|
||||||
|
const second = Obj.reduce({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
c: 3,
|
||||||
|
d: 4
|
||||||
|
}, (accum, value) => accum + value, 10);
|
||||||
|
|
||||||
|
assert.strictEqual(second, 20);
|
||||||
|
|
||||||
|
const third = Obj.reduce({
|
||||||
|
a: 1,
|
||||||
|
b: 2,
|
||||||
|
c: 3,
|
||||||
|
d: 4
|
||||||
|
}, (accum, value, key) => {
|
||||||
|
accum[key] = 0 - value;
|
||||||
|
return accum;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
assert.strictEqual(third.a, -1);
|
||||||
|
assert.strictEqual(third.b, -2);
|
||||||
|
assert.strictEqual(third.c, -3);
|
||||||
|
assert.strictEqual(third.d, -4);
|
||||||
|
});
|
Loading…
x
Reference in New Issue
Block a user