aboutsummaryrefslogtreecommitdiffstats
path: root/src/js/fullscreen.js
diff options
context:
space:
mode:
authorSam Potts <sam@potts.es>2018-02-11 15:09:34 +1100
committerSam Potts <sam@potts.es>2018-02-11 15:09:34 +1100
commit73a39769d4cc3d5d04e272ca571c849a0d8adfd6 (patch)
treea061524c38ed6da8c0d560096610a0cdaf36dcda /src/js/fullscreen.js
parentd21b58e1c9c74ed15fb02a76c864177028882416 (diff)
downloadplyr-73a39769d4cc3d5d04e272ca571c849a0d8adfd6.tar.lz
plyr-73a39769d4cc3d5d04e272ca571c849a0d8adfd6.tar.xz
plyr-73a39769d4cc3d5d04e272ca571c849a0d8adfd6.zip
Fullscreen API changes, color settings tweaks
Diffstat (limited to 'src/js/fullscreen.js')
-rw-r--r--src/js/fullscreen.js238
1 files changed, 156 insertions, 82 deletions
diff --git a/src/js/fullscreen.js b/src/js/fullscreen.js
index 366ea729..0c031276 100644
--- a/src/js/fullscreen.js
+++ b/src/js/fullscreen.js
@@ -1,127 +1,201 @@
// ==========================================================================
-// Plyr fullscreen API
+// Fullscreen wrapper
// ==========================================================================
import utils from './utils';
-// Determine the prefix
-const prefix = (() => {
- let value = false;
+const browser = utils.getBrowser();
- if (utils.is.function(document.cancelFullScreen)) {
- value = '';
+function onChange() {
+ if (!this.enabled) {
+ return;
+ }
+
+ // Update toggle button
+ const button = this.player.elements.buttons.fullscreen;
+ if (utils.is.element(button)) {
+ utils.toggleState(button, this.active);
+ }
+
+ // Trigger an event
+ utils.dispatchEvent(this.target, this.active ? 'enterfullscreen' : 'exitfullscreen', true);
+
+ // Trap focus in container
+ if (!browser.isIos) {
+ utils.trapFocus.call(this.player, this.target, this.active);
+ }
+}
+
+function toggleFallback(toggle = false) {
+ // Store or restore scroll position
+ if (toggle) {
+ this.scrollPosition = {
+ x: window.scrollX || 0,
+ y: window.scrollY || 0,
+ };
} else {
+ window.scrollTo(this.scrollPosition.x, this.scrollPosition.y);
+ }
+
+ // Toggle scroll
+ document.body.style.overflow = toggle ? 'hidden' : '';
+
+ // Toggle class hook
+ utils.toggleClass(this.target, this.player.config.classNames.fullscreen.fallback, toggle);
+
+ // Toggle button and fire events
+ onChange.call(this);
+}
+
+class Fullscreen {
+ constructor(player) {
+ // Keep reference to parent
+ this.player = player;
+
+ // Get prefix
+ this.prefix = Fullscreen.prefix;
+
+ // Scroll position
+ this.scrollPosition = { x: 0, y: 0 };
+
+ // Register event listeners
+ // Handle event (incase user presses escape etc)
+ utils.on(document, this.prefix === 'ms' ? 'MSFullscreenChange' : `${this.prefix}fullscreenchange`, () => {
+ // TODO: Filter for target??
+ onChange.call(this);
+ });
+
+ // Fullscreen toggle on double click
+ utils.on(this.player.elements.container, 'dblclick', () => {
+ this.toggle();
+ });
+
+ // Update the UI
+ this.update();
+ }
+
+ // Determine if native supported
+ static get native() {
+ return !!(document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled);
+ }
+
+ // Get the prefix for handlers
+ static get prefix() {
+ // No prefix
+ if (utils.is.function(document.cancelFullScreen)) {
+ return false;
+ }
+
// Check for fullscreen support by vendor prefix
- [
+ let value = '';
+ const prefixes = [
'webkit',
- 'o',
'moz',
'ms',
- 'khtml',
- ].some(pre => {
+ ];
+
+ prefixes.some(pre => {
if (utils.is.function(document[`${pre}CancelFullScreen`])) {
value = pre;
return true;
- } else if (utils.is.function(document.msExitFullscreen) && document.msFullscreenEnabled) {
- // Special case for MS (when isn't it?)
+ } else if (utils.is.function(document.msExitFullscreen)) {
value = 'ms';
return true;
}
return false;
});
- }
-
- return value;
-})();
-// Fullscreen API
-const fullscreen = {
- // Get the prefix
- prefix,
+ return value;
+ }
- // Check if we can use it
- enabled: document.fullscreenEnabled || document.webkitFullscreenEnabled || document.mozFullScreenEnabled || document.msFullscreenEnabled,
+ // Determine if fullscreen is enabled
+ get enabled() {
+ const fallback = this.player.config.fullscreen.fallback && !utils.inFrame();
- // Yet again Microsoft awesomeness,
- // Sometimes the prefix is 'ms', sometimes 'MS' to keep you on your toes
- eventType: prefix === 'ms' ? 'MSFullscreenChange' : `${prefix}fullscreenchange`,
+ return (Fullscreen.native || fallback) && this.player.config.fullscreen.enabled && this.player.supported.ui && this.player.isVideo;
+ }
- // Is an element fullscreen
- isFullScreen(element) {
- if (!fullscreen.enabled) {
+ // Get active state
+ get active() {
+ if (!this.enabled) {
return false;
}
- const target = utils.is.nullOrUndefined(element) ? document.body : element;
-
- switch (prefix) {
- case '':
- return document.fullscreenElement === target;
-
- case 'moz':
- return document.mozFullScreenElement === target;
-
- default:
- return document[`${prefix}FullscreenElement`] === target;
+ // Fallback using classname
+ if (!Fullscreen.native) {
+ return utils.hasClass(this.target, this.player.config.classNames.fullscreen.fallback);
}
- },
- // Make an element fullscreen
- requestFullScreen(element) {
- if (!fullscreen.enabled) {
- return false;
- }
+ const element = !this.prefix ? document.fullscreenElement : document[`${this.prefix}FullscreenElement`];
- const target = utils.is.nullOrUndefined(element) ? document.body : element;
+ return element === this.target;
+ }
- return !prefix.length ? target.requestFullScreen() : target[prefix + (prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen')]();
- },
+ // Get target element
+ get target() {
+ return browser.isIos && this.player.config.fullscreen.iosNative ? this.player.media : this.player.elements.container;
+ }
- // Bail from fullscreen
- cancelFullScreen() {
- if (!fullscreen.enabled) {
- return false;
+ // Update UI
+ update() {
+ if (this.enabled) {
+ this.player.debug.log(`${Fullscreen.native ? 'Native' : 'Fallback'} fullscreen enabled`);
+ } else {
+ this.player.debug.log('Fullscreen not supported and fallback disabled');
}
- return !prefix.length ? document.cancelFullScreen() : document[prefix + (prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen')]();
- },
+ // Add styling hook to show button
+ utils.toggleClass(this.player.elements.container, this.player.config.classNames.fullscreen.enabled, this.enabled);
+ }
- // Get the current element
- element() {
- if (!fullscreen.enabled) {
- return null;
+ // Make an element fullscreen
+ enter() {
+ if (!this.enabled) {
+ return;
}
- return !prefix.length ? document.fullscreenElement : document[`${prefix}FullscreenElement`];
- },
+ // iOS native fullscreen doesn't need the request step
+ if (browser.isIos && this.player.config.fullscreen.iosNative) {
+ if (this.player.playing) {
+ this.target.webkitEnterFullscreen();
+ }
+ } else if (!Fullscreen.native) {
+ toggleFallback.call(this, true);
+ } else if (!this.prefix) {
+ this.target.requestFullScreen();
+ } else if (!utils.is.empty(this.prefix)) {
+ this.target[`${this.prefix}${this.prefix === 'ms' ? 'RequestFullscreen' : 'RequestFullScreen'}`]();
+ }
+ }
- // Setup fullscreen
- setup() {
- if (!this.supported.ui || this.isAudio || !this.config.fullscreen.enabled) {
+ // Bail from fullscreen
+ exit() {
+ if (!this.enabled) {
return;
}
- // Check for native support
- const nativeSupport = fullscreen.enabled;
-
- if (nativeSupport || (this.config.fullscreen.fallback && !utils.inFrame())) {
- this.debug.log(`${nativeSupport ? 'Native' : 'Fallback'} fullscreen enabled`);
-
- // Add styling hook to show button
- utils.toggleClass(this.elements.container, this.config.classNames.fullscreen.enabled, true);
- } else {
- this.debug.log('Fullscreen not supported and fallback disabled');
+ // iOS native fullscreen
+ if (browser.isIos && this.player.config.fullscreen.iosNative) {
+ this.target.webkitExitFullscreen();
+ this.player.play();
+ } else if (!Fullscreen.native) {
+ toggleFallback.call(this, false);
+ } else if (!this.prefix) {
+ document.cancelFullScreen();
+ } else if (!utils.is.empty(this.prefix)) {
+ document[`${this.prefix}${this.prefix === 'ms' ? 'ExitFullscreen' : 'CancelFullScreen'}`]();
}
+ }
- // Toggle state
- if (this.elements.buttons && this.elements.buttons.fullscreen) {
- utils.toggleState(this.elements.buttons.fullscreen, false);
+ // Toggle state
+ toggle() {
+ if (!this.active) {
+ this.enter();
+ } else {
+ this.exit();
}
+ }
+}
- // Trap focus in container
- utils.trapFocus.call(this);
- },
-};
-
-export default fullscreen;
+export default Fullscreen;