Updated data attributes to data-plyr namespace. Speed menu fixes

This commit is contained in:
Sam Potts
2017-11-23 12:57:43 +11:00
parent 7382553a78
commit de6f0f1b77
20 changed files with 365 additions and 429 deletions

View File

@ -43,20 +43,13 @@ const captions = {
// Inject the container
if (!utils.is.htmlElement(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));
utils.insertAfter(this.elements.captions, this.elements.wrapper);
}
// Set the class hook
utils.toggleClass(
this.elements.container,
this.config.classNames.captions.enabled,
!utils.is.empty(captions.getTracks.call(this))
);
utils.toggleClass(this.elements.container, this.config.classNames.captions.enabled, !utils.is.empty(captions.getTracks.call(this)));
// If no caption file exists, hide container for caption text
if (utils.is.empty(captions.getTracks.call(this))) {

52
src/js/controls.js vendored
View File

@ -336,9 +336,7 @@ const controls = {
)
);
container.appendChild(
utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.display[type]), '00:00')
);
container.appendChild(utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.display[type]), '00:00'));
this.elements.display[type] = container;
@ -491,14 +489,7 @@ const controls = {
};
this.options.quality.forEach(quality =>
controls.createMenuItem.call(
this,
quality,
list,
type,
controls.getLabel.call(this, 'quality', quality),
getBadge(quality)
)
controls.createMenuItem.call(this, quality, list, type, controls.getLabel.call(this, 'quality', quality), getBadge(quality))
);
controls.updateSetting.call(this, type, list);
@ -710,16 +701,17 @@ const controls = {
},
// Set a list of available captions languages
setSpeedMenu(options) {
setSpeedMenu() {
const type = 'speed';
// Set options if passed and filter based on config
if (utils.is.array(options)) {
this.options.speed = options.filter(speed => this.config.speed.options.includes(speed));
} else {
this.options.speed = this.config.speed.options;
// Set the default speeds
if (!utils.is.object(this.options.speed) || !Object.keys(this.options.speed).length) {
this.options.speed = [0.5, 0.75, 1, 1.25, 1.5, 1.75, 2];
}
// Set options if passed and filter based on config
this.options.speed = this.options.speed.filter(speed => this.config.speed.options.includes(speed));
// Toggle the pane and tab
const toggle = !utils.is.empty(this.options.speed);
controls.toggleTab.call(this, type, toggle);
@ -740,9 +732,7 @@ const controls = {
utils.emptyElement(list);
// Create items
this.options.speed.forEach(speed =>
controls.createMenuItem.call(this, speed, list, type, controls.getLabel.call(this, 'speed', speed))
);
this.options.speed.forEach(speed => controls.createMenuItem.call(this, speed, list, type, controls.getLabel.call(this, 'speed', speed)));
controls.updateSetting.call(this, type, list);
},
@ -751,9 +741,7 @@ const controls = {
toggleMenu(event) {
const { form } = this.elements.settings;
const button = this.elements.buttons.settings;
const show = utils.is.boolean(event)
? event
: utils.is.htmlElement(form) && form.getAttribute('aria-hidden') === 'true';
const show = utils.is.boolean(event) ? event : utils.is.htmlElement(form) && form.getAttribute('aria-hidden') === 'true';
if (utils.is.event(event)) {
const isMenuItem = utils.is.htmlElement(form) && form.contains(event.target);
@ -899,10 +887,7 @@ const controls = {
}
// Create the container
const container = utils.createElement(
'div',
utils.getAttributesFromSelector(this.config.selectors.controls.wrapper)
);
const container = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.controls.wrapper));
// Restart button
if (this.config.controls.includes('restart')) {
@ -927,10 +912,7 @@ const controls = {
// Progress
if (this.config.controls.includes('progress')) {
const progress = utils.createElement(
'span',
utils.getAttributesFromSelector(this.config.selectors.progress)
);
const progress = utils.createElement('span', utils.getAttributesFromSelector(this.config.selectors.progress));
// Seek range slider
const seek = controls.createRange.call(this, 'seek', {
@ -1228,13 +1210,7 @@ const controls = {
if (this.config.tooltips.controls) {
const labels = utils.getElements.call(
this,
[
this.config.selectors.controls.wrapper,
' ',
this.config.selectors.labels,
' .',
this.config.classNames.hidden,
].join('')
[this.config.selectors.controls.wrapper, ' ', this.config.selectors.labels, ' .', this.config.classNames.hidden].join('')
);
Array.from(labels).forEach(label => {

View File

@ -108,19 +108,7 @@ const defaults = {
},
// Default controls
controls: [
'play-large',
'play',
'progress',
'current-time',
'mute',
'volume',
'captions',
'settings',
'pip',
'airplay',
'fullscreen',
],
controls: ['play-large', 'play', 'progress', 'current-time', 'mute', 'volume', 'captions', 'settings', 'pip', 'airplay', 'fullscreen'],
settings: ['captions', 'quality', 'speed', 'loop'],
// Localisation

View File

@ -35,11 +35,7 @@ const fullscreen = {
prefix,
// Check if we can use it
enabled:
document.fullscreenEnabled ||
document.webkitFullscreenEnabled ||
document.mozFullScreenEnabled ||
document.msFullscreenEnabled,
enabled: document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled,
// Yet again Microsoft awesomeness,
// Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes
@ -73,9 +69,7 @@ const fullscreen = {
const target = utils.is.nullOrUndefined(element) ? document.body : element;
return !prefix.length
? target.requestFullScreen()
: target[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
return !prefix.length ? target.requestFullScreen() : target[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
},
// Bail from fullscreen
@ -84,9 +78,7 @@ const fullscreen = {
return false;
}
return !prefix.length
? document.cancelFullScreen()
: document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();
return !prefix.length ? document.cancelFullScreen() : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();
},
// Get the current element

View File

@ -47,29 +47,7 @@ const listeners = {
// Reset on keyup
if (pressed) {
// Which keycodes should we prevent default
const preventDefault = [
48,
49,
50,
51,
52,
53,
54,
56,
57,
32,
75,
38,
40,
77,
39,
37,
70,
67,
73,
76,
79,
];
const preventDefault = [48, 49, 50, 51, 52, 53, 54, 56, 57, 32, 75, 38, 40, 77, 39, 37, 70, 67, 73, 76, 79];
// Check focused element
// and if the focused element is not editable (e.g. text input)
@ -212,13 +190,9 @@ const listeners = {
// Toggle controls visibility based on mouse movement
if (this.config.hideControls) {
// Toggle controls on mouse events and entering fullscreen
utils.on(
this.elements.container,
'mouseenter mouseleave mousemove touchstart touchend touchmove enterfullscreen exitfullscreen',
event => {
this.toggleControls(event);
}
);
utils.on(this.elements.container, 'mouseenter mouseleave mousemove touchstart touchend touchmove enterfullscreen exitfullscreen', event => {
this.toggleControls(event);
});
}
// Handle user exiting fullscreen by escaping etc
@ -512,9 +486,7 @@ const listeners = {
}
// Seek tooltip
utils.on(this.elements.progress, 'mouseenter mouseleave mousemove', event =>
controls.updateSeekTooltip.call(this, event)
);
utils.on(this.elements.progress, 'mouseenter mouseleave mousemove', event => controls.updateSeekTooltip.call(this, event));
// Toggle controls visibility based on mouse movement
if (this.config.hideControls) {

View File

@ -31,18 +31,10 @@ const media = {
if (this.supported.ui) {
// Check for picture-in-picture support
utils.toggleClass(
this.elements.container,
this.config.classNames.pip.supported,
support.pip && this.type === 'video'
);
utils.toggleClass(this.elements.container, this.config.classNames.pip.supported, support.pip && this.type === 'video');
// Check for airplay support
utils.toggleClass(
this.elements.container,
this.config.classNames.airplay.supported,
support.airplay && this.isHTML5
);
utils.toggleClass(this.elements.container, this.config.classNames.airplay.supported, support.airplay && this.isHTML5);
// If there's no autoplay attribute, assume the video is stopped and add state class
utils.toggleClass(this.elements.container, this.config.classNames.stopped, this.config.autoplay);

View File

@ -208,11 +208,6 @@ const vimeo = {
player.config.autopause = state;
});
// Get available speeds
if (player.config.controls.includes('settings') && player.config.settings.includes('speed')) {
controls.setSpeedMenu.call(player);
}
// Get title
player.embed.getVideoTitle().then(title => {
player.config.title = title;

View File

@ -143,8 +143,7 @@ const youtube = {
case 101:
case 150:
detail.message =
'The owner of the requested video does not allow it to be played in embedded players.';
detail.message = 'The owner of the requested video does not allow it to be played in embedded players.';
break;
default:
@ -282,9 +281,7 @@ const youtube = {
});
// Get available speeds
if (player.config.controls.includes('settings') && player.config.settings.includes('speed')) {
controls.setSpeedMenu.call(player, instance.getAvailablePlaybackRates());
}
player.options.speed = instance.getAvailablePlaybackRates();
// Set the tabindex to avoid focus entering iframe
if (player.supported.ui) {

View File

@ -56,7 +56,7 @@ class Plyr {
options,
(() => {
try {
return JSON.parse(this.media.getAttribute('data-plyr'));
return JSON.parse(this.media.getAttribute('data-plyr-config'));
} catch (e) {
return null;
}
@ -146,13 +146,19 @@ class Plyr {
// Supported: video, audio, vimeo, youtube
const type = this.media.tagName.toLowerCase();
// Embed attributes
const attributes = {
provider: 'data-plyr-provider',
id: 'data-plyr-provider-id',
};
// Different setup based on type
switch (type) {
// TODO: Handle passing an iframe for true progressive enhancement
// case 'iframe':
case 'div':
this.type = this.media.getAttribute('data-type');
this.embedId = this.media.getAttribute('data-video-id');
this.type = this.media.getAttribute(attributes.provider);
this.embedId = this.media.getAttribute(attributes.id);
if (utils.is.empty(this.type)) {
this.console.error('Setup failed: embed type missing');
@ -165,8 +171,9 @@ class Plyr {
}
// Clean up
this.media.removeAttribute('data-type');
this.media.removeAttribute('data-video-id');
this.media.removeAttribute(attributes.provider);
this.media.removeAttribute(attributes.id);
break;
case 'video':

View File

@ -116,11 +116,7 @@ const source = {
}
// Restore class hooks
utils.toggleClass(
this.elements.container,
this.config.classNames.captions.active,
this.supported.ui && this.captions.enabled
);
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, this.supported.ui && this.captions.enabled);
ui.addStyleHook.call(this);

View File

@ -302,12 +302,7 @@ const ui = {
const invert = !utils.is.htmlElement(this.elements.display.duration) && this.config.invertTime;
// Duration
ui.updateTimeDisplay.call(
this,
this.elements.display.currentTime,
invert ? this.duration - this.currentTime : this.currentTime,
invert
);
ui.updateTimeDisplay.call(this, this.elements.display.currentTime, invert ? this.duration - this.currentTime : this.currentTime, invert);
// Ignore updates while seeking
if (event && event.type === 'timeupdate' && this.media.seeking) {

View File

@ -41,9 +41,7 @@ const utils = {
return this.instanceof(input, window.TextTrackCue) || this.instanceof(input, window.VTTCue);
},
track(input) {
return (
this.instanceof(input, window.TextTrack) || (!this.nullOrUndefined(input) && this.string(input.kind))
);
return this.instanceof(input, window.TextTrack) || (!this.nullOrUndefined(input) && this.string(input.kind));
},
nullOrUndefined(input) {
return input === null || typeof input === 'undefined';
@ -358,12 +356,7 @@ const utils = {
return Array.from(document.querySelectorAll(selector)).includes(this);
}
const matches =
prototype.matches ||
prototype.webkitMatchesSelector ||
prototype.mozMatchesSelector ||
prototype.msMatchesSelector ||
match;
const matches = prototype.matches || prototype.webkitMatchesSelector || prototype.mozMatchesSelector || prototype.msMatchesSelector || match;
return matches.call(element, selector);
},
@ -417,9 +410,7 @@ const utils = {
// Seek tooltip
if (utils.is.htmlElement(this.elements.progress)) {
this.elements.display.seekTooltip = this.elements.progress.querySelector(
`.${this.config.classNames.tooltip}`
);
this.elements.display.seekTooltip = this.elements.progress.querySelector(`.${this.config.classNames.tooltip}`);
}
return true;