Fixed bug for captions with no srclang and labels and improved logic (fixes #875)

This commit is contained in:
Sam Potts 2018-04-17 22:49:28 +10:00
parent 3061a701d5
commit 46fe3eecff
16 changed files with 372 additions and 171 deletions

View File

@ -1,3 +1,13 @@
## v3.1.1
* Fullscreen fixes (thanks @friday)
* Menu fix for if speed not in config
* Menu z-index fix (thanks @danielsarin)
* i18n fix for missing "Normal" string (thanks @danielsarin)
* Safer check for active caption (thanks @Antonio-Laguna)
* Add custom property fallback (thanks @friday)
* Fixed bug for captions with no srclang and labels and improved logic (fixes #875)
## v3.1.0 ## v3.1.0
* Styling fixes * Styling fixes

2
demo/dist/demo.css vendored

File diff suppressed because one or more lines are too long

2
dist/plyr.css vendored

File diff suppressed because one or more lines are too long

185
dist/plyr.js vendored
View File

@ -172,6 +172,7 @@ var defaults = {
all: 'All', all: 'All',
reset: 'Reset', reset: 'Reset',
disabled: 'Disabled', disabled: 'Disabled',
enabled: 'Enabled',
advertisement: 'Ad' advertisement: 'Ad'
}, },
@ -2130,6 +2131,36 @@ var Fullscreen = function () {
// ========================================================================== // ==========================================================================
var i18n = {
get: function get$$1() {
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
return '';
}
var string = config.i18n[key];
var replace = {
'{seektime}': config.seekTime,
'{title}': config.title
};
Object.entries(replace).forEach(function (_ref) {
var _ref2 = slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
string = utils.replaceAll(string, key, value);
});
return string;
}
};
// ==========================================================================
var captions = { var captions = {
// Setup captions // Setup captions
setup: function setup() { setup: function setup() {
@ -2169,6 +2200,7 @@ var captions = {
return; return;
} }
// Inject the container // Inject the container
if (!utils.is.element(this.elements.captions)) { if (!utils.is.element(this.elements.captions)) {
this.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.captions)); this.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.captions));
@ -2273,9 +2305,54 @@ var captions = {
getCurrentTrack: function getCurrentTrack() { getCurrentTrack: function getCurrentTrack() {
var _this2 = this; var _this2 = this;
return captions.getTracks.call(this).find(function (track) { var tracks = captions.getTracks.call(this);
if (!tracks.length) {
return null;
}
// Get track based on current language
var track = tracks.find(function (track) {
return track.language.toLowerCase() === _this2.language; return track.language.toLowerCase() === _this2.language;
}); });
// Get the <track> with default attribute
if (!track) {
track = utils.getElement.call(this, 'track[default]');
}
// Get the first track
if (!track) {
var _tracks = slicedToArray(tracks, 1);
track = _tracks[0];
}
return track;
},
// Get UI label for track
getLabel: function getLabel(track) {
var currentTrack = track;
if (!utils.is.track(currentTrack) && support.textTracks && this.captions.active) {
currentTrack = captions.getCurrentTrack.call(this);
}
if (utils.is.track(currentTrack)) {
if (!utils.is.empty(currentTrack.label)) {
return currentTrack.label;
}
if (!utils.is.empty(currentTrack.language)) {
return track.language.toUpperCase();
}
return i18n.get('enabled', this.config);
}
return i18n.get('disabled', this.config);
}, },
@ -2361,36 +2438,6 @@ var captions = {
// ========================================================================== // ==========================================================================
var i18n = {
get: function get$$1() {
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
return '';
}
var string = config.i18n[key];
var replace = {
'{seektime}': config.seekTime,
'{title}': config.title
};
Object.entries(replace).forEach(function (_ref) {
var _ref2 = slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
string = utils.replaceAll(string, key, value);
});
return string;
}
};
// ==========================================================================
var ui = { var ui = {
addStyleHook: function addStyleHook() { addStyleHook: function addStyleHook() {
utils.toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true); utils.toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);
@ -3311,6 +3358,9 @@ var controls = {
var toggle = !utils.is.empty(this.options.quality) && this.options.quality.length > 1; var toggle = !utils.is.empty(this.options.quality) && this.options.quality.length > 1;
controls.toggleTab.call(this, type, toggle); controls.toggleTab.call(this, type, toggle);
// Check if we need to toggle the parent
controls.checkMenu.call(this);
// If we're hiding, nothing more to do // If we're hiding, nothing more to do
if (!toggle) { if (!toggle) {
return; return;
@ -3373,10 +3423,11 @@ var controls = {
if (utils.is.number(value)) { if (utils.is.number(value)) {
return value + 'p'; return value + 'p';
} }
return utils.toTitleCase(value); return utils.toTitleCase(value);
case 'captions': case 'captions':
return controls.getLanguage.call(this); return captions.getLabel.call(this);
default: default:
return null; return null;
@ -3392,7 +3443,18 @@ var controls = {
switch (setting) { switch (setting) {
case 'captions': case 'captions':
value = this.captions.active ? this.captions.language : i18n.get('disabled', this.config); if (this.captions.active) {
if (this.options.captions.length > 2 || !this.options.captions.some(function (lang) {
return lang === 'enabled';
})) {
value = this.captions.language;
} else {
value = 'enabled';
}
} else {
value = '';
}
break; break;
default: default:
@ -3424,16 +3486,13 @@ var controls = {
} }
// Update the label // Update the label
if (!utils.is.empty(value)) {
var label = this.elements.settings.tabs[setting].querySelector('.' + this.config.classNames.menu.value); var label = this.elements.settings.tabs[setting].querySelector('.' + this.config.classNames.menu.value);
label.innerHTML = controls.getLabel.call(this, setting, value); label.innerHTML = controls.getLabel.call(this, setting, value);
}
// Find the radio option // Find the radio option and check it
var target = list && list.querySelector('input[value="' + value + '"]'); var target = list && list.querySelector('input[value="' + value + '"]');
if (utils.is.element(target)) { if (utils.is.element(target)) {
// Check it
target.checked = true; target.checked = true;
} }
}, },
@ -3477,21 +3536,6 @@ var controls = {
// Get current selected caption language // Get current selected caption language
// TODO: rework this to user the getter in the API? // TODO: rework this to user the getter in the API?
getLanguage: function getLanguage() {
if (!this.supported.ui) {
return null;
}
if (support.textTracks && captions.getTracks.call(this).length && this.captions.active) {
var currentTrack = captions.getCurrentTrack.call(this);
if (utils.is.track(currentTrack)) {
return currentTrack.label;
}
}
return i18n.get('disabled', this.config);
},
// Set a list of available captions languages // Set a list of available captions languages
@ -3509,6 +3553,9 @@ var controls = {
// Empty the menu // Empty the menu
utils.emptyElement(list); utils.emptyElement(list);
// Check if we need to toggle the parent
controls.checkMenu.call(this);
// If there's no captions, bail // If there's no captions, bail
if (!toggle) { if (!toggle) {
return; return;
@ -3517,8 +3564,8 @@ var controls = {
// Re-map the tracks into just the data we need // Re-map the tracks into just the data we need
var tracks = captions.getTracks.call(this).map(function (track) { var tracks = captions.getTracks.call(this).map(function (track) {
return { return {
language: track.language, language: !utils.is.empty(track.language) ? track.language : 'enabled',
label: !utils.is.empty(track.label) ? track.label : track.language.toUpperCase() label: captions.getLabel.call(_this3, track)
}; };
}); });
@ -3530,7 +3577,12 @@ var controls = {
// Generate options // Generate options
tracks.forEach(function (track) { tracks.forEach(function (track) {
controls.createMenuItem.call(_this3, track.language, list, 'language', track.label || track.language, controls.createBadge.call(_this3, track.language.toUpperCase()), track.language.toLowerCase() === _this3.captions.language.toLowerCase()); controls.createMenuItem.call(_this3, track.language, list, 'language', track.label, track.language !== 'enabled' ? controls.createBadge.call(_this3, track.language.toUpperCase()) : null, track.language.toLowerCase() === _this3.captions.language.toLowerCase());
});
// Store reference
this.options.captions = tracks.map(function (track) {
return track.language;
}); });
controls.updateSetting.call(this, type, list); controls.updateSetting.call(this, type, list);
@ -4049,7 +4101,7 @@ var controls = {
seektime: this.config.seekTime, seektime: this.config.seekTime,
speed: this.speed, speed: this.speed,
quality: this.quality, quality: this.quality,
captions: controls.getLanguage.call(this) captions: captions.getLabel.call(this)
// TODO: Looping // TODO: Looping
// loop: 'None', // loop: 'None',
}); });
@ -6579,7 +6631,8 @@ var Plyr = function () {
// Options // Options
this.options = { this.options = {
speed: [], speed: [],
quality: [] quality: [],
captions: []
}; };
// Debugging // Debugging
@ -7742,17 +7795,29 @@ var Plyr = function () {
return; return;
} }
// Toggle captions based on input
this.toggleCaptions(!utils.is.empty(input));
// If empty string is passed, assume disable captions // If empty string is passed, assume disable captions
if (utils.is.empty(input)) { if (utils.is.empty(input)) {
this.toggleCaptions(false);
return; return;
} }
// Normalize // Normalize
var language = input.toLowerCase(); var language = input.toLowerCase();
// Check for support
if (!this.options.captions.includes(language)) {
this.debug.warn('Unsupported language option: ' + language);
return;
}
// Ensure captions are enabled
this.toggleCaptions(true);
// Enabled only
if (language === 'enabled') {
return;
}
// If nothing to change, bail // If nothing to change, bail
if (this.language === language) { if (this.language === language) {
return; return;

2
dist/plyr.js.map vendored

File diff suppressed because one or more lines are too long

2
dist/plyr.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6112,6 +6112,7 @@ var defaults = {
all: 'All', all: 'All',
reset: 'Reset', reset: 'Reset',
disabled: 'Disabled', disabled: 'Disabled',
enabled: 'Enabled',
advertisement: 'Ad' advertisement: 'Ad'
}, },
@ -8064,6 +8065,36 @@ var Fullscreen = function () {
// ========================================================================== // ==========================================================================
var i18n = {
get: function get() {
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
return '';
}
var string = config.i18n[key];
var replace = {
'{seektime}': config.seekTime,
'{title}': config.title
};
Object.entries(replace).forEach(function (_ref) {
var _ref2 = slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
string = utils.replaceAll(string, key, value);
});
return string;
}
};
// ==========================================================================
var captions = { var captions = {
// Setup captions // Setup captions
setup: function setup() { setup: function setup() {
@ -8103,6 +8134,7 @@ var captions = {
return; return;
} }
// Inject the container // Inject the container
if (!utils.is.element(this.elements.captions)) { if (!utils.is.element(this.elements.captions)) {
this.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.captions)); this.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.captions));
@ -8207,9 +8239,54 @@ var captions = {
getCurrentTrack: function getCurrentTrack() { getCurrentTrack: function getCurrentTrack() {
var _this2 = this; var _this2 = this;
return captions.getTracks.call(this).find(function (track) { var tracks = captions.getTracks.call(this);
if (!tracks.length) {
return null;
}
// Get track based on current language
var track = tracks.find(function (track) {
return track.language.toLowerCase() === _this2.language; return track.language.toLowerCase() === _this2.language;
}); });
// Get the <track> with default attribute
if (!track) {
track = utils.getElement.call(this, 'track[default]');
}
// Get the first track
if (!track) {
var _tracks = slicedToArray(tracks, 1);
track = _tracks[0];
}
return track;
},
// Get UI label for track
getLabel: function getLabel(track) {
var currentTrack = track;
if (!utils.is.track(currentTrack) && support.textTracks && this.captions.active) {
currentTrack = captions.getCurrentTrack.call(this);
}
if (utils.is.track(currentTrack)) {
if (!utils.is.empty(currentTrack.label)) {
return currentTrack.label;
}
if (!utils.is.empty(currentTrack.language)) {
return track.language.toUpperCase();
}
return i18n.get('enabled', this.config);
}
return i18n.get('disabled', this.config);
}, },
@ -8295,36 +8372,6 @@ var captions = {
// ========================================================================== // ==========================================================================
var i18n = {
get: function get() {
var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (utils.is.empty(key) || utils.is.empty(config) || !Object.keys(config.i18n).includes(key)) {
return '';
}
var string = config.i18n[key];
var replace = {
'{seektime}': config.seekTime,
'{title}': config.title
};
Object.entries(replace).forEach(function (_ref) {
var _ref2 = slicedToArray(_ref, 2),
key = _ref2[0],
value = _ref2[1];
string = utils.replaceAll(string, key, value);
});
return string;
}
};
// ==========================================================================
var ui = { var ui = {
addStyleHook: function addStyleHook() { addStyleHook: function addStyleHook() {
utils.toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true); utils.toggleClass(this.elements.container, this.config.selectors.container.replace('.', ''), true);
@ -9245,6 +9292,9 @@ var controls = {
var toggle = !utils.is.empty(this.options.quality) && this.options.quality.length > 1; var toggle = !utils.is.empty(this.options.quality) && this.options.quality.length > 1;
controls.toggleTab.call(this, type, toggle); controls.toggleTab.call(this, type, toggle);
// Check if we need to toggle the parent
controls.checkMenu.call(this);
// If we're hiding, nothing more to do // If we're hiding, nothing more to do
if (!toggle) { if (!toggle) {
return; return;
@ -9307,10 +9357,11 @@ var controls = {
if (utils.is.number(value)) { if (utils.is.number(value)) {
return value + 'p'; return value + 'p';
} }
return utils.toTitleCase(value); return utils.toTitleCase(value);
case 'captions': case 'captions':
return controls.getLanguage.call(this); return captions.getLabel.call(this);
default: default:
return null; return null;
@ -9326,7 +9377,18 @@ var controls = {
switch (setting) { switch (setting) {
case 'captions': case 'captions':
value = this.captions.active ? this.captions.language : i18n.get('disabled', this.config); if (this.captions.active) {
if (this.options.captions.length > 2 || !this.options.captions.some(function (lang) {
return lang === 'enabled';
})) {
value = this.captions.language;
} else {
value = 'enabled';
}
} else {
value = '';
}
break; break;
default: default:
@ -9358,16 +9420,13 @@ var controls = {
} }
// Update the label // Update the label
if (!utils.is.empty(value)) {
var label = this.elements.settings.tabs[setting].querySelector('.' + this.config.classNames.menu.value); var label = this.elements.settings.tabs[setting].querySelector('.' + this.config.classNames.menu.value);
label.innerHTML = controls.getLabel.call(this, setting, value); label.innerHTML = controls.getLabel.call(this, setting, value);
}
// Find the radio option // Find the radio option and check it
var target = list && list.querySelector('input[value="' + value + '"]'); var target = list && list.querySelector('input[value="' + value + '"]');
if (utils.is.element(target)) { if (utils.is.element(target)) {
// Check it
target.checked = true; target.checked = true;
} }
}, },
@ -9411,21 +9470,6 @@ var controls = {
// Get current selected caption language // Get current selected caption language
// TODO: rework this to user the getter in the API? // TODO: rework this to user the getter in the API?
getLanguage: function getLanguage() {
if (!this.supported.ui) {
return null;
}
if (support.textTracks && captions.getTracks.call(this).length && this.captions.active) {
var currentTrack = captions.getCurrentTrack.call(this);
if (utils.is.track(currentTrack)) {
return currentTrack.label;
}
}
return i18n.get('disabled', this.config);
},
// Set a list of available captions languages // Set a list of available captions languages
@ -9443,6 +9487,9 @@ var controls = {
// Empty the menu // Empty the menu
utils.emptyElement(list); utils.emptyElement(list);
// Check if we need to toggle the parent
controls.checkMenu.call(this);
// If there's no captions, bail // If there's no captions, bail
if (!toggle) { if (!toggle) {
return; return;
@ -9451,8 +9498,8 @@ var controls = {
// Re-map the tracks into just the data we need // Re-map the tracks into just the data we need
var tracks = captions.getTracks.call(this).map(function (track) { var tracks = captions.getTracks.call(this).map(function (track) {
return { return {
language: track.language, language: !utils.is.empty(track.language) ? track.language : 'enabled',
label: !utils.is.empty(track.label) ? track.label : track.language.toUpperCase() label: captions.getLabel.call(_this3, track)
}; };
}); });
@ -9464,7 +9511,12 @@ var controls = {
// Generate options // Generate options
tracks.forEach(function (track) { tracks.forEach(function (track) {
controls.createMenuItem.call(_this3, track.language, list, 'language', track.label || track.language, controls.createBadge.call(_this3, track.language.toUpperCase()), track.language.toLowerCase() === _this3.captions.language.toLowerCase()); controls.createMenuItem.call(_this3, track.language, list, 'language', track.label, track.language !== 'enabled' ? controls.createBadge.call(_this3, track.language.toUpperCase()) : null, track.language.toLowerCase() === _this3.captions.language.toLowerCase());
});
// Store reference
this.options.captions = tracks.map(function (track) {
return track.language;
}); });
controls.updateSetting.call(this, type, list); controls.updateSetting.call(this, type, list);
@ -9983,7 +10035,7 @@ var controls = {
seektime: this.config.seekTime, seektime: this.config.seekTime,
speed: this.speed, speed: this.speed,
quality: this.quality, quality: this.quality,
captions: controls.getLanguage.call(this) captions: captions.getLabel.call(this)
// TODO: Looping // TODO: Looping
// loop: 'None', // loop: 'None',
}); });
@ -12513,7 +12565,8 @@ var Plyr = function () {
// Options // Options
this.options = { this.options = {
speed: [], speed: [],
quality: [] quality: [],
captions: []
}; };
// Debugging // Debugging
@ -13676,17 +13729,29 @@ var Plyr = function () {
return; return;
} }
// Toggle captions based on input
this.toggleCaptions(!utils.is.empty(input));
// If empty string is passed, assume disable captions // If empty string is passed, assume disable captions
if (utils.is.empty(input)) { if (utils.is.empty(input)) {
this.toggleCaptions(false);
return; return;
} }
// Normalize // Normalize
var language = input.toLowerCase(); var language = input.toLowerCase();
// Check for support
if (!this.options.captions.includes(language)) {
this.debug.warn('Unsupported language option: ' + language);
return;
}
// Ensure captions are enabled
this.toggleCaptions(true);
// Enabled only
if (language === 'enabled') {
return;
}
// If nothing to change, bail // If nothing to change, bail
if (this.language === language) { if (this.language === language) {
return; return;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -6,6 +6,7 @@
import support from './support'; import support from './support';
import utils from './utils'; import utils from './utils';
import controls from './controls'; import controls from './controls';
import i18n from './i18n';
const captions = { const captions = {
// Setup captions // Setup captions
@ -46,6 +47,7 @@ const captions = {
return; return;
} }
// Inject the container // Inject the container
if (!utils.is.element(this.elements.captions)) { if (!utils.is.element(this.elements.captions)) {
this.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.captions)); this.elements.captions = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.captions));
@ -148,7 +150,49 @@ const captions = {
// Get the current track for the current language // Get the current track for the current language
getCurrentTrack() { getCurrentTrack() {
return captions.getTracks.call(this).find(track => track.language.toLowerCase() === this.language); const tracks = captions.getTracks.call(this);
if (!tracks.length) {
return null;
}
// Get track based on current language
let track = tracks.find(track => track.language.toLowerCase() === this.language);
// Get the <track> with default attribute
if (!track) {
track = utils.getElement.call(this, 'track[default]');
}
// Get the first track
if (!track) {
[track] = tracks;
}
return track;
},
// Get UI label for track
getLabel(track) {
let currentTrack = track;
if (!utils.is.track(currentTrack) && support.textTracks && this.captions.active) {
currentTrack = captions.getCurrentTrack.call(this);
}
if (utils.is.track(currentTrack)) {
if (!utils.is.empty(currentTrack.label)) {
return currentTrack.label;
}
if (!utils.is.empty(currentTrack.language)) {
return track.language.toUpperCase();
}
return i18n.get('enabled', this.config);
}
return i18n.get('disabled', this.config);
}, },
// Display active caption if it contains text // Display active caption if it contains text

58
src/js/controls.js vendored
View File

@ -456,6 +456,9 @@ const controls = {
const toggle = !utils.is.empty(this.options.quality) && this.options.quality.length > 1; const toggle = !utils.is.empty(this.options.quality) && this.options.quality.length > 1;
controls.toggleTab.call(this, type, toggle); controls.toggleTab.call(this, type, toggle);
// Check if we need to toggle the parent
controls.checkMenu.call(this);
// If we're hiding, nothing more to do // If we're hiding, nothing more to do
if (!toggle) { if (!toggle) {
return; return;
@ -495,10 +498,12 @@ const controls = {
}; };
// Sort options by the config and then render options // Sort options by the config and then render options
this.options.quality.sort((a, b) => { this.options.quality
.sort((a, b) => {
const sorting = this.config.quality.options; const sorting = this.config.quality.options;
return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1; return sorting.indexOf(a) > sorting.indexOf(b) ? 1 : -1;
}).forEach(quality => { })
.forEach(quality => {
const label = controls.getLabel.call(this, 'quality', quality); const label = controls.getLabel.call(this, 'quality', quality);
controls.createMenuItem.call(this, quality, list, type, label, getBadge(quality)); controls.createMenuItem.call(this, quality, list, type, label, getBadge(quality));
}); });
@ -517,10 +522,11 @@ const controls = {
if (utils.is.number(value)) { if (utils.is.number(value)) {
return `${value}p`; return `${value}p`;
} }
return utils.toTitleCase(value); return utils.toTitleCase(value);
case 'captions': case 'captions':
return controls.getLanguage.call(this); return captions.getLabel.call(this);
default: default:
return null; return null;
@ -535,7 +541,16 @@ const controls = {
switch (setting) { switch (setting) {
case 'captions': case 'captions':
value = this.captions.active ? this.captions.language : i18n.get('disabled', this.config); if (this.captions.active) {
if (this.options.captions.length > 2 || !this.options.captions.some(lang => lang === 'enabled')) {
value = this.captions.language;
} else {
value = 'enabled';
}
} else {
value = '';
}
break; break;
default: default:
@ -567,16 +582,13 @@ const controls = {
} }
// Update the label // Update the label
if (!utils.is.empty(value)) {
const label = this.elements.settings.tabs[setting].querySelector(`.${this.config.classNames.menu.value}`); const label = this.elements.settings.tabs[setting].querySelector(`.${this.config.classNames.menu.value}`);
label.innerHTML = controls.getLabel.call(this, setting, value); label.innerHTML = controls.getLabel.call(this, setting, value);
}
// Find the radio option // Find the radio option and check it
const target = list && list.querySelector(`input[value="${value}"]`); const target = list && list.querySelector(`input[value="${value}"]`);
if (utils.is.element(target)) { if (utils.is.element(target)) {
// Check it
target.checked = true; target.checked = true;
} }
}, },
@ -627,21 +639,7 @@ const controls = {
// Get current selected caption language // Get current selected caption language
// TODO: rework this to user the getter in the API? // TODO: rework this to user the getter in the API?
getLanguage() {
if (!this.supported.ui) {
return null;
}
if (support.textTracks && captions.getTracks.call(this).length && this.captions.active) {
const currentTrack = captions.getCurrentTrack.call(this);
if (utils.is.track(currentTrack)) {
return currentTrack.label;
}
}
return i18n.get('disabled', this.config);
},
// Set a list of available captions languages // Set a list of available captions languages
setCaptionsMenu() { setCaptionsMenu() {
@ -656,6 +654,9 @@ const controls = {
// Empty the menu // Empty the menu
utils.emptyElement(list); utils.emptyElement(list);
// Check if we need to toggle the parent
controls.checkMenu.call(this);
// If there's no captions, bail // If there's no captions, bail
if (!toggle) { if (!toggle) {
return; return;
@ -663,8 +664,8 @@ const controls = {
// Re-map the tracks into just the data we need // Re-map the tracks into just the data we need
const tracks = captions.getTracks.call(this).map(track => ({ const tracks = captions.getTracks.call(this).map(track => ({
language: track.language, language: !utils.is.empty(track.language) ? track.language : 'enabled',
label: !utils.is.empty(track.label) ? track.label : track.language.toUpperCase(), label: captions.getLabel.call(this, track),
})); }));
// Add the "Disabled" option to turn off captions // Add the "Disabled" option to turn off captions
@ -680,12 +681,15 @@ const controls = {
track.language, track.language,
list, list,
'language', 'language',
track.label || track.language, track.label,
controls.createBadge.call(this, track.language.toUpperCase()), track.language !== 'enabled' ? controls.createBadge.call(this, track.language.toUpperCase()) : null,
track.language.toLowerCase() === this.captions.language.toLowerCase(), track.language.toLowerCase() === this.captions.language.toLowerCase(),
); );
}); });
// Store reference
this.options.captions = tracks.map(track => track.language);
controls.updateSetting.call(this, type, list); controls.updateSetting.call(this, type, list);
}, },
@ -1211,7 +1215,7 @@ const controls = {
seektime: this.config.seekTime, seektime: this.config.seekTime,
speed: this.speed, speed: this.speed,
quality: this.quality, quality: this.quality,
captions: controls.getLanguage.call(this), captions: captions.getLabel.call(this),
// TODO: Looping // TODO: Looping
// loop: 'None', // loop: 'None',
}); });

View File

@ -185,6 +185,7 @@ const defaults = {
all: 'All', all: 'All',
reset: 'Reset', reset: 'Reset',
disabled: 'Disabled', disabled: 'Disabled',
enabled: 'Enabled',
advertisement: 'Ad', advertisement: 'Ad',
}, },

View File

@ -2,7 +2,6 @@
// Plyr Event Listeners // Plyr Event Listeners
// ========================================================================== // ==========================================================================
import support from './support';
import utils from './utils'; import utils from './utils';
import controls from './controls'; import controls from './controls';
import ui from './ui'; import ui from './ui';

View File

@ -97,6 +97,7 @@ class Plyr {
this.options = { this.options = {
speed: [], speed: [],
quality: [], quality: [],
captions: [],
}; };
// Debugging // Debugging
@ -875,17 +876,29 @@ class Plyr {
return; return;
} }
// Toggle captions based on input
this.toggleCaptions(!utils.is.empty(input));
// If empty string is passed, assume disable captions // If empty string is passed, assume disable captions
if (utils.is.empty(input)) { if (utils.is.empty(input)) {
this.toggleCaptions(false);
return; return;
} }
// Normalize // Normalize
const language = input.toLowerCase(); const language = input.toLowerCase();
// Check for support
if (!this.options.captions.includes(language)) {
this.debug.warn(`Unsupported language option: ${language}`);
return;
}
// Ensure captions are enabled
this.toggleCaptions(true);
// Enabled only
if (language === 'enabled') {
return;
}
// If nothing to change, bail // If nothing to change, bail
if (this.language === language) { if (this.language === language) {
return; return;