This commit is contained in:
Sam Potts 2018-05-28 10:19:07 +10:00
parent cd51788b98
commit 90c5735904
19 changed files with 123 additions and 149 deletions

View File

@ -105,7 +105,7 @@ const controls = `
<svg role="presentation"><use xlink:href="#plyr-rewind"></use></svg>
<span class="plyr__tooltip" role="tooltip">Rewind {seektime} secs</span>
</button>
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Play, {title}" data-plyr="play">
<button type="button" class="plyr__control" aria-label="Play, {title}" data-plyr="play">
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-pause"></use></svg>
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-play"></use></svg>
<span class="label--pressed plyr__tooltip" role="tooltip">Pause</span>
@ -123,7 +123,7 @@ const controls = `
</div>
<div class="plyr__time plyr__time--current" aria-label="Current time">00:00</div>
<div class="plyr__time plyr__time--duration" aria-label="Duration">00:00</div>
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Mute" data-plyr="mute">
<button type="button" class="plyr__control" aria-label="Mute" data-plyr="mute">
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-muted"></use></svg>
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-volume"></use></svg>
<span class="label--pressed plyr__tooltip" role="tooltip">Unmute</span>
@ -133,13 +133,13 @@ const controls = `
<label for="plyr-volume-{id}" class="plyr__sr-only">Volume</label>
<input data-plyr="volume" type="range" min="0" max="1" step="0.05" value="1" autocomplete="off" id="plyr-volume-{id}">
</div>
<button type="button" class="plyr__control" aria-pressed="true" aria-label="Enable captions" data-plyr="captions">
<button type="button" class="plyr__control" aria-label="Enable captions" data-plyr="captions">
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-captions-on"></use></svg>
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-captions-off"></use></svg>
<span class="label--pressed plyr__tooltip" role="tooltip">Disable captions</span>
<span class="label--not-pressed plyr__tooltip" role="tooltip">Enable captions</span>
</button>
<button type="button" class="plyr__control" aria-pressed="false" aria-label="Enter fullscreen" data-plyr="fullscreen">
<button type="button" class="plyr__control" aria-label="Enter fullscreen" data-plyr="fullscreen">
<svg class="icon--pressed" role="presentation"><use xlink:href="#plyr-exit-fullscreen"></use></svg>
<svg class="icon--not-pressed" role="presentation"><use xlink:href="#plyr-enter-fullscreen"></use></svg>
<span class="label--pressed plyr__tooltip" role="tooltip">Exit fullscreen</span>

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

46
dist/plyr.js vendored
View File

@ -1098,31 +1098,6 @@ var utils = {
},
// Toggle aria-pressed state on a toggle button
// http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles
toggleState: function toggleState(element, input) {
// If multiple elements passed
if (utils.is.array(element) || utils.is.nodeList(element)) {
Array.from(element).forEach(function (target) {
return utils.toggleState(target, input);
});
return;
}
// Bail if no target
if (!utils.is.element(element)) {
return;
}
// Get state
var pressed = element.getAttribute('aria-pressed') === 'true';
var state = utils.is.boolean(input) ? input : !pressed;
// Set the attribute on target
element.setAttribute('aria-pressed', state);
},
// Format string
format: function format(input) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
@ -3590,6 +3565,10 @@ var defaults$1 = {
// Only allow one media playing at once (vimeo only)
autopause: true,
// Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)
// TODO: Remove iosNative fullscreen option in favour of this (logic needs work)
playsinline: true,
// Default time to skip when rewind/fast forward
seekTime: 10,
@ -3835,6 +3814,7 @@ var defaults$1 = {
posterEnabled: 'plyr__poster-enabled',
ads: 'plyr__ads',
control: 'plyr__control',
controlPressed: 'plyr__control--pressed',
playing: 'plyr--playing',
paused: 'plyr--paused',
stopped: 'plyr--stopped',
@ -3905,7 +3885,7 @@ function onChange() {
// Update toggle button
var button = this.player.elements.buttons.fullscreen;
if (utils.is.element(button)) {
utils.toggleState(button, this.active);
button.pressed = this.active;
}
// Trigger an event
@ -4320,13 +4300,17 @@ var ui = {
// Check playing state
checkPlaying: function checkPlaying(event) {
var _this3 = this;
// Class hooks
utils.toggleClass(this.elements.container, this.config.classNames.playing, this.playing);
utils.toggleClass(this.elements.container, this.config.classNames.paused, this.paused);
utils.toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);
// Set ARIA state
utils.toggleState(this.elements.buttons.play, this.playing);
// Set state
Array.from(this.elements.buttons.play).forEach(function (target) {
target.pressed = _this3.playing;
});
// Only update controls on non timeupdate events
if (utils.is.event(event) && event.type === 'timeupdate') {
@ -4340,7 +4324,7 @@ var ui = {
// Check if media is loading
checkLoading: function checkLoading(event) {
var _this3 = this;
var _this4 = this;
this.loading = ['stalled', 'waiting'].includes(event.type);
@ -4350,10 +4334,10 @@ var ui = {
// Timer to prevent flicker when seeking
this.timers.loading = setTimeout(function () {
// Update progress bar loading class state
utils.toggleClass(_this3.elements.container, _this3.config.classNames.loading, _this3.loading);
utils.toggleClass(_this4.elements.container, _this4.config.classNames.loading, _this4.loading);
// Update controls visibility
ui.toggleControls.call(_this3);
ui.toggleControls.call(_this4);
}, this.loading ? 250 : 0);
},

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

@ -6504,31 +6504,6 @@ var utils = {
},
// Toggle aria-pressed state on a toggle button
// http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles
toggleState: function toggleState(element, input) {
// If multiple elements passed
if (utils.is.array(element) || utils.is.nodeList(element)) {
Array.from(element).forEach(function (target) {
return utils.toggleState(target, input);
});
return;
}
// Bail if no target
if (!utils.is.element(element)) {
return;
}
// Get state
var pressed = element.getAttribute('aria-pressed') === 'true';
var state = utils.is.boolean(input) ? input : !pressed;
// Set the attribute on target
element.setAttribute('aria-pressed', state);
},
// Format string
format: function format(input) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
@ -7432,9 +7407,6 @@ var controls = {
// 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;
} else {
button.appendChild(controls.createIcon.call(this, icon));
button.appendChild(controls.createLabel.call(this, label));
@ -7456,6 +7428,40 @@ var controls = {
this.elements.buttons[type] = button;
}
/* // Toggle aria-pressed state on a toggle button
// http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles
toggleState(element, input) {
// If multiple elements passed
if (utils.is.array(element) || utils.is.nodeList(element)) {
Array.from(element).forEach(target => utils.toggleState(target, input));
return;
}
// Bail if no target
if (!utils.is.element(element)) {
return;
}
// Get state
const pressed = element.classList.contains(this.config.className;
const state = utils.is.boolean(input) ? input : !pressed;
// Set the attribute on target
element.setAttribute('aria-pressed', state);
}, */
var className = this.config.classNames.controlPressed;
Object.defineProperty(button, 'pressed', {
enumerable: true,
configurable: true,
get: function get() {
return utils.hasClass(button, className);
},
set: function set() {
var pressed = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
utils.toggleClass(button, className, pressed);
}
});
return button;
},
@ -7616,7 +7622,7 @@ var controls = {
// Update mute state
if (utils.is.element(this.elements.buttons.mute)) {
utils.toggleState(this.elements.buttons.mute, this.muted || this.volume === 0);
this.elements.buttons.mute.pressed = this.muted || this.volume === 0;
}
},
@ -8931,7 +8937,7 @@ var captions = {
if (active) {
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, true);
utils.toggleState(this.elements.buttons.captions, true);
this.elements.buttons.captions.pressed = true;
}
}
};
@ -8996,6 +9002,10 @@ var defaults$1 = {
// Only allow one media playing at once (vimeo only)
autopause: true,
// Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)
// TODO: Remove iosNative fullscreen option in favour of this (logic needs work)
playsinline: true,
// Default time to skip when rewind/fast forward
seekTime: 10,
@ -9241,6 +9251,7 @@ var defaults$1 = {
posterEnabled: 'plyr__poster-enabled',
ads: 'plyr__ads',
control: 'plyr__control',
controlPressed: 'plyr__control--pressed',
playing: 'plyr--playing',
paused: 'plyr--paused',
stopped: 'plyr--stopped',
@ -9311,7 +9322,7 @@ function onChange() {
// Update toggle button
var button = this.player.elements.buttons.fullscreen;
if (utils.is.element(button)) {
utils.toggleState(button, this.active);
button.pressed = this.active;
}
// Trigger an event
@ -9726,13 +9737,17 @@ var ui = {
// Check playing state
checkPlaying: function checkPlaying(event) {
var _this3 = this;
// Class hooks
utils.toggleClass(this.elements.container, this.config.classNames.playing, this.playing);
utils.toggleClass(this.elements.container, this.config.classNames.paused, this.paused);
utils.toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);
// Set ARIA state
utils.toggleState(this.elements.buttons.play, this.playing);
// Set state
Array.from(this.elements.buttons.play).forEach(function (target) {
target.pressed = _this3.playing;
});
// Only update controls on non timeupdate events
if (utils.is.event(event) && event.type === 'timeupdate') {
@ -9746,7 +9761,7 @@ var ui = {
// Check if media is loading
checkLoading: function checkLoading(event) {
var _this3 = this;
var _this4 = this;
this.loading = ['stalled', 'waiting'].includes(event.type);
@ -9756,10 +9771,10 @@ var ui = {
// Timer to prevent flicker when seeking
this.timers.loading = setTimeout(function () {
// Update progress bar loading class state
utils.toggleClass(_this3.elements.container, _this3.config.classNames.loading, _this3.loading);
utils.toggleClass(_this4.elements.container, _this4.config.classNames.loading, _this4.loading);
// Update controls visibility
ui.toggleControls.call(_this3);
ui.toggleControls.call(_this4);
}, this.loading ? 250 : 0);
},
@ -12711,7 +12726,7 @@ var Plyr = function () {
this.captions.active = show;
// Toggle state
utils.toggleState(this.elements.buttons.captions, this.captions.active);
this.elements.buttons.captions.pressed = this.captions.active;
// Add class hook
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, this.captions.active);

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

@ -262,7 +262,7 @@ const captions = {
if (active) {
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, true);
utils.toggleState(this.elements.buttons.captions, true);
this.elements.buttons.captions.pressed = true;
}
},
};

47
src/js/controls.js vendored
View File

@ -243,9 +243,6 @@ const controls = {
// 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;
} else {
button.appendChild(controls.createIcon.call(this, icon));
button.appendChild(controls.createLabel.call(this, label));
@ -267,22 +264,23 @@ const controls = {
this.elements.buttons[type] = button;
}
// Toggle classname when pressed property is set
const className = this.config.classNames.controlPressed;
Object.defineProperty(button, 'pressed', {
enumerable: true,
get() {
return utils.hasClass(button, className);
},
set(pressed = false) {
utils.toggleClass(button, className, pressed);
},
});
return button;
},
// Create an <input type='range'>
createRange(type, attributes) {
// Seek label
const label = utils.createElement(
'label',
{
for: attributes.id,
id: `${attributes.id}-label`,
class: this.config.classNames.hidden,
},
i18n.get(type, this.config),
);
// Seek input
const input = utils.createElement(
'input',
@ -297,7 +295,7 @@ const controls = {
autocomplete: 'off',
// A11y fixes for https://github.com/sampotts/plyr/issues/905
role: 'slider',
'aria-labelledby': `${attributes.id}-label`,
'aria-label': i18n.get(type, this.config),
'aria-valuemin': 0,
'aria-valuemax': 100,
'aria-valuenow': 0,
@ -311,10 +309,7 @@ const controls = {
// Set the fill for webkit now
controls.updateRangeFill.call(this, input);
return {
label,
input,
};
return input;
},
// Create a <progress>
@ -435,7 +430,7 @@ const controls = {
// Update mute state
if (utils.is.element(this.elements.buttons.mute)) {
utils.toggleState(this.elements.buttons.mute, this.muted || this.volume === 0);
this.elements.buttons.mute.pressed = this.muted || this.volume === 0;
}
},
@ -1149,11 +1144,9 @@ const controls = {
const progress = utils.createElement('div', utils.getAttributesFromSelector(this.config.selectors.progress));
// Seek range slider
const seek = controls.createRange.call(this, 'seek', {
progress.appendChild(controls.createRange.call(this, 'seek', {
id: `plyr-seek-${data.id}`,
});
progress.appendChild(seek.label);
progress.appendChild(seek.input);
}));
// Buffer progress
progress.appendChild(controls.createProgress.call(this, 'buffer'));
@ -1207,15 +1200,13 @@ const controls = {
};
// Create the volume range slider
const range = controls.createRange.call(
volume.appendChild(controls.createRange.call(
this,
'volume',
utils.extend(attributes, {
id: `plyr-volume-${data.id}`,
}),
);
volume.appendChild(range.label);
volume.appendChild(range.input);
));
this.elements.volume = volume;

View File

@ -18,6 +18,10 @@ const defaults = {
// Only allow one media playing at once (vimeo only)
autopause: true,
// Allow inline playback on iOS (this effects YouTube/Vimeo - HTML5 requires the attribute present)
// TODO: Remove iosNative fullscreen option in favour of this (logic needs work)
playsinline: true,
// Default time to skip when rewind/fast forward
seekTime: 10,
@ -334,6 +338,7 @@ const defaults = {
posterEnabled: 'plyr__poster-enabled',
ads: 'plyr__ads',
control: 'plyr__control',
controlPressed: 'plyr__control--pressed',
playing: 'plyr--playing',
paused: 'plyr--paused',
stopped: 'plyr--stopped',

View File

@ -15,7 +15,7 @@ function onChange() {
// Update toggle button
const button = this.player.elements.buttons.fullscreen;
if (utils.is.element(button)) {
utils.toggleState(button, this.active);
button.pressed = this.active;
}
// Trigger an event

View File

@ -854,7 +854,7 @@ class Plyr {
this.captions.active = show;
// Toggle state
utils.toggleState(this.elements.buttons.captions, this.captions.active);
this.elements.buttons.captions.pressed = this.captions.active;
// Add class hook
utils.toggleClass(this.elements.container, this.config.classNames.captions.active, this.captions.active);

View File

@ -164,17 +164,16 @@ const ui = {
}
// Load the image, and set poster if successful
const loadPromise = utils.loadImage(poster)
.then(() => {
this.elements.poster.style.backgroundImage = `url('${poster}')`;
Object.assign(this.elements.poster.style, {
backgroundImage: `url('${poster}')`,
// Reset backgroundSize as well (since it can be set to "cover" for padded thumbnails for youtube)
backgroundSize: '',
});
ui.togglePoster.call(this, true);
return poster;
const loadPromise = utils.loadImage(poster).then(() => {
this.elements.poster.style.backgroundImage = `url('${poster}')`;
Object.assign(this.elements.poster.style, {
backgroundImage: `url('${poster}')`,
// Reset backgroundSize as well (since it can be set to "cover" for padded thumbnails for youtube)
backgroundSize: '',
});
ui.togglePoster.call(this, true);
return poster;
});
// Hide the element if the poster can't be loaded (otherwise it will just be a black element covering the video)
loadPromise.catch(() => ui.togglePoster.call(this, false));
@ -190,8 +189,10 @@ const ui = {
utils.toggleClass(this.elements.container, this.config.classNames.paused, this.paused);
utils.toggleClass(this.elements.container, this.config.classNames.stopped, this.stopped);
// Set ARIA state
utils.toggleState(this.elements.buttons.play, this.playing);
// Set state
Array.from(this.elements.buttons.play).forEach(target => {
target.pressed = this.playing;
});
// Only update controls on non timeupdate events
if (utils.is.event(event) && event.type === 'timeupdate') {

View File

@ -572,28 +572,6 @@ const utils = {
element.dispatchEvent(event);
},
// Toggle aria-pressed state on a toggle button
// http://www.ssbbartgroup.com/blog/how-not-to-misuse-aria-states-properties-and-roles
toggleState(element, input) {
// If multiple elements passed
if (utils.is.array(element) || utils.is.nodeList(element)) {
Array.from(element).forEach(target => utils.toggleState(target, input));
return;
}
// Bail if no target
if (!utils.is.element(element)) {
return;
}
// Get state
const pressed = element.getAttribute('aria-pressed') === 'true';
const state = utils.is.boolean(input) ? input : !pressed;
// Set the attribute on target
element.setAttribute('aria-pressed', state);
},
// Format string
format(input, ...args) {
if (utils.is.empty(input)) {

View File

@ -34,10 +34,10 @@
}
// Change icons on state change
.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 {
.plyr__control:not(.plyr__control--pressed) .icon--pressed,
.plyr__control.plyr__control--pressed .icon--not-pressed,
.plyr__control:not(.plyr__control--pressed) .label--pressed,
.plyr__control.plyr__control--pressed .label--not-pressed {
display: none;
}