Fixes for fast forward and issues with event.preventDefault()

This commit is contained in:
Sam Potts
2018-03-27 10:36:08 +11:00
parent 3d2ba8c009
commit 9c1bc6ab08
22 changed files with 2553 additions and 1464 deletions

View File

@ -128,7 +128,7 @@ class Listeners {
case 39:
// Arrow forward
this.player.forward();
this.player.fastForward();
break;
case 37:
@ -379,12 +379,13 @@ class Listeners {
// IE doesn't support input event, so we fallback to change
const inputEvent = browser.isIE ? 'change' : 'input';
// Trigger custom and default handlers
const proxy = (event, handlerKey, defaultHandler) => {
const customHandler = this.player.config.listeners[handlerKey];
// Run default and custom handlers
const proxy = (event, defaultHandler, customHandlerKey) => {
const customHandler = this.player.config.listeners[customHandlerKey];
const hasCustomHandler = utils.is.function(customHandler);
// Execute custom handler
if (utils.is.function(customHandler)) {
if (hasCustomHandler) {
customHandler.call(this.player, event);
}
@ -394,107 +395,110 @@ class Listeners {
}
};
// Trigger custom and default handlers
const on = (element, type, defaultHandler, customHandlerKey, passive = true) => {
const customHandler = this.player.config.listeners[customHandlerKey];
const hasCustomHandler = utils.is.function(customHandler);
utils.on(element, type, event => proxy(event, defaultHandler, customHandlerKey), passive && !hasCustomHandler);
};
// Play/pause toggle
utils.on(this.player.elements.buttons.play, 'click', event =>
proxy(event, 'play', () => {
this.player.togglePlay();
}),
);
on(this.player.elements.buttons.play, 'click', this.player.togglePlay, 'play');
// Pause
utils.on(this.player.elements.buttons.restart, 'click', event =>
proxy(event, 'restart', () => {
this.player.restart();
}),
);
on(this.player.elements.buttons.restart, 'click', this.player.restart, 'restart');
// Rewind
utils.on(this.player.elements.buttons.rewind, 'click', event =>
proxy(event, 'rewind', () => {
this.player.rewind();
}),
);
on(this.player.elements.buttons.rewind, 'click', this.player.rewind, 'rewind');
// Rewind
utils.on(this.player.elements.buttons.forward, 'click', event =>
proxy(event, 'forward', () => {
this.player.forward();
}),
);
on(this.player.elements.buttons.fastForward, 'click', this.player.fastForward, 'fastForward');
// Mute toggle
utils.on(this.player.elements.buttons.mute, 'click', event =>
proxy(event, 'mute', () => {
on(
this.player.elements.buttons.mute,
'click',
() => {
this.player.muted = !this.player.muted;
}),
},
'mute',
);
// Captions toggle
utils.on(this.player.elements.buttons.captions, 'click', event =>
proxy(event, 'captions', () => {
this.player.toggleCaptions();
}),
);
on(this.player.elements.buttons.captions, 'click', this.player.toggleCaptions);
// Fullscreen toggle
utils.on(this.player.elements.buttons.fullscreen, 'click', event =>
proxy(event, 'fullscreen', () => {
on(
this.player.elements.buttons.fullscreen,
'click',
() => {
this.player.fullscreen.toggle();
}),
},
'fullscreen',
);
// Picture-in-Picture
utils.on(this.player.elements.buttons.pip, 'click', event =>
proxy(event, 'pip', () => {
on(
this.player.elements.buttons.pip,
'click',
() => {
this.player.pip = 'toggle';
}),
},
'pip',
);
// Airplay
utils.on(this.player.elements.buttons.airplay, 'click', event =>
proxy(event, 'airplay', () => {
this.player.airplay();
}),
);
on(this.player.elements.buttons.airplay, 'click', this.player.airplay, 'airplay');
// Settings menu
utils.on(this.player.elements.buttons.settings, 'click', event => {
on(this.player.elements.buttons.settings, 'click', event => {
controls.toggleMenu.call(this.player, event);
});
// Settings menu
utils.on(this.player.elements.settings.form, 'click', event => {
on(this.player.elements.settings.form, 'click', event => {
event.stopPropagation();
// Settings menu items - use event delegation as items are added/removed
if (utils.matches(event.target, this.player.config.selectors.inputs.language)) {
proxy(event, 'language', () => {
this.player.language = event.target.value;
});
proxy(
event,
() => {
this.player.language = event.target.value;
},
'language',
);
} else if (utils.matches(event.target, this.player.config.selectors.inputs.quality)) {
proxy(event, 'quality', () => {
this.player.quality = event.target.value;
});
proxy(
event,
() => {
this.player.quality = event.target.value;
},
'quality',
);
} else if (utils.matches(event.target, this.player.config.selectors.inputs.speed)) {
proxy(event, 'speed', () => {
this.player.speed = parseFloat(event.target.value);
});
proxy(
event,
() => {
this.player.speed = parseFloat(event.target.value);
},
'speed',
);
} else {
controls.showTab.call(this.player, event);
}
});
// Seek
utils.on(this.player.elements.inputs.seek, inputEvent, event =>
proxy(event, 'seek', () => {
this.player.currentTime = event.target.value / event.target.max * this.player.duration;
}),
);
on(this.player.elements.inputs.seek, inputEvent, 'seek', event => {
this.player.currentTime = event.target.value / event.target.max * this.player.duration;
});
// Current time invert
// Only if one time element is used for both currentTime and duration
if (this.player.config.toggleInvert && !utils.is.element(this.player.elements.display.duration)) {
utils.on(this.player.elements.display.currentTime, 'click', () => {
on(this.player.elements.display.currentTime, 'click', () => {
// Do nothing if we're at the start
if (this.player.currentTime === 0) {
return;
@ -506,31 +510,34 @@ class Listeners {
}
// Volume
utils.on(this.player.elements.inputs.volume, inputEvent, event =>
proxy(event, 'volume', () => {
on(
this.player.elements.inputs.volume,
inputEvent,
event => {
this.player.volume = event.target.value;
}),
},
'volume',
);
// Polyfill for lower fill in <input type="range"> for webkit
if (browser.isWebkit) {
utils.on(utils.getElements.call(this.player, 'input[type="range"]'), 'input', event => {
on(utils.getElements.call(this.player, 'input[type="range"]'), 'input', event => {
controls.updateRangeFill.call(this.player, event.target);
});
}
// Seek tooltip
utils.on(this.player.elements.progress, 'mouseenter mouseleave mousemove', event => controls.updateSeekTooltip.call(this.player, event));
on(this.player.elements.progress, 'mouseenter mouseleave mousemove', event => controls.updateSeekTooltip.call(this.player, event));
// Toggle controls visibility based on mouse movement
if (this.player.config.hideControls) {
// Watch for cursor over controls so they don't hide when trying to interact
utils.on(this.player.elements.controls, 'mouseenter mouseleave', event => {
on(this.player.elements.controls, 'mouseenter mouseleave', event => {
this.player.elements.controls.hover = event.type === 'mouseenter';
});
// Watch for cursor over controls so they don't hide when trying to interact
utils.on(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
on(this.player.elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
this.player.elements.controls.pressed = [
'mousedown',
'touchstart',
@ -538,50 +545,50 @@ class Listeners {
});
// Focus in/out on controls
utils.on(this.player.elements.controls, 'focusin focusout', event => {
on(this.player.elements.controls, 'focusin focusout', event => {
this.player.toggleControls(event);
});
}
// Mouse wheel for volume
utils.on(
on(
this.player.elements.inputs.volume,
'wheel',
event =>
proxy(event, 'volume', () => {
// Detect "natural" scroll - suppored on OS X Safari only
// Other browsers on OS X will be inverted until support improves
const inverted = event.webkitDirectionInvertedFromDevice;
const step = 1 / 50;
let direction = 0;
event => {
// Detect "natural" scroll - suppored on OS X Safari only
// Other browsers on OS X will be inverted until support improves
const inverted = event.webkitDirectionInvertedFromDevice;
const step = 1 / 50;
let direction = 0;
// Scroll down (or up on natural) to decrease
if (event.deltaY < 0 || event.deltaX > 0) {
if (inverted) {
this.player.decreaseVolume(step);
direction = -1;
} else {
this.player.increaseVolume(step);
direction = 1;
}
// Scroll down (or up on natural) to decrease
if (event.deltaY < 0 || event.deltaX > 0) {
if (inverted) {
this.player.decreaseVolume(step);
direction = -1;
} else {
this.player.increaseVolume(step);
direction = 1;
}
}
// Scroll up (or down on natural) to increase
if (event.deltaY > 0 || event.deltaX < 0) {
if (inverted) {
this.player.increaseVolume(step);
direction = 1;
} else {
this.player.decreaseVolume(step);
direction = -1;
}
// Scroll up (or down on natural) to increase
if (event.deltaY > 0 || event.deltaX < 0) {
if (inverted) {
this.player.increaseVolume(step);
direction = 1;
} else {
this.player.decreaseVolume(step);
direction = -1;
}
}
// Don't break page scrolling at max and min
if ((direction === 1 && this.player.media.volume < 1) || (direction === -1 && this.player.media.volume > 0)) {
event.preventDefault();
}
}),
// Don't break page scrolling at max and min
if ((direction === 1 && this.player.media.volume < 1) || (direction === -1 && this.player.media.volume > 0)) {
event.preventDefault();
}
},
'volume',
false,
);
}