diff options
author | Sam Potts <sam@potts.es> | 2018-02-11 15:09:34 +1100 |
---|---|---|
committer | Sam Potts <sam@potts.es> | 2018-02-11 15:09:34 +1100 |
commit | 73a39769d4cc3d5d04e272ca571c849a0d8adfd6 (patch) | |
tree | a061524c38ed6da8c0d560096610a0cdaf36dcda /src/js/fullscreen.js | |
parent | d21b58e1c9c74ed15fb02a76c864177028882416 (diff) | |
download | plyr-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.js | 238 |
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; |