Escape closes menu
This commit is contained in:
parent
58079393e6
commit
c8db1e55dd
157
dist/plyr.js
vendored
157
dist/plyr.js
vendored
@ -50,6 +50,9 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var isEvent = function isEvent(input) {
|
var isEvent = function isEvent(input) {
|
||||||
return instanceOf(input, Event);
|
return instanceOf(input, Event);
|
||||||
};
|
};
|
||||||
|
var isKeyboardEvent = function isKeyboardEvent(input) {
|
||||||
|
return instanceOf(input, KeyboardEvent);
|
||||||
|
};
|
||||||
var isCue = function isCue(input) {
|
var isCue = function isCue(input) {
|
||||||
return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
|
return instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
|
||||||
};
|
};
|
||||||
@ -93,6 +96,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
element: isElement,
|
element: isElement,
|
||||||
textNode: isTextNode,
|
textNode: isTextNode,
|
||||||
event: isEvent,
|
event: isEvent,
|
||||||
|
keyboardEvent: isKeyboardEvent,
|
||||||
cue: isCue,
|
cue: isCue,
|
||||||
track: isTrack,
|
track: isTrack,
|
||||||
url: isUrl,
|
url: isUrl,
|
||||||
@ -1797,7 +1801,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
this.listeners.bind(menuItem, 'click keyup', function (event) {
|
this.listeners.bind(menuItem, 'click keyup', function (event) {
|
||||||
if (event.type === 'keyup' && event.which !== 32) {
|
if (is.keyboardEvent(event) && event.which !== 32) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1823,7 +1827,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
controls.showMenuPanel.call(_this2, 'home', event.type === 'keyup');
|
controls.showMenuPanel.call(_this2, 'home', is.keyboardEvent(event));
|
||||||
}, type, false);
|
}, type, false);
|
||||||
|
|
||||||
controls.bindMenuItemShortcuts.call(this, menuItem, type);
|
controls.bindMenuItemShortcuts.call(this, menuItem, type);
|
||||||
@ -2422,13 +2426,18 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var show = is.boolean(input) ? input : is.element(popup) && popup.hasAttribute('hidden');
|
// True toggle by default
|
||||||
|
var show = is.element(popup) && popup.hasAttribute('hidden');
|
||||||
|
|
||||||
if (is.event(input)) {
|
if (is.boolean(input)) {
|
||||||
var isMenuItem = is.element(popup) && popup.contains(input.target);
|
show = input;
|
||||||
var isButton = input.target === this.elements.buttons.settings;
|
} else if (is.keyboardEvent(input) && input.which === 27) {
|
||||||
|
show = false;
|
||||||
|
} else if (is.event(input)) {
|
||||||
|
var isMenuItem = popup.contains(input.target);
|
||||||
|
var isButton = input.target === button;
|
||||||
|
|
||||||
// If the click was inside the form or if the click
|
// If the click was inside the menu or if the click
|
||||||
// wasn't the button or menu item and we're trying to
|
// wasn't the button or menu item and we're trying to
|
||||||
// show the menu (a doc click shouldn't show the menu)
|
// show the menu (a doc click shouldn't show the menu)
|
||||||
if (isMenuItem || !isMenuItem && !isButton && show) {
|
if (isMenuItem || !isMenuItem && !isButton && show) {
|
||||||
@ -2441,26 +2450,26 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set form and button attributes
|
// Set button attributes
|
||||||
if (is.element(button)) {
|
|
||||||
button.setAttribute('aria-expanded', show);
|
button.setAttribute('aria-expanded', show);
|
||||||
}
|
|
||||||
|
|
||||||
// Show the actual popup
|
// Show the actual popup
|
||||||
if (is.element(popup)) {
|
|
||||||
toggleHidden(popup, !show);
|
toggleHidden(popup, !show);
|
||||||
|
|
||||||
|
// Add class hook
|
||||||
toggleClass(this.elements.container, this.config.classNames.menu.open, show);
|
toggleClass(this.elements.container, this.config.classNames.menu.open, show);
|
||||||
|
|
||||||
// Focus the first item if key interaction
|
// Focus the first item if key interaction
|
||||||
if (show && is.event(input) && input.type === 'keyup') {
|
if (show && is.keyboardEvent(input)) {
|
||||||
var pane = Object.values(this.elements.settings.panels).find(function (pane) {
|
var pane = Object.values(this.elements.settings.panels).find(function (pane) {
|
||||||
return !pane.hidden;
|
return !pane.hidden;
|
||||||
});
|
});
|
||||||
var firstItem = pane.querySelector('[role^="menuitem"]');
|
var firstItem = pane.querySelector('[role^="menuitem"]');
|
||||||
|
|
||||||
setFocus.call(this, firstItem, true);
|
setFocus.call(this, firstItem, true);
|
||||||
}
|
}
|
||||||
|
// If closing, re-focus the button
|
||||||
|
else if (!show) {
|
||||||
|
setFocus.call(this, button, is.keyboardEvent(input));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -4340,6 +4349,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
key: 'handleKey',
|
key: 'handleKey',
|
||||||
value: function handleKey(event) {
|
value: function handleKey(event) {
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
|
var elements = player.elements;
|
||||||
|
|
||||||
var code = event.keyCode ? event.keyCode : event.which;
|
var code = event.keyCode ? event.keyCode : event.which;
|
||||||
var pressed = event.type === 'keydown';
|
var pressed = event.type === 'keydown';
|
||||||
@ -4371,7 +4381,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var focused = document.activeElement;
|
var focused = document.activeElement;
|
||||||
if (is.element(focused)) {
|
if (is.element(focused)) {
|
||||||
var editable = player.config.selectors.editable;
|
var editable = player.config.selectors.editable;
|
||||||
var seek = player.elements.inputs.seek;
|
var seek = elements.inputs.seek;
|
||||||
|
|
||||||
|
|
||||||
if (focused !== seek && matches(focused, editable)) {
|
if (focused !== seek && matches(focused, editable)) {
|
||||||
@ -4502,17 +4512,19 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
key: 'firstTouch',
|
key: 'firstTouch',
|
||||||
value: function firstTouch() {
|
value: function firstTouch() {
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
|
var elements = player.elements;
|
||||||
|
|
||||||
|
|
||||||
player.touch = true;
|
player.touch = true;
|
||||||
|
|
||||||
// Add touch class
|
// Add touch class
|
||||||
toggleClass(player.elements.container, player.config.classNames.isTouch, true);
|
toggleClass(elements.container, player.config.classNames.isTouch, true);
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
key: 'setTabFocus',
|
key: 'setTabFocus',
|
||||||
value: function setTabFocus(event) {
|
value: function setTabFocus(event) {
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
|
var elements = player.elements;
|
||||||
|
|
||||||
|
|
||||||
clearTimeout(this.focusTimer);
|
clearTimeout(this.focusTimer);
|
||||||
@ -4551,7 +4563,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var focused = document.activeElement;
|
var focused = document.activeElement;
|
||||||
|
|
||||||
// Ignore if current focus element isn't inside the player
|
// Ignore if current focus element isn't inside the player
|
||||||
if (!player.elements.container.contains(focused)) {
|
if (!elements.container.contains(focused)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4589,16 +4601,17 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
key: 'container',
|
key: 'container',
|
||||||
value: function container() {
|
value: function container() {
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
|
var elements = player.elements;
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
|
|
||||||
if (!player.config.keyboard.global && player.config.keyboard.focused) {
|
if (!player.config.keyboard.global && player.config.keyboard.focused) {
|
||||||
on.call(player, player.elements.container, 'keydown keyup', this.handleKey, false);
|
on.call(player, elements.container, 'keydown keyup', this.handleKey, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle controls on mouse events and entering fullscreen
|
// Toggle controls on mouse events and entering fullscreen
|
||||||
on.call(player, player.elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
on.call(player, elements.container, 'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen', function (event) {
|
||||||
var controls$$1 = player.elements.controls;
|
var controls$$1 = elements.controls;
|
||||||
|
|
||||||
// Remove button states for fullscreen
|
// Remove button states for fullscreen
|
||||||
|
|
||||||
@ -4634,6 +4647,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
key: 'media',
|
key: 'media',
|
||||||
value: function media() {
|
value: function media() {
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
|
var elements = player.elements;
|
||||||
|
|
||||||
// Time change on media
|
// Time change on media
|
||||||
|
|
||||||
@ -4649,8 +4663,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// Check for audio tracks on load
|
// Check for audio tracks on load
|
||||||
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
||||||
on.call(player, player.media, 'canplay', function () {
|
on.call(player, player.media, 'canplay', function () {
|
||||||
toggleHidden(player.elements.volume, !player.hasAudio);
|
toggleHidden(elements.volume, !player.hasAudio);
|
||||||
toggleHidden(player.elements.buttons.mute, !player.hasAudio);
|
toggleHidden(elements.buttons.mute, !player.hasAudio);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle the media finishing
|
// Handle the media finishing
|
||||||
@ -4711,8 +4725,8 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On click play, pause ore restart
|
// On click play, pause ore restart
|
||||||
on.call(player, player.elements.container, 'click touchstart', function (event) {
|
on.call(player, elements.container, 'click touchstart', function (event) {
|
||||||
var targets = [player.elements.container, wrapper];
|
var targets = [elements.container, wrapper];
|
||||||
|
|
||||||
// Ignore if click if not container or in video wrapper
|
// Ignore if click if not container or in video wrapper
|
||||||
if (!targets.includes(event.target) && !wrapper.contains(event.target)) {
|
if (!targets.includes(event.target) && !wrapper.contains(event.target)) {
|
||||||
@ -4721,7 +4735,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// First touch on touch devices will just show controls (if we're hiding controls)
|
// First touch on touch devices will just show controls (if we're hiding controls)
|
||||||
// If controls are shown then it'll toggle like a pointer device
|
// If controls are shown then it'll toggle like a pointer device
|
||||||
if (player.config.hideControls && player.touch && hasClass(player.elements.container, player.config.classNames.hideControls)) {
|
if (player.config.hideControls && player.touch && hasClass(elements.container, player.config.classNames.hideControls)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4736,7 +4750,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
|
|
||||||
// Disable right click
|
// Disable right click
|
||||||
if (player.supported.ui && player.config.disableContextMenu) {
|
if (player.supported.ui && player.config.disableContextMenu) {
|
||||||
on.call(player, player.elements.wrapper, 'contextmenu', function (event) {
|
on.call(player, elements.wrapper, 'contextmenu', function (event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}, false);
|
}, false);
|
||||||
}
|
}
|
||||||
@ -4785,7 +4799,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
detail = player.media.error;
|
detail = player.media.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerEvent.call(player, player.elements.container, event.type, true, detail);
|
triggerEvent.call(player, elements.container, event.type, true, detail);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4837,59 +4851,60 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
var _this2 = this;
|
var _this2 = this;
|
||||||
|
|
||||||
var player = this.player;
|
var player = this.player;
|
||||||
|
var elements = player.elements;
|
||||||
|
|
||||||
// IE doesn't support input event, so we fallback to change
|
// IE doesn't support input event, so we fallback to change
|
||||||
|
|
||||||
var inputEvent = browser.isIE ? 'change' : 'input';
|
var inputEvent = browser.isIE ? 'change' : 'input';
|
||||||
|
|
||||||
// Play/pause toggle
|
// Play/pause toggle
|
||||||
if (player.elements.buttons.play) {
|
if (elements.buttons.play) {
|
||||||
Array.from(player.elements.buttons.play).forEach(function (button) {
|
Array.from(elements.buttons.play).forEach(function (button) {
|
||||||
_this2.bind(button, 'click', player.togglePlay, 'play');
|
_this2.bind(button, 'click', player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause
|
// Pause
|
||||||
this.bind(player.elements.buttons.restart, 'click', player.restart, 'restart');
|
this.bind(elements.buttons.restart, 'click', player.restart, 'restart');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
this.bind(player.elements.buttons.rewind, 'click', player.rewind, 'rewind');
|
this.bind(elements.buttons.rewind, 'click', player.rewind, 'rewind');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
this.bind(player.elements.buttons.fastForward, 'click', player.forward, 'fastForward');
|
this.bind(elements.buttons.fastForward, 'click', player.forward, 'fastForward');
|
||||||
|
|
||||||
// Mute toggle
|
// Mute toggle
|
||||||
this.bind(player.elements.buttons.mute, 'click', function () {
|
this.bind(elements.buttons.mute, 'click', function () {
|
||||||
player.muted = !player.muted;
|
player.muted = !player.muted;
|
||||||
}, 'mute');
|
}, 'mute');
|
||||||
|
|
||||||
// Captions toggle
|
// Captions toggle
|
||||||
this.bind(player.elements.buttons.captions, 'click', function () {
|
this.bind(elements.buttons.captions, 'click', function () {
|
||||||
return player.toggleCaptions();
|
return player.toggleCaptions();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Fullscreen toggle
|
// Fullscreen toggle
|
||||||
this.bind(player.elements.buttons.fullscreen, 'click', function () {
|
this.bind(elements.buttons.fullscreen, 'click', function () {
|
||||||
player.fullscreen.toggle();
|
player.fullscreen.toggle();
|
||||||
}, 'fullscreen');
|
}, 'fullscreen');
|
||||||
|
|
||||||
// Picture-in-Picture
|
// Picture-in-Picture
|
||||||
this.bind(player.elements.buttons.pip, 'click', function () {
|
this.bind(elements.buttons.pip, 'click', function () {
|
||||||
player.pip = 'toggle';
|
player.pip = 'toggle';
|
||||||
}, 'pip');
|
}, 'pip');
|
||||||
|
|
||||||
// Airplay
|
// Airplay
|
||||||
this.bind(player.elements.buttons.airplay, 'click', player.airplay, 'airplay');
|
this.bind(elements.buttons.airplay, 'click', player.airplay, 'airplay');
|
||||||
|
|
||||||
// Settings menu - click toggle
|
// Settings menu - click toggle
|
||||||
this.bind(player.elements.buttons.settings, 'click', function (event) {
|
this.bind(elements.buttons.settings, 'click', function (event) {
|
||||||
controls.toggleMenu.call(player, event);
|
controls.toggleMenu.call(player, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Settings menu - keyboard toggle
|
// Settings menu - keyboard toggle
|
||||||
// We have to bind to keyup otherwise Firefox triggers a click when a keydown event handler shifts focus
|
// We have to bind to keyup otherwise Firefox triggers a click when a keydown event handler shifts focus
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
|
||||||
this.bind(player.elements.buttons.settings, 'keyup', function (event) {
|
this.bind(elements.buttons.settings, 'keyup', function (event) {
|
||||||
// We only care about space and return
|
// We only care about space and return
|
||||||
if (event.which !== 32 && event.which !== 13) {
|
if (event.which !== 32 && event.which !== 13) {
|
||||||
return;
|
return;
|
||||||
@ -4907,23 +4922,30 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
controls.toggleMenu.call(player, event);
|
controls.toggleMenu.call(player, event);
|
||||||
}, null, false);
|
}, null, false);
|
||||||
|
|
||||||
|
// Escape closes menu
|
||||||
|
this.bind(elements.settings.menu, 'keydown', function (event) {
|
||||||
|
if (event.which === 27) {
|
||||||
|
controls.toggleMenu.call(player, event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Set range input alternative "value", which matches the tooltip time (#954)
|
// Set range input alternative "value", which matches the tooltip time (#954)
|
||||||
this.bind(player.elements.inputs.seek, 'mousedown mousemove', function (event) {
|
this.bind(elements.inputs.seek, 'mousedown mousemove', function (event) {
|
||||||
var rect = player.elements.progress.getBoundingClientRect();
|
var rect = elements.progress.getBoundingClientRect();
|
||||||
var percent = 100 / rect.width * (event.pageX - rect.left);
|
var percent = 100 / rect.width * (event.pageX - rect.left);
|
||||||
event.currentTarget.setAttribute('seek-value', percent);
|
event.currentTarget.setAttribute('seek-value', percent);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause while seeking
|
// Pause while seeking
|
||||||
this.bind(player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', function (event) {
|
this.bind(elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', function (event) {
|
||||||
var seek = event.currentTarget;
|
var seek = event.currentTarget;
|
||||||
var code = event.keyCode ? event.keyCode : event.which;
|
var code = event.keyCode ? event.keyCode : event.which;
|
||||||
var eventType = event.type;
|
|
||||||
var attribute = 'play-on-seeked';
|
var attribute = 'play-on-seeked';
|
||||||
|
|
||||||
if ((eventType === 'keydown' || eventType === 'keyup') && code !== 39 && code !== 37) {
|
if (is.keyboardEvent(event) && code !== 39 && code !== 37) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was playing before?
|
// Was playing before?
|
||||||
var play = seek.hasAttribute(attribute);
|
var play = seek.hasAttribute(attribute);
|
||||||
|
|
||||||
@ -4945,7 +4967,6 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
// it takes over further interactions on the page. This is a hack
|
// it takes over further interactions on the page. This is a hack
|
||||||
if (browser.isIos) {
|
if (browser.isIos) {
|
||||||
var inputs = getElements.call(player, 'input[type="range"]');
|
var inputs = getElements.call(player, 'input[type="range"]');
|
||||||
|
|
||||||
Array.from(inputs).forEach(function (input) {
|
Array.from(inputs).forEach(function (input) {
|
||||||
return _this2.bind(input, inputEvent, function (event) {
|
return _this2.bind(input, inputEvent, function (event) {
|
||||||
return repaint(event.target);
|
return repaint(event.target);
|
||||||
@ -4954,7 +4975,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Seek
|
// Seek
|
||||||
this.bind(player.elements.inputs.seek, inputEvent, function (event) {
|
this.bind(elements.inputs.seek, inputEvent, function (event) {
|
||||||
var seek = event.currentTarget;
|
var seek = event.currentTarget;
|
||||||
|
|
||||||
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
// If it exists, use seek-value instead of "value" for consistency with tooltip time (#954)
|
||||||
@ -4969,10 +4990,24 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
player.currentTime = seekTo / seek.max * player.duration;
|
player.currentTime = seekTo / seek.max * player.duration;
|
||||||
}, 'seek');
|
}, 'seek');
|
||||||
|
|
||||||
|
// Seek tooltip
|
||||||
|
this.bind(elements.progress, 'mouseenter mouseleave mousemove', function (event) {
|
||||||
|
return controls.updateSeekTooltip.call(player, event);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Polyfill for lower fill in <input type="range"> for webkit
|
||||||
|
if (browser.isWebkit) {
|
||||||
|
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
||||||
|
_this2.bind(element, 'input', function (event) {
|
||||||
|
return controls.updateRangeFill.call(player, event.target);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Current time invert
|
// Current time invert
|
||||||
// Only if one time element is used for both currentTime and duration
|
// Only if one time element is used for both currentTime and duration
|
||||||
if (player.config.toggleInvert && !is.element(player.elements.display.duration)) {
|
if (player.config.toggleInvert && !is.element(elements.display.duration)) {
|
||||||
this.bind(player.elements.display.currentTime, 'click', function () {
|
this.bind(elements.display.currentTime, 'click', function () {
|
||||||
// Do nothing if we're at the start
|
// Do nothing if we're at the start
|
||||||
if (player.currentTime === 0) {
|
if (player.currentTime === 0) {
|
||||||
return;
|
return;
|
||||||
@ -4985,36 +5020,22 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
this.bind(player.elements.inputs.volume, inputEvent, function (event) {
|
this.bind(elements.inputs.volume, inputEvent, function (event) {
|
||||||
player.volume = event.target.value;
|
player.volume = event.target.value;
|
||||||
}, 'volume');
|
}, 'volume');
|
||||||
|
|
||||||
// Polyfill for lower fill in <input type="range"> for webkit
|
|
||||||
if (browser.isWebkit) {
|
|
||||||
Array.from(getElements.call(player, 'input[type="range"]')).forEach(function (element) {
|
|
||||||
_this2.bind(element, 'input', function (event) {
|
|
||||||
return controls.updateRangeFill.call(player, event.target);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek tooltip
|
|
||||||
this.bind(player.elements.progress, 'mouseenter mouseleave mousemove', function (event) {
|
|
||||||
return controls.updateSeekTooltip.call(player, event);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
this.bind(player.elements.controls, 'mouseenter mouseleave', function (event) {
|
this.bind(elements.controls, 'mouseenter mouseleave', function (event) {
|
||||||
player.elements.controls.hover = !player.touch && event.type === 'mouseenter';
|
elements.controls.hover = !player.touch && event.type === 'mouseenter';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
this.bind(player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function (event) {
|
this.bind(elements.controls, 'mousedown mouseup touchstart touchend touchcancel', function (event) {
|
||||||
player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Focus in/out on controls
|
// Focus in/out on controls
|
||||||
this.bind(player.elements.controls, 'focusin focusout', function (event) {
|
this.bind(elements.controls, 'focusin focusout', function (event) {
|
||||||
var config = player.config,
|
var config = player.config,
|
||||||
elements = player.elements,
|
elements = player.elements,
|
||||||
timers = player.timers;
|
timers = player.timers;
|
||||||
@ -5048,7 +5069,7 @@ typeof navigator === "object" && (function (global, factory) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Mouse wheel for volume
|
// Mouse wheel for volume
|
||||||
this.bind(player.elements.inputs.volume, 'wheel', function (event) {
|
this.bind(elements.inputs.volume, 'wheel', function (event) {
|
||||||
// Detect "natural" scroll - suppored on OS X Safari only
|
// Detect "natural" scroll - suppored on OS X Safari only
|
||||||
// Other browsers on OS X will be inverted until support improves
|
// Other browsers on OS X will be inverted until support improves
|
||||||
var inverted = event.webkitDirectionInvertedFromDevice;
|
var inverted = event.webkitDirectionInvertedFromDevice;
|
||||||
|
2
dist/plyr.js.map
vendored
2
dist/plyr.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js
vendored
2
dist/plyr.min.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.min.js.map
vendored
2
dist/plyr.min.js.map
vendored
File diff suppressed because one or more lines are too long
31
src/js/controls.js
vendored
31
src/js/controls.js
vendored
@ -479,7 +479,7 @@ const controls = {
|
|||||||
menuItem,
|
menuItem,
|
||||||
'click keyup',
|
'click keyup',
|
||||||
event => {
|
event => {
|
||||||
if (event.type === 'keyup' && event.which !== 32) {
|
if (is.keyboardEvent(event) && event.which !== 32) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +505,7 @@ const controls = {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
controls.showMenuPanel.call(this, 'home', event.type === 'keyup');
|
controls.showMenuPanel.call(this, 'home', is.keyboardEvent(event));
|
||||||
},
|
},
|
||||||
type,
|
type,
|
||||||
false,
|
false,
|
||||||
@ -1084,13 +1084,18 @@ const controls = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const show = is.boolean(input) ? input : is.element(popup) && popup.hasAttribute('hidden');
|
// True toggle by default
|
||||||
|
let show = is.element(popup) && popup.hasAttribute('hidden');
|
||||||
|
|
||||||
if (is.event(input)) {
|
if (is.boolean(input)) {
|
||||||
const isMenuItem = is.element(popup) && popup.contains(input.target);
|
show = input;
|
||||||
const isButton = input.target === this.elements.buttons.settings;
|
} else if (is.keyboardEvent(input) && input.which === 27) {
|
||||||
|
show = false;
|
||||||
|
} else if (is.event(input)) {
|
||||||
|
const isMenuItem = popup.contains(input.target);
|
||||||
|
const isButton = input.target === button;
|
||||||
|
|
||||||
// If the click was inside the form or if the click
|
// If the click was inside the menu or if the click
|
||||||
// wasn't the button or menu item and we're trying to
|
// wasn't the button or menu item and we're trying to
|
||||||
// show the menu (a doc click shouldn't show the menu)
|
// show the menu (a doc click shouldn't show the menu)
|
||||||
if (isMenuItem || (!isMenuItem && !isButton && show)) {
|
if (isMenuItem || (!isMenuItem && !isButton && show)) {
|
||||||
@ -1103,24 +1108,24 @@ const controls = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set form and button attributes
|
// Set button attributes
|
||||||
if (is.element(button)) {
|
|
||||||
button.setAttribute('aria-expanded', show);
|
button.setAttribute('aria-expanded', show);
|
||||||
}
|
|
||||||
|
|
||||||
// Show the actual popup
|
// Show the actual popup
|
||||||
if (is.element(popup)) {
|
|
||||||
toggleHidden(popup, !show);
|
toggleHidden(popup, !show);
|
||||||
|
|
||||||
|
// Add class hook
|
||||||
toggleClass(this.elements.container, this.config.classNames.menu.open, show);
|
toggleClass(this.elements.container, this.config.classNames.menu.open, show);
|
||||||
|
|
||||||
// Focus the first item if key interaction
|
// Focus the first item if key interaction
|
||||||
if (show && is.event(input) && input.type === 'keyup') {
|
if (show && is.keyboardEvent(input)) {
|
||||||
const pane = Object.values(this.elements.settings.panels).find(pane => !pane.hidden);
|
const pane = Object.values(this.elements.settings.panels).find(pane => !pane.hidden);
|
||||||
const firstItem = pane.querySelector('[role^="menuitem"]');
|
const firstItem = pane.querySelector('[role^="menuitem"]');
|
||||||
|
|
||||||
setFocus.call(this, firstItem, true);
|
setFocus.call(this, firstItem, true);
|
||||||
}
|
}
|
||||||
|
// If closing, re-focus the button
|
||||||
|
else if (!show) {
|
||||||
|
setFocus.call(this, button, is.keyboardEvent(input));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ class Listeners {
|
|||||||
// Handle key presses
|
// Handle key presses
|
||||||
handleKey(event) {
|
handleKey(event) {
|
||||||
const { player } = this;
|
const { player } = this;
|
||||||
|
const { elements } = player;
|
||||||
const code = event.keyCode ? event.keyCode : event.which;
|
const code = event.keyCode ? event.keyCode : event.which;
|
||||||
const pressed = event.type === 'keydown';
|
const pressed = event.type === 'keydown';
|
||||||
const repeat = pressed && code === this.lastKey;
|
const repeat = pressed && code === this.lastKey;
|
||||||
@ -56,7 +57,7 @@ class Listeners {
|
|||||||
const focused = document.activeElement;
|
const focused = document.activeElement;
|
||||||
if (is.element(focused)) {
|
if (is.element(focused)) {
|
||||||
const { editable } = player.config.selectors;
|
const { editable } = player.config.selectors;
|
||||||
const { seek } = player.elements.inputs;
|
const { seek } = elements.inputs;
|
||||||
|
|
||||||
if (focused !== seek && matches(focused, editable)) {
|
if (focused !== seek && matches(focused, editable)) {
|
||||||
return;
|
return;
|
||||||
@ -182,15 +183,17 @@ class Listeners {
|
|||||||
// Device is touch enabled
|
// Device is touch enabled
|
||||||
firstTouch() {
|
firstTouch() {
|
||||||
const { player } = this;
|
const { player } = this;
|
||||||
|
const { elements } = player;
|
||||||
|
|
||||||
player.touch = true;
|
player.touch = true;
|
||||||
|
|
||||||
// Add touch class
|
// Add touch class
|
||||||
toggleClass(player.elements.container, player.config.classNames.isTouch, true);
|
toggleClass(elements.container, player.config.classNames.isTouch, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
setTabFocus(event) {
|
setTabFocus(event) {
|
||||||
const { player } = this;
|
const { player } = this;
|
||||||
|
const { elements } = player;
|
||||||
|
|
||||||
clearTimeout(this.focusTimer);
|
clearTimeout(this.focusTimer);
|
||||||
|
|
||||||
@ -228,7 +231,7 @@ class Listeners {
|
|||||||
const focused = document.activeElement;
|
const focused = document.activeElement;
|
||||||
|
|
||||||
// Ignore if current focus element isn't inside the player
|
// Ignore if current focus element isn't inside the player
|
||||||
if (!player.elements.container.contains(focused)) {
|
if (!elements.container.contains(focused)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -258,19 +261,20 @@ class Listeners {
|
|||||||
// Container listeners
|
// Container listeners
|
||||||
container() {
|
container() {
|
||||||
const { player } = this;
|
const { player } = this;
|
||||||
|
const { elements } = player;
|
||||||
|
|
||||||
// Keyboard shortcuts
|
// Keyboard shortcuts
|
||||||
if (!player.config.keyboard.global && player.config.keyboard.focused) {
|
if (!player.config.keyboard.global && player.config.keyboard.focused) {
|
||||||
on.call(player, player.elements.container, 'keydown keyup', this.handleKey, false);
|
on.call(player, elements.container, 'keydown keyup', this.handleKey, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Toggle controls on mouse events and entering fullscreen
|
// Toggle controls on mouse events and entering fullscreen
|
||||||
on.call(
|
on.call(
|
||||||
player,
|
player,
|
||||||
player.elements.container,
|
elements.container,
|
||||||
'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',
|
'mousemove mouseleave touchstart touchmove enterfullscreen exitfullscreen',
|
||||||
event => {
|
event => {
|
||||||
const { controls } = player.elements;
|
const { controls } = elements;
|
||||||
|
|
||||||
// Remove button states for fullscreen
|
// Remove button states for fullscreen
|
||||||
if (event.type === 'enterfullscreen') {
|
if (event.type === 'enterfullscreen') {
|
||||||
@ -301,6 +305,7 @@ class Listeners {
|
|||||||
// Listen for media events
|
// Listen for media events
|
||||||
media() {
|
media() {
|
||||||
const { player } = this;
|
const { player } = this;
|
||||||
|
const { elements } = player;
|
||||||
|
|
||||||
// Time change on media
|
// Time change on media
|
||||||
on.call(player, player.media, 'timeupdate seeking seeked', event => controls.timeUpdate.call(player, event));
|
on.call(player, player.media, 'timeupdate seeking seeked', event => controls.timeUpdate.call(player, event));
|
||||||
@ -313,8 +318,8 @@ class Listeners {
|
|||||||
// Check for audio tracks on load
|
// Check for audio tracks on load
|
||||||
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
// We can't use `loadedmetadata` as it doesn't seem to have audio tracks at that point
|
||||||
on.call(player, player.media, 'canplay', () => {
|
on.call(player, player.media, 'canplay', () => {
|
||||||
toggleHidden(player.elements.volume, !player.hasAudio);
|
toggleHidden(elements.volume, !player.hasAudio);
|
||||||
toggleHidden(player.elements.buttons.mute, !player.hasAudio);
|
toggleHidden(elements.buttons.mute, !player.hasAudio);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Handle the media finishing
|
// Handle the media finishing
|
||||||
@ -367,8 +372,8 @@ class Listeners {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// On click play, pause ore restart
|
// On click play, pause ore restart
|
||||||
on.call(player, player.elements.container, 'click touchstart', event => {
|
on.call(player, elements.container, 'click touchstart', event => {
|
||||||
const targets = [player.elements.container, wrapper];
|
const targets = [elements.container, wrapper];
|
||||||
|
|
||||||
// Ignore if click if not container or in video wrapper
|
// Ignore if click if not container or in video wrapper
|
||||||
if (!targets.includes(event.target) && !wrapper.contains(event.target)) {
|
if (!targets.includes(event.target) && !wrapper.contains(event.target)) {
|
||||||
@ -380,7 +385,7 @@ class Listeners {
|
|||||||
if (
|
if (
|
||||||
player.config.hideControls &&
|
player.config.hideControls &&
|
||||||
player.touch &&
|
player.touch &&
|
||||||
hasClass(player.elements.container, player.config.classNames.hideControls)
|
hasClass(elements.container, player.config.classNames.hideControls)
|
||||||
) {
|
) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -398,7 +403,7 @@ class Listeners {
|
|||||||
if (player.supported.ui && player.config.disableContextMenu) {
|
if (player.supported.ui && player.config.disableContextMenu) {
|
||||||
on.call(
|
on.call(
|
||||||
player,
|
player,
|
||||||
player.elements.wrapper,
|
elements.wrapper,
|
||||||
'contextmenu',
|
'contextmenu',
|
||||||
event => {
|
event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -449,7 +454,7 @@ class Listeners {
|
|||||||
detail = player.media.error;
|
detail = player.media.error;
|
||||||
}
|
}
|
||||||
|
|
||||||
triggerEvent.call(player, player.elements.container, event.type, true, detail);
|
triggerEvent.call(player, elements.container, event.type, true, detail);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,29 +494,30 @@ class Listeners {
|
|||||||
// Listen for control events
|
// Listen for control events
|
||||||
controls() {
|
controls() {
|
||||||
const { player } = this;
|
const { player } = this;
|
||||||
|
const { elements } = player;
|
||||||
|
|
||||||
// IE doesn't support input event, so we fallback to change
|
// IE doesn't support input event, so we fallback to change
|
||||||
const inputEvent = browser.isIE ? 'change' : 'input';
|
const inputEvent = browser.isIE ? 'change' : 'input';
|
||||||
|
|
||||||
// Play/pause toggle
|
// Play/pause toggle
|
||||||
if (player.elements.buttons.play) {
|
if (elements.buttons.play) {
|
||||||
Array.from(player.elements.buttons.play).forEach(button => {
|
Array.from(elements.buttons.play).forEach(button => {
|
||||||
this.bind(button, 'click', player.togglePlay, 'play');
|
this.bind(button, 'click', player.togglePlay, 'play');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pause
|
// Pause
|
||||||
this.bind(player.elements.buttons.restart, 'click', player.restart, 'restart');
|
this.bind(elements.buttons.restart, 'click', player.restart, 'restart');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
this.bind(player.elements.buttons.rewind, 'click', player.rewind, 'rewind');
|
this.bind(elements.buttons.rewind, 'click', player.rewind, 'rewind');
|
||||||
|
|
||||||
// Rewind
|
// Rewind
|
||||||
this.bind(player.elements.buttons.fastForward, 'click', player.forward, 'fastForward');
|
this.bind(elements.buttons.fastForward, 'click', player.forward, 'fastForward');
|
||||||
|
|
||||||
// Mute toggle
|
// Mute toggle
|
||||||
this.bind(
|
this.bind(
|
||||||
player.elements.buttons.mute,
|
elements.buttons.mute,
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
player.muted = !player.muted;
|
player.muted = !player.muted;
|
||||||
@ -520,11 +526,11 @@ class Listeners {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Captions toggle
|
// Captions toggle
|
||||||
this.bind(player.elements.buttons.captions, 'click', () => player.toggleCaptions());
|
this.bind(elements.buttons.captions, 'click', () => player.toggleCaptions());
|
||||||
|
|
||||||
// Fullscreen toggle
|
// Fullscreen toggle
|
||||||
this.bind(
|
this.bind(
|
||||||
player.elements.buttons.fullscreen,
|
elements.buttons.fullscreen,
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
player.fullscreen.toggle();
|
player.fullscreen.toggle();
|
||||||
@ -534,7 +540,7 @@ class Listeners {
|
|||||||
|
|
||||||
// Picture-in-Picture
|
// Picture-in-Picture
|
||||||
this.bind(
|
this.bind(
|
||||||
player.elements.buttons.pip,
|
elements.buttons.pip,
|
||||||
'click',
|
'click',
|
||||||
() => {
|
() => {
|
||||||
player.pip = 'toggle';
|
player.pip = 'toggle';
|
||||||
@ -543,10 +549,10 @@ class Listeners {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Airplay
|
// Airplay
|
||||||
this.bind(player.elements.buttons.airplay, 'click', player.airplay, 'airplay');
|
this.bind(elements.buttons.airplay, 'click', player.airplay, 'airplay');
|
||||||
|
|
||||||
// Settings menu - click toggle
|
// Settings menu - click toggle
|
||||||
this.bind(player.elements.buttons.settings, 'click', event => {
|
this.bind(elements.buttons.settings, 'click', event => {
|
||||||
controls.toggleMenu.call(player, event);
|
controls.toggleMenu.call(player, event);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -554,7 +560,7 @@ class Listeners {
|
|||||||
// We have to bind to keyup otherwise Firefox triggers a click when a keydown event handler shifts focus
|
// We have to bind to keyup otherwise Firefox triggers a click when a keydown event handler shifts focus
|
||||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
|
// https://bugzilla.mozilla.org/show_bug.cgi?id=1220143
|
||||||
this.bind(
|
this.bind(
|
||||||
player.elements.buttons.settings,
|
elements.buttons.settings,
|
||||||
'keyup',
|
'keyup',
|
||||||
event => {
|
event => {
|
||||||
// We only care about space and return
|
// We only care about space and return
|
||||||
@ -577,23 +583,30 @@ class Listeners {
|
|||||||
false,
|
false,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Escape closes menu
|
||||||
|
this.bind(elements.settings.menu, 'keydown', event => {
|
||||||
|
if (event.which === 27) {
|
||||||
|
controls.toggleMenu.call(player, event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Set range input alternative "value", which matches the tooltip time (#954)
|
// Set range input alternative "value", which matches the tooltip time (#954)
|
||||||
this.bind(player.elements.inputs.seek, 'mousedown mousemove', event => {
|
this.bind(elements.inputs.seek, 'mousedown mousemove', event => {
|
||||||
const rect = player.elements.progress.getBoundingClientRect();
|
const rect = elements.progress.getBoundingClientRect();
|
||||||
const percent = 100 / rect.width * (event.pageX - rect.left);
|
const percent = 100 / rect.width * (event.pageX - rect.left);
|
||||||
event.currentTarget.setAttribute('seek-value', percent);
|
event.currentTarget.setAttribute('seek-value', percent);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Pause while seeking
|
// Pause while seeking
|
||||||
this.bind(player.elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {
|
this.bind(elements.inputs.seek, 'mousedown mouseup keydown keyup touchstart touchend', event => {
|
||||||
const seek = event.currentTarget;
|
const seek = event.currentTarget;
|
||||||
const code = event.keyCode ? event.keyCode : event.which;
|
const code = event.keyCode ? event.keyCode : event.which;
|
||||||
const eventType = event.type;
|
|
||||||
const attribute = 'play-on-seeked';
|
const attribute = 'play-on-seeked';
|
||||||
|
|
||||||
if ((eventType === 'keydown' || eventType === 'keyup') && (code !== 39 && code !== 37)) {
|
if (is.keyboardEvent(event) && (code !== 39 && code !== 37)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Was playing before?
|
// Was playing before?
|
||||||
const play = seek.hasAttribute(attribute);
|
const play = seek.hasAttribute(attribute);
|
||||||
|
|
||||||
@ -615,13 +628,12 @@ class Listeners {
|
|||||||
// it takes over further interactions on the page. This is a hack
|
// it takes over further interactions on the page. This is a hack
|
||||||
if (browser.isIos) {
|
if (browser.isIos) {
|
||||||
const inputs = getElements.call(player, 'input[type="range"]');
|
const inputs = getElements.call(player, 'input[type="range"]');
|
||||||
|
|
||||||
Array.from(inputs).forEach(input => this.bind(input, inputEvent, event => repaint(event.target)));
|
Array.from(inputs).forEach(input => this.bind(input, inputEvent, event => repaint(event.target)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Seek
|
// Seek
|
||||||
this.bind(
|
this.bind(
|
||||||
player.elements.inputs.seek,
|
elements.inputs.seek,
|
||||||
inputEvent,
|
inputEvent,
|
||||||
event => {
|
event => {
|
||||||
const seek = event.currentTarget;
|
const seek = event.currentTarget;
|
||||||
@ -640,10 +652,22 @@ class Listeners {
|
|||||||
'seek',
|
'seek',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Seek tooltip
|
||||||
|
this.bind(elements.progress, 'mouseenter mouseleave mousemove', event =>
|
||||||
|
controls.updateSeekTooltip.call(player, event),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Polyfill for lower fill in <input type="range"> for webkit
|
||||||
|
if (browser.isWebkit) {
|
||||||
|
Array.from(getElements.call(player, 'input[type="range"]')).forEach(element => {
|
||||||
|
this.bind(element, 'input', event => controls.updateRangeFill.call(player, event.target));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Current time invert
|
// Current time invert
|
||||||
// Only if one time element is used for both currentTime and duration
|
// Only if one time element is used for both currentTime and duration
|
||||||
if (player.config.toggleInvert && !is.element(player.elements.display.duration)) {
|
if (player.config.toggleInvert && !is.element(elements.display.duration)) {
|
||||||
this.bind(player.elements.display.currentTime, 'click', () => {
|
this.bind(elements.display.currentTime, 'click', () => {
|
||||||
// Do nothing if we're at the start
|
// Do nothing if we're at the start
|
||||||
if (player.currentTime === 0) {
|
if (player.currentTime === 0) {
|
||||||
return;
|
return;
|
||||||
@ -657,7 +681,7 @@ class Listeners {
|
|||||||
|
|
||||||
// Volume
|
// Volume
|
||||||
this.bind(
|
this.bind(
|
||||||
player.elements.inputs.volume,
|
elements.inputs.volume,
|
||||||
inputEvent,
|
inputEvent,
|
||||||
event => {
|
event => {
|
||||||
player.volume = event.target.value;
|
player.volume = event.target.value;
|
||||||
@ -665,30 +689,18 @@ class Listeners {
|
|||||||
'volume',
|
'volume',
|
||||||
);
|
);
|
||||||
|
|
||||||
// Polyfill for lower fill in <input type="range"> for webkit
|
|
||||||
if (browser.isWebkit) {
|
|
||||||
Array.from(getElements.call(player, 'input[type="range"]')).forEach(element => {
|
|
||||||
this.bind(element, 'input', event => controls.updateRangeFill.call(player, event.target));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek tooltip
|
|
||||||
this.bind(player.elements.progress, 'mouseenter mouseleave mousemove', event =>
|
|
||||||
controls.updateSeekTooltip.call(player, event),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.hover state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
this.bind(player.elements.controls, 'mouseenter mouseleave', event => {
|
this.bind(elements.controls, 'mouseenter mouseleave', event => {
|
||||||
player.elements.controls.hover = !player.touch && event.type === 'mouseenter';
|
elements.controls.hover = !player.touch && event.type === 'mouseenter';
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
|
||||||
this.bind(player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
|
this.bind(elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
|
||||||
player.elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Focus in/out on controls
|
// Focus in/out on controls
|
||||||
this.bind(player.elements.controls, 'focusin focusout', event => {
|
this.bind(elements.controls, 'focusin focusout', event => {
|
||||||
const { config, elements, timers } = player;
|
const { config, elements, timers } = player;
|
||||||
const isFocusIn = event.type === 'focusin';
|
const isFocusIn = event.type === 'focusin';
|
||||||
|
|
||||||
@ -718,7 +730,7 @@ class Listeners {
|
|||||||
|
|
||||||
// Mouse wheel for volume
|
// Mouse wheel for volume
|
||||||
this.bind(
|
this.bind(
|
||||||
player.elements.inputs.volume,
|
elements.inputs.volume,
|
||||||
'wheel',
|
'wheel',
|
||||||
event => {
|
event => {
|
||||||
// Detect "natural" scroll - suppored on OS X Safari only
|
// Detect "natural" scroll - suppored on OS X Safari only
|
||||||
|
@ -16,6 +16,7 @@ const isNodeList = input => instanceOf(input, NodeList);
|
|||||||
const isElement = input => instanceOf(input, Element);
|
const isElement = input => instanceOf(input, Element);
|
||||||
const isTextNode = input => getConstructor(input) === Text;
|
const isTextNode = input => getConstructor(input) === Text;
|
||||||
const isEvent = input => instanceOf(input, Event);
|
const isEvent = input => instanceOf(input, Event);
|
||||||
|
const isKeyboardEvent = input => instanceOf(input, KeyboardEvent);
|
||||||
const isCue = input => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
|
const isCue = input => instanceOf(input, window.TextTrackCue) || instanceOf(input, window.VTTCue);
|
||||||
const isTrack = input => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind));
|
const isTrack = input => instanceOf(input, TextTrack) || (!isNullOrUndefined(input) && isString(input.kind));
|
||||||
|
|
||||||
@ -56,6 +57,7 @@ export default {
|
|||||||
element: isElement,
|
element: isElement,
|
||||||
textNode: isTextNode,
|
textNode: isTextNode,
|
||||||
event: isEvent,
|
event: isEvent,
|
||||||
|
keyboardEvent: isKeyboardEvent,
|
||||||
cue: isCue,
|
cue: isCue,
|
||||||
track: isTrack,
|
track: isTrack,
|
||||||
url: isUrl,
|
url: isUrl,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user