aboutsummaryrefslogtreecommitdiffstats
path: root/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'src/js')
-rw-r--r--src/js/config/defaults.js3
-rw-r--r--src/js/fullscreen.js9
-rw-r--r--src/js/listeners.js11
-rw-r--r--src/js/plyr.js7
-rw-r--r--src/js/utils/elements.js22
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);