Global listeners to prevent repeat binding
This commit is contained in:
parent
9c4b7e7094
commit
2497e25b3c
2
dist/plyr.js
vendored
2
dist/plyr.js
vendored
File diff suppressed because one or more lines are too long
2
dist/plyr.js.map
vendored
2
dist/plyr.js.map
vendored
File diff suppressed because one or more lines are too long
@ -13,6 +13,214 @@ import ui from './ui';
|
|||||||
const browser = utils.getBrowser();
|
const browser = utils.getBrowser();
|
||||||
|
|
||||||
const listeners = {
|
const listeners = {
|
||||||
|
// Global listeners
|
||||||
|
global() {
|
||||||
|
let last = null;
|
||||||
|
|
||||||
|
// Get the key code for an event
|
||||||
|
const getKeyCode = event => (event.keyCode ? event.keyCode : event.which);
|
||||||
|
|
||||||
|
// Handle key press
|
||||||
|
const handleKey = event => {
|
||||||
|
const code = getKeyCode(event);
|
||||||
|
const pressed = event.type === 'keydown';
|
||||||
|
const held = pressed && code === last;
|
||||||
|
|
||||||
|
// If the event is bubbled from the media element
|
||||||
|
// Firefox doesn't get the keycode for whatever reason
|
||||||
|
if (!utils.is.number(code)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seek by the number keys
|
||||||
|
const seekByKey = () => {
|
||||||
|
// Divide the max duration into 10th's and times by the number value
|
||||||
|
this.currentTime = this.duration / 10 * (code - 48);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Handle the key on keydown
|
||||||
|
// 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,
|
||||||
|
];
|
||||||
|
|
||||||
|
// Check focused element
|
||||||
|
// and if the focused element is not editable (e.g. text input)
|
||||||
|
// and any that accept key input http://webaim.org/techniques/keyboard/
|
||||||
|
const focused = utils.getFocusElement();
|
||||||
|
if (utils.is.htmlElement(focused) && utils.matches(focused, this.config.selectors.editable)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the code is found prevent default (e.g. prevent scrolling for arrows)
|
||||||
|
if (preventDefault.includes(code)) {
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (code) {
|
||||||
|
case 48:
|
||||||
|
case 49:
|
||||||
|
case 50:
|
||||||
|
case 51:
|
||||||
|
case 52:
|
||||||
|
case 53:
|
||||||
|
case 54:
|
||||||
|
case 55:
|
||||||
|
case 56:
|
||||||
|
case 57:
|
||||||
|
// 0-9
|
||||||
|
if (!held) {
|
||||||
|
seekByKey();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 32:
|
||||||
|
case 75:
|
||||||
|
// Space and K key
|
||||||
|
if (!held) {
|
||||||
|
this.warn('togglePlay', event.type);
|
||||||
|
this.togglePlay();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 38:
|
||||||
|
// Arrow up
|
||||||
|
this.increaseVolume(0.1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 40:
|
||||||
|
// Arrow down
|
||||||
|
this.decreaseVolume(0.1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 77:
|
||||||
|
// M key
|
||||||
|
if (!held) {
|
||||||
|
this.muted = 'toggle';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 39:
|
||||||
|
// Arrow forward
|
||||||
|
this.forward();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 37:
|
||||||
|
// Arrow back
|
||||||
|
this.rewind();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 70:
|
||||||
|
// F key
|
||||||
|
this.toggleFullscreen();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 67:
|
||||||
|
// C key
|
||||||
|
if (!held) {
|
||||||
|
this.toggleCaptions();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 73:
|
||||||
|
this.setLoop('start');
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 76:
|
||||||
|
this.setLoop();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 79:
|
||||||
|
this.setLoop('end');
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escape is handle natively when in full screen
|
||||||
|
// So we only need to worry about non native
|
||||||
|
if (!fullscreen.enabled && this.fullscreen.active && code === 27) {
|
||||||
|
this.toggleFullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store last code for next cycle
|
||||||
|
last = code;
|
||||||
|
} else {
|
||||||
|
last = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Keyboard shortcuts
|
||||||
|
if (this.config.keyboard.global) {
|
||||||
|
this.warn('bound');
|
||||||
|
utils.on(window, 'keydown keyup', handleKey, false);
|
||||||
|
} else if (this.config.keyboard.focused) {
|
||||||
|
utils.on(this.elements.container, 'keydown keyup', handleKey, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Detect tab focus
|
||||||
|
// Remove class on blur/focusout
|
||||||
|
utils.on(this.elements.container, 'focusout', event => {
|
||||||
|
utils.toggleClass(event.target, this.config.classNames.tabFocus, false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add classname to tabbed elements
|
||||||
|
utils.on(this.elements.container, 'keydown', event => {
|
||||||
|
if (event.keyCode !== 9) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delay the adding of classname until the focus has changed
|
||||||
|
// This event fires before the focusin event
|
||||||
|
window.setTimeout(() => {
|
||||||
|
utils.toggleClass(utils.getFocusElement(), this.config.classNames.tabFocus, true);
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 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 touchcancel touchmove enterfullscreen',
|
||||||
|
event => {
|
||||||
|
this.toggleControls(event);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle user exiting fullscreen by escaping etc
|
||||||
|
if (fullscreen.enabled) {
|
||||||
|
utils.on(document, fullscreen.eventType, event => {
|
||||||
|
this.toggleFullscreen(event);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Listen for media events
|
// Listen for media events
|
||||||
media() {
|
media() {
|
||||||
// Time change on media
|
// Time change on media
|
||||||
@ -138,7 +346,6 @@ const listeners = {
|
|||||||
controls() {
|
controls() {
|
||||||
// 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';
|
||||||
let last = null;
|
|
||||||
|
|
||||||
// Trigger custom and default handlers
|
// Trigger custom and default handlers
|
||||||
const proxy = (event, handlerKey, defaultHandler) => {
|
const proxy = (event, handlerKey, defaultHandler) => {
|
||||||
@ -168,188 +375,6 @@ const listeners = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get the key code for an event
|
|
||||||
const getKeyCode = event => (event.keyCode ? event.keyCode : event.which);
|
|
||||||
|
|
||||||
// Handle key press
|
|
||||||
const handleKey = event => {
|
|
||||||
const code = getKeyCode(event);
|
|
||||||
const pressed = event.type === 'keydown';
|
|
||||||
const held = pressed && code === last;
|
|
||||||
|
|
||||||
// If the event is bubbled from the media element
|
|
||||||
// Firefox doesn't get the keycode for whatever reason
|
|
||||||
if (!utils.is.number(code)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Seek by the number keys
|
|
||||||
const seekByKey = () => {
|
|
||||||
// Divide the max duration into 10th's and times by the number value
|
|
||||||
this.currentTime = this.duration / 10 * (code - 48);
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle the key on keydown
|
|
||||||
// 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,
|
|
||||||
];
|
|
||||||
|
|
||||||
// Check focused element
|
|
||||||
// and if the focused element is not editable (e.g. text input)
|
|
||||||
// and any that accept key input http://webaim.org/techniques/keyboard/
|
|
||||||
const focused = utils.getFocusElement();
|
|
||||||
if (utils.is.htmlElement(focused) && utils.matches(focused, this.config.selectors.editable)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the code is found prevent default (e.g. prevent scrolling for arrows)
|
|
||||||
if (preventDefault.includes(code)) {
|
|
||||||
event.preventDefault();
|
|
||||||
event.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (code) {
|
|
||||||
case 48:
|
|
||||||
case 49:
|
|
||||||
case 50:
|
|
||||||
case 51:
|
|
||||||
case 52:
|
|
||||||
case 53:
|
|
||||||
case 54:
|
|
||||||
case 55:
|
|
||||||
case 56:
|
|
||||||
case 57:
|
|
||||||
// 0-9
|
|
||||||
if (!held) {
|
|
||||||
seekByKey();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 32:
|
|
||||||
case 75:
|
|
||||||
// Space and K key
|
|
||||||
if (!held) {
|
|
||||||
this.togglePlay();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 38:
|
|
||||||
// Arrow up
|
|
||||||
this.increaseVolume(0.1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 40:
|
|
||||||
// Arrow down
|
|
||||||
this.decreaseVolume(0.1);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 77:
|
|
||||||
// M key
|
|
||||||
if (!held) {
|
|
||||||
this.muted = 'toggle';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 39:
|
|
||||||
// Arrow forward
|
|
||||||
this.forward();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 37:
|
|
||||||
// Arrow back
|
|
||||||
this.rewind();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 70:
|
|
||||||
// F key
|
|
||||||
this.toggleFullscreen();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 67:
|
|
||||||
// C key
|
|
||||||
if (!held) {
|
|
||||||
this.toggleCaptions();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 73:
|
|
||||||
this.setLoop('start');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 76:
|
|
||||||
this.setLoop();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 79:
|
|
||||||
this.setLoop('end');
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Escape is handle natively when in full screen
|
|
||||||
// So we only need to worry about non native
|
|
||||||
if (!fullscreen.enabled && this.fullscreen.active && code === 27) {
|
|
||||||
this.toggleFullscreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Store last code for next cycle
|
|
||||||
last = code;
|
|
||||||
} else {
|
|
||||||
last = null;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Keyboard shortcuts
|
|
||||||
if (this.config.keyboard.global) {
|
|
||||||
utils.on(window, 'keydown keyup', handleKey, false);
|
|
||||||
} else if (this.config.keyboard.focused) {
|
|
||||||
utils.on(this.elements.container, 'keydown keyup', handleKey, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Detect tab focus
|
|
||||||
// Remove class on blur/focusout
|
|
||||||
utils.on(this.elements.container, 'focusout', event => {
|
|
||||||
utils.toggleClass(event.target, this.config.classNames.tabFocus, false);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Add classname to tabbed elements
|
|
||||||
utils.on(this.elements.container, 'keydown', event => {
|
|
||||||
if (event.keyCode !== 9) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Delay the adding of classname until the focus has changed
|
|
||||||
// This event fires before the focusin event
|
|
||||||
window.setTimeout(() => {
|
|
||||||
utils.toggleClass(utils.getFocusElement(), this.config.classNames.tabFocus, true);
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Play
|
// Play
|
||||||
utils.on(this.elements.buttons.play, 'click', event => proxy(event, 'play', togglePlay));
|
utils.on(this.elements.buttons.play, 'click', event => proxy(event, 'play', togglePlay));
|
||||||
|
|
||||||
@ -484,15 +509,6 @@ const listeners = {
|
|||||||
|
|
||||||
// Toggle controls visibility based on mouse movement
|
// Toggle controls visibility based on mouse movement
|
||||||
if (this.config.hideControls) {
|
if (this.config.hideControls) {
|
||||||
// Toggle controls on mouse events and entering fullscreen
|
|
||||||
utils.on(
|
|
||||||
this.elements.container,
|
|
||||||
'mouseenter mouseleave mousemove touchstart touchend touchcancel touchmove enterfullscreen',
|
|
||||||
event => {
|
|
||||||
this.toggleControls(event);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Watch for cursor over controls so they don't hide when trying to interact
|
// Watch for cursor over controls so they don't hide when trying to interact
|
||||||
utils.on(this.elements.controls, 'mouseenter mouseleave', event => {
|
utils.on(this.elements.controls, 'mouseenter mouseleave', event => {
|
||||||
this.elements.controls.hover = event.type === 'mouseenter';
|
this.elements.controls.hover = event.type === 'mouseenter';
|
||||||
@ -556,13 +572,6 @@ const listeners = {
|
|||||||
}),
|
}),
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
// Handle user exiting fullscreen by escaping etc
|
|
||||||
if (fullscreen.enabled) {
|
|
||||||
utils.on(document, fullscreen.eventType, event => {
|
|
||||||
this.toggleFullscreen(event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import utils from './utils';
|
|||||||
import captions from './captions';
|
import captions from './captions';
|
||||||
import controls from './controls';
|
import controls from './controls';
|
||||||
import fullscreen from './fullscreen';
|
import fullscreen from './fullscreen';
|
||||||
|
import listeners from './listeners';
|
||||||
import media from './media';
|
import media from './media';
|
||||||
import storage from './storage';
|
import storage from './storage';
|
||||||
import source from './source';
|
import source from './source';
|
||||||
@ -214,6 +215,9 @@ class Plyr {
|
|||||||
// Allow focus to be captured
|
// Allow focus to be captured
|
||||||
this.elements.container.setAttribute('tabindex', 0);
|
this.elements.container.setAttribute('tabindex', 0);
|
||||||
|
|
||||||
|
// Global listeners
|
||||||
|
listeners.global.call(this);
|
||||||
|
|
||||||
// Add style hook
|
// Add style hook
|
||||||
ui.addStyleHook.call(this);
|
ui.addStyleHook.call(this);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user