diff options
Diffstat (limited to 'src/js')
-rw-r--r-- | src/js/config/defaults.js | 3 | ||||
-rw-r--r-- | src/js/fullscreen.js | 9 | ||||
-rw-r--r-- | src/js/listeners.js | 11 | ||||
-rw-r--r-- | src/js/plyr.js | 7 | ||||
-rw-r--r-- | src/js/utils/elements.js | 22 |
5 files changed, 47 insertions, 5 deletions
diff --git a/src/js/config/defaults.js b/src/js/config/defaults.js index c299a3c9..31ae6983 100644 --- a/src/js/config/defaults.js +++ b/src/js/config/defaults.js @@ -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 diff --git a/src/js/fullscreen.js b/src/js/fullscreen.js index 4d3c89ac..0db4aa3f 100644 --- a/src/js/fullscreen.js +++ b/src/js/fullscreen.js @@ -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() { diff --git a/src/js/listeners.js b/src/js/listeners.js index cd468083..ede8d88c 100644 --- a/src/js/listeners.js +++ b/src/js/listeners.js @@ -814,6 +814,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) { + for (let i = 0; i < elements.fullscreen.children.length; i++) { + if (!elements.fullscreen.children[i].contains(elements.container)) { + this.bind(elements.fullscreen.children[i], '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); diff --git a/src/js/plyr.js b/src/js/plyr.js index 00b95a5f..a69e793d 100644 --- a/src/js/plyr.js +++ b/src/js/plyr.js @@ -80,6 +80,7 @@ class Plyr { // Elements cache this.elements = { container: null, + fullscreen: null, captions: null, buttons: {}, display: {}, @@ -282,6 +283,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)) { @@ -294,9 +298,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); diff --git a/src/js/utils/elements.js b/src/js/utils/elements.js index bdf18bfd..f782fc3e 100644 --- a/src/js/utils/elements.js +++ b/src/js/utils/elements.js @@ -237,6 +237,28 @@ 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); |