Play button as toggle button, tooltip changes, docs updated, fullscreen fix
This commit is contained in:
111
src/js/controls.js
vendored
111
src/js/controls.js
vendored
@ -92,8 +92,9 @@ const controls = {
|
||||
},
|
||||
|
||||
// Create hidden text label
|
||||
createLabel(type) {
|
||||
createLabel(type, attr) {
|
||||
let text = this.config.i18n[type];
|
||||
const attributes = Object.assign({}, attr);
|
||||
|
||||
switch (type) {
|
||||
case 'pip':
|
||||
@ -108,13 +109,13 @@ const controls = {
|
||||
break;
|
||||
}
|
||||
|
||||
return utils.createElement(
|
||||
'span',
|
||||
{
|
||||
class: this.config.classNames.hidden,
|
||||
},
|
||||
text
|
||||
);
|
||||
if ('class' in attributes) {
|
||||
attributes.class += ` ${this.config.classNames.hidden}`;
|
||||
} else {
|
||||
attributes.class = this.config.classNames.hidden;
|
||||
}
|
||||
|
||||
return utils.createElement('span', attributes, text);
|
||||
},
|
||||
|
||||
// Create a badge
|
||||
@ -145,16 +146,19 @@ const controls = {
|
||||
const button = utils.createElement('button');
|
||||
const attributes = Object.assign({}, attr);
|
||||
let type = buttonType;
|
||||
let iconDefault;
|
||||
let iconToggled;
|
||||
let labelKey;
|
||||
|
||||
let toggle = false;
|
||||
let label;
|
||||
let icon;
|
||||
let labelPressed;
|
||||
let iconPressed;
|
||||
|
||||
if (!('type' in attributes)) {
|
||||
attributes.type = 'button';
|
||||
}
|
||||
|
||||
if ('class' in attributes) {
|
||||
if (attributes.class.indexOf(this.config.classNames.control) === -1) {
|
||||
if (attributes.class.includes(this.config.classNames.control)) {
|
||||
attributes.class += ` ${this.config.classNames.control}`;
|
||||
}
|
||||
} else {
|
||||
@ -163,57 +167,71 @@ const controls = {
|
||||
|
||||
// Large play button
|
||||
switch (type) {
|
||||
case 'play':
|
||||
toggle = true;
|
||||
label = 'play';
|
||||
labelPressed = 'pause';
|
||||
icon = 'play';
|
||||
iconPressed = 'pause';
|
||||
break;
|
||||
|
||||
case 'mute':
|
||||
labelKey = 'toggleMute';
|
||||
iconDefault = 'volume';
|
||||
iconToggled = 'muted';
|
||||
toggle = true;
|
||||
label = 'mute';
|
||||
labelPressed = 'unmute';
|
||||
icon = 'volume';
|
||||
iconPressed = 'muted';
|
||||
break;
|
||||
|
||||
case 'captions':
|
||||
labelKey = 'toggleCaptions';
|
||||
iconDefault = 'captions-off';
|
||||
iconToggled = 'captions-on';
|
||||
toggle = true;
|
||||
label = 'enableCaptions';
|
||||
labelPressed = 'disableCaptions';
|
||||
icon = 'captions-off';
|
||||
iconPressed = 'captions-on';
|
||||
break;
|
||||
|
||||
case 'fullscreen':
|
||||
labelKey = 'toggleFullscreen';
|
||||
iconDefault = 'enter-fullscreen';
|
||||
iconToggled = 'exit-fullscreen';
|
||||
toggle = true;
|
||||
label = 'enterFullscreen';
|
||||
labelPressed = 'exitFullscreen';
|
||||
icon = 'enter-fullscreen';
|
||||
iconPressed = 'exit-fullscreen';
|
||||
break;
|
||||
|
||||
case 'play-large':
|
||||
attributes.class = 'plyr__play-large';
|
||||
attributes.class += ` ${this.config.classNames.control}--overlaid`;
|
||||
type = 'play';
|
||||
labelKey = 'play';
|
||||
iconDefault = 'play';
|
||||
label = 'play';
|
||||
icon = 'play';
|
||||
break;
|
||||
|
||||
default:
|
||||
labelKey = type;
|
||||
iconDefault = type;
|
||||
label = type;
|
||||
icon = type;
|
||||
}
|
||||
|
||||
// Setup toggle icon and labels
|
||||
if (toggle) {
|
||||
// Icon
|
||||
button.appendChild(controls.createIcon.call(this, iconPressed, { class: 'icon--pressed' }));
|
||||
button.appendChild(controls.createIcon.call(this, icon, { class: 'icon--not-pressed' }));
|
||||
|
||||
// Label/Tooltip
|
||||
button.appendChild(controls.createLabel.call(this, labelPressed, { class: 'label--pressed' }));
|
||||
button.appendChild(controls.createLabel.call(this, label, { class: 'label--not-pressed' }));
|
||||
|
||||
// Add aria attributes
|
||||
attributes['aria-pressed'] = false;
|
||||
attributes['aria-label'] = this.config.i18n[label];
|
||||
} else {
|
||||
button.appendChild(controls.createIcon.call(this, icon));
|
||||
button.appendChild(controls.createLabel.call(this, label));
|
||||
}
|
||||
|
||||
// Merge attributes
|
||||
utils.extend(attributes, utils.getAttributesFromSelector(this.config.selectors.buttons[type], attributes));
|
||||
|
||||
// Add toggle icon if needed
|
||||
if (utils.is.string(iconToggled)) {
|
||||
button.appendChild(
|
||||
controls.createIcon.call(this, iconToggled, {
|
||||
class: 'icon--pressed',
|
||||
})
|
||||
);
|
||||
button.appendChild(
|
||||
controls.createIcon.call(this, iconDefault, {
|
||||
class: 'icon--not-pressed',
|
||||
})
|
||||
);
|
||||
} else {
|
||||
button.appendChild(controls.createIcon.call(this, iconDefault));
|
||||
}
|
||||
|
||||
button.appendChild(controls.createLabel.call(this, labelKey));
|
||||
|
||||
utils.setAttributes(button, attributes);
|
||||
|
||||
this.elements.buttons[type] = button;
|
||||
@ -909,10 +927,10 @@ const controls = {
|
||||
container.appendChild(controls.createButton.call(this, 'rewind'));
|
||||
}
|
||||
|
||||
// Play Pause button
|
||||
// Play/Pause button
|
||||
if (this.config.controls.includes('play')) {
|
||||
container.appendChild(controls.createButton.call(this, 'play'));
|
||||
container.appendChild(controls.createButton.call(this, 'pause'));
|
||||
// container.appendChild(controls.createButton.call(this, 'pause'));
|
||||
}
|
||||
|
||||
// Fast forward button
|
||||
@ -1233,6 +1251,7 @@ const controls = {
|
||||
Array.from(labels).forEach(label => {
|
||||
utils.toggleClass(label, this.config.classNames.hidden, false);
|
||||
utils.toggleClass(label, this.config.classNames.tooltip, true);
|
||||
label.setAttribute('role', 'tooltip');
|
||||
});
|
||||
}
|
||||
},
|
||||
|
@ -133,9 +133,13 @@ const defaults = {
|
||||
currentTime: 'Current time',
|
||||
duration: 'Duration',
|
||||
volume: 'Volume',
|
||||
toggleMute: 'Toggle Mute',
|
||||
toggleCaptions: 'Toggle Captions',
|
||||
toggleFullscreen: 'Toggle Fullscreen',
|
||||
mute: 'Mute',
|
||||
unmute: 'Unmute',
|
||||
enableCaptions: 'Enable captions',
|
||||
disableCaptions: 'Disable captions',
|
||||
fullscreen: 'Fullscreen',
|
||||
enterFullscreen: 'Enter fullscreen',
|
||||
exitFullscreen: 'Exit fullscreen',
|
||||
frameTitle: 'Player for {title}',
|
||||
captions: 'Captions',
|
||||
settings: 'Settings',
|
||||
|
@ -217,11 +217,11 @@ const listeners = {
|
||||
}
|
||||
|
||||
// Handle user exiting fullscreen by escaping etc
|
||||
/* if (fullscreen.enabled) {
|
||||
if (fullscreen.enabled) {
|
||||
utils.on(document, fullscreen.eventType, event => {
|
||||
this.toggleFullscreen(event);
|
||||
});
|
||||
} */
|
||||
}
|
||||
},
|
||||
|
||||
// Listen for media events
|
||||
@ -372,24 +372,12 @@ const listeners = {
|
||||
}
|
||||
};
|
||||
|
||||
// Click play/pause helper
|
||||
const togglePlay = () => {
|
||||
const play = this.togglePlay();
|
||||
|
||||
// Determine which buttons
|
||||
const target = this.elements.buttons[play ? 'pause' : 'play'];
|
||||
|
||||
// Transfer focus
|
||||
if (utils.is.htmlElement(target)) {
|
||||
target.focus();
|
||||
}
|
||||
};
|
||||
|
||||
// Play
|
||||
utils.on(this.elements.buttons.play, 'click', event => proxy(event, 'play', togglePlay));
|
||||
|
||||
// Pause
|
||||
utils.on(this.elements.buttons.pause, 'click', event => proxy(event, 'pause', togglePlay));
|
||||
// Play/pause toggle
|
||||
utils.on(this.elements.buttons.play, 'click', event =>
|
||||
proxy(event, 'play', () => {
|
||||
this.togglePlay();
|
||||
})
|
||||
);
|
||||
|
||||
// Pause
|
||||
utils.on(this.elements.buttons.restart, 'click', event =>
|
||||
@ -412,21 +400,21 @@ const listeners = {
|
||||
})
|
||||
);
|
||||
|
||||
// Mute
|
||||
// Mute toggle
|
||||
utils.on(this.elements.buttons.mute, 'click', event =>
|
||||
proxy(event, 'mute', () => {
|
||||
this.muted = !this.muted;
|
||||
})
|
||||
);
|
||||
|
||||
// Captions
|
||||
// Captions toggle
|
||||
utils.on(this.elements.buttons.captions, 'click', event =>
|
||||
proxy(event, 'captions', () => {
|
||||
this.toggleCaptions();
|
||||
})
|
||||
);
|
||||
|
||||
// Fullscreen
|
||||
// Fullscreen toggle
|
||||
utils.on(this.elements.buttons.fullscreen, 'click', event =>
|
||||
proxy(event, 'fullscreen', () => {
|
||||
this.toggleFullscreen();
|
||||
|
@ -710,22 +710,17 @@ class Plyr {
|
||||
toggleFullscreen(event) {
|
||||
// Check for native support
|
||||
if (fullscreen.enabled) {
|
||||
// If it's a fullscreen change event, update the UI
|
||||
if (utils.is.event(event) && event.type === fullscreen.eventType) {
|
||||
// If it's a fullscreen change event, update the state
|
||||
this.fullscreen.active = fullscreen.isFullScreen(this.elements.container);
|
||||
} else {
|
||||
// Else it's a user request to enter or exit
|
||||
if (!this.fullscreen.active) {
|
||||
// Request full screen
|
||||
fullscreen.requestFullScreen(this.elements.container);
|
||||
} else {
|
||||
// Bail from fullscreen
|
||||
fullscreen.cancelFullScreen();
|
||||
}
|
||||
|
||||
// Check if we're actually full screen (it could fail)
|
||||
this.fullscreen.active = fullscreen.isFullScreen(this.elements.container);
|
||||
|
||||
return this;
|
||||
}
|
||||
} else {
|
||||
@ -754,7 +749,7 @@ class Plyr {
|
||||
}
|
||||
|
||||
// Set button state
|
||||
if (this.elements.buttons && this.elements.buttons.fullscreen) {
|
||||
if (utils.is.htmlElement(this.elements.buttons.fullscreen)) {
|
||||
utils.toggleState(this.elements.buttons.fullscreen, this.fullscreen.active);
|
||||
}
|
||||
|
||||
|
@ -139,10 +139,14 @@ const ui = {
|
||||
// Check playing state
|
||||
checkPlaying() {
|
||||
window.setTimeout(() => {
|
||||
// Class hooks
|
||||
utils.toggleClass(this.elements.container, this.config.classNames.playing, this.playing);
|
||||
|
||||
utils.toggleClass(this.elements.container, this.config.classNames.stopped, this.paused);
|
||||
|
||||
// Set aria state
|
||||
Array.from(this.elements.buttons.play).forEach(button => utils.toggleState(button, this.playing));
|
||||
|
||||
// Toggle controls
|
||||
this.toggleControls(!this.playing);
|
||||
}, 100);
|
||||
},
|
||||
|
@ -20,11 +20,6 @@
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
// Hide toggle icons by default
|
||||
.icon--pressed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
// Default focus
|
||||
&:focus {
|
||||
outline: 0;
|
||||
@ -37,10 +32,10 @@
|
||||
}
|
||||
|
||||
// Change icons on state change
|
||||
.plyr__control[aria-pressed='true'] .icon--pressed {
|
||||
display: block;
|
||||
}
|
||||
.plyr__control[aria-pressed='true'] .icon--not-pressed {
|
||||
.plyr__control[aria-pressed='false'] .icon--pressed,
|
||||
.plyr__control[aria-pressed='true'] .icon--not-pressed,
|
||||
.plyr__control[aria-pressed='false'] .label--pressed,
|
||||
.plyr__control[aria-pressed='true'] .label--not-pressed {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@ -55,7 +50,7 @@
|
||||
}
|
||||
|
||||
// Large play button (video only)
|
||||
.plyr__play-large {
|
||||
.plyr__control--overlaid {
|
||||
display: none;
|
||||
position: absolute;
|
||||
z-index: 3;
|
||||
@ -68,37 +63,25 @@
|
||||
border-radius: 100%;
|
||||
box-shadow: 0 1px 1px fade(#000, 15%);
|
||||
color: @plyr-video-control-color;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
svg {
|
||||
position: relative;
|
||||
left: 2px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
display: block;
|
||||
fill: currentColor;
|
||||
pointer-events: none;
|
||||
width: @plyr-control-icon-size-large;
|
||||
height: @plyr-control-icon-size-large;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
background: @plyr-video-control-bg-hover;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
&.plyr__tab-focus {
|
||||
.plyr-tab-focus();
|
||||
}
|
||||
}
|
||||
|
||||
.plyr--full-ui.plyr--video .plyr__play-large {
|
||||
.plyr--full-ui.plyr--video .plyr__control--overlaid {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.plyr--playing .plyr__play-large {
|
||||
.plyr--playing .plyr__control--overlaid {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
@ -91,17 +91,6 @@
|
||||
color: @plyr-audio-control-color;
|
||||
}
|
||||
|
||||
// States
|
||||
.plyr__controls [data-plyr='pause'] {
|
||||
display: none;
|
||||
}
|
||||
.plyr--playing .plyr__controls [data-plyr='play'] {
|
||||
display: none;
|
||||
}
|
||||
.plyr--playing .plyr__controls [data-plyr='pause'] {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
// Some options are hidden by default
|
||||
.plyr [data-plyr='captions'],
|
||||
.plyr [data-plyr='pip'],
|
||||
|
@ -17,12 +17,9 @@
|
||||
@plyr-font-size-small: 14px;
|
||||
@plyr-font-size-time: 14px;
|
||||
@plyr-font-size-badge: 10px;
|
||||
|
||||
@plyr-font-weight-regular: 500;
|
||||
@plyr-font-weight-bold: 600;
|
||||
|
||||
@plyr-line-height: 1.7;
|
||||
|
||||
@plyr-font-smoothing: on;
|
||||
|
||||
// Focus
|
||||
@ -38,6 +35,7 @@
|
||||
|
||||
// Controls
|
||||
@plyr-control-icon-size: 18px;
|
||||
@plyr-control-icon-size-large: 20px;
|
||||
@plyr-control-spacing: 10px;
|
||||
@plyr-control-padding: (@plyr-control-spacing * 0.7);
|
||||
@plyr-video-controls-bg: #000;
|
||||
@ -49,6 +47,7 @@
|
||||
@plyr-audio-control-color: #565d64;
|
||||
@plyr-audio-control-color-hover: #fff;
|
||||
@plyr-audio-control-bg-hover: @plyr-color-main;
|
||||
|
||||
// Tooltips
|
||||
@plyr-tooltip-bg: fade(#fff, 90%);
|
||||
@plyr-tooltip-color: #565d64;
|
||||
|
Reference in New Issue
Block a user