Merge branch 'develop' into css-variables

# Conflicts:
#	src/js/captions.js
#	src/js/config/defaults.js
#	src/js/fullscreen.js
#	src/js/listeners.js
#	src/js/plyr.js
This commit is contained in:
Sam Potts
2020-04-24 00:22:17 +10:00
8 changed files with 61 additions and 10 deletions

View File

@ -133,8 +133,12 @@ const captions = {
});
// Turn off native caption rendering to avoid double captions
// Note: mode='hidden' forces a track to download. To ensure every track
// isn't downloaded at once, only 'showing' tracks should be reassigned
// eslint-disable-next-line no-param-reassign
track.mode = 'hidden';
if (track.mode === 'showing') {
track.mode = 'hidden';
}
// Add event listener for cue changes
on.call(this, track, 'cuechange', () => captions.updateCues.call(this));
@ -211,6 +215,14 @@ const captions = {
// Trigger event (not used internally)
triggerEvent.call(this, this.media, active ? 'captionsenabled' : 'captionsdisabled');
}
// Wait for the call stack to clear before setting mode='hidden'
// on the active track - forcing the browser to download it
setTimeout(() => {
if (active && this.captions.toggled) {
this.captions.currentTrackNode.mode = 'hidden';
}
});
},
// Set captions by track index

View File

@ -115,6 +115,9 @@ const defaults = {
enabled: true, // Allow fullscreen?
fallback: true, // Fallback using full viewport/window
iosNative: false, // Use the native fullscreen in iOS (disables custom controls)
// Selector for the fullscreen container so contextual / non-player content can remain visible in fullscreen mode
// Non-ancestors of the player element will be ignored
// container: null, // defaults to the player element
},
// Local storage

View File

@ -5,7 +5,7 @@
// ==========================================================================
import browser from './utils/browser';
import { getElements, hasClass, toggleClass } from './utils/elements';
import { getElements, hasClass, toggleClass, closest } from './utils/elements';
import { on, triggerEvent } from './utils/events';
import is from './utils/is';
import { silencePromise } from './utils/promise';
@ -25,6 +25,11 @@ class Fullscreen {
// Force the use of 'full window/browser' rather than fullscreen
this.forceFallback = player.config.fullscreen.fallback === 'force';
// Get the fullscreen element
// Checks container is an ancestor, defaults to null
this.player.elements.fullscreen =
player.config.fullscreen.container && closest(this.player.elements.container, player.config.fullscreen.container);
// Register event listeners
// Handle event (incase user presses escape etc)
on.call(
@ -126,7 +131,7 @@ class Fullscreen {
get target() {
return browser.isIos && this.player.config.fullscreen.iosNative
? this.player.media
: this.player.elements.container;
: this.player.elements.fullscreen || this.player.elements.container;
}
onChange() {

View File

@ -333,7 +333,6 @@ class Listeners {
const resized = () => {
clearTimeout(timers.resized);
timers.resized = setTimeout(setPlayerSize, 50);
};
@ -357,7 +356,7 @@ class Listeners {
// Set Vimeo gutter
setGutter(ratio, padding, isEnter);
// If not using the native browser fullscreen API, we need to check for resizes of viewport
// If not using native browser fullscreen API, we need to check for resizes of viewport
if (!usingNative) {
if (isEnter) {
on.call(player, window, 'resize', resized);
@ -817,6 +816,17 @@ class Listeners {
elements.controls.hover = !player.touch && event.type === 'mouseenter';
});
// Also update controls.hover state for any non-player children of fullscreen element (as above)
if (elements.fullscreen) {
Array.from(elements.fullscreen.children)
.filter(c => !c.contains(elements.container))
.forEach(child => {
this.bind(child, 'mouseenter mouseleave', event => {
elements.controls.hover = !player.touch && event.type === 'mouseenter';
});
});
}
// Update controls.pressed state (used for ui.toggleControls to avoid hiding when interacting)
this.bind(elements.controls, 'mousedown mouseup touchstart touchend touchcancel', event => {
elements.controls.pressed = ['mousedown', 'touchstart'].includes(event.type);

View File

@ -80,6 +80,7 @@ class Plyr {
// Elements cache
this.elements = {
container: null,
fullscreen: null,
captions: null,
buttons: {},
display: {},
@ -285,6 +286,9 @@ class Plyr {
});
}
// Setup fullscreen
this.fullscreen = new Fullscreen(this);
// Setup interface
// If embed but not fully supported, build interface now to avoid flash of controls
if (this.isHTML5 || (this.isEmbed && !this.supported.ui)) {
@ -297,9 +301,6 @@ class Plyr {
// Global listeners
this.listeners.global();
// Setup fullscreen
this.fullscreen = new Fullscreen(this);
// Setup ads if provided
if (this.config.ads.enabled) {
this.ads = new Ads(this);

View File

@ -237,6 +237,26 @@ export function matches(element, selector) {
return method.call(element, selector);
}
// Closest ancestor element matching selector (also tests element itself)
export function closest(element, selector) {
const { prototype } = Element;
// https://developer.mozilla.org/en-US/docs/Web/API/Element/closest#Polyfill
function closestElement() {
let el = this;
do {
if (matches.matches(el, selector)) return el;
el = el.parentElement || el.parentNode;
} while (el !== null && el.nodeType === 1);
return null;
}
const method = prototype.closest || closestElement;
return method.call(element, selector);
}
// Find all elements
export function getElements(selector) {
return this.elements.container.querySelectorAll(selector);