From 6dd4ca165f9dae0ebbb8582269d403f4e0deb69a Mon Sep 17 00:00:00 2001 From: DM Date: Fri, 20 Nov 2020 20:18:17 +0100 Subject: [PATCH] add fullscreen button --- locales/en.js | 4 +- public/javascripts/fullscreen.js | 143 ++++++++++++++++++++++ public/javascripts/spacedeck_sections.js | 21 ++++ views/partials/tool/toolbar-elements.html | 7 ++ views/spacedeck.ejs | 1 + 5 files changed, 175 insertions(+), 1 deletion(-) create mode 100644 public/javascripts/fullscreen.js diff --git a/locales/en.js b/locales/en.js index 6f6aa0f6..24dbb6ff 100644 --- a/locales/en.js +++ b/locales/en.js @@ -323,5 +323,7 @@ "mute_present": "Unfollow", "follow_present_help": "If someone else is presenting this Space, the other members automatically follow the presentation. Switch following on or off with this button.", "export": "export", - "media": "Media" + "media": "Media", + "fullscreen": "Fullscreen", + "window": "Window" } \ No newline at end of file diff --git a/public/javascripts/fullscreen.js b/public/javascripts/fullscreen.js new file mode 100644 index 00000000..c751dce1 --- /dev/null +++ b/public/javascripts/fullscreen.js @@ -0,0 +1,143 @@ +// https://github.com/neovov/Fullscreen-API-Polyfill +(function ( doc ) { + // Use JavaScript strict mode + "use strict"; + + /*global Element, Promise */ + + var pollute = true, + api, + vendor, + apis = { + // http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html + w3: { + enabled: "fullscreenEnabled", + element: "fullscreenElement", + request: "requestFullscreen", + exit: "exitFullscreen", + events: { + change: "fullscreenchange", + error: "fullscreenerror" + } + }, + webkit: { + enabled: "webkitFullscreenEnabled", + element: "webkitCurrentFullScreenElement", + request: "webkitRequestFullscreen", + exit: "webkitExitFullscreen", + events: { + change: "webkitfullscreenchange", + error: "webkitfullscreenerror" + } + }, + moz: { + enabled: "mozFullScreenEnabled", + element: "mozFullScreenElement", + request: "mozRequestFullScreen", + exit: "mozCancelFullScreen", + events: { + change: "mozfullscreenchange", + error: "mozfullscreenerror" + } + }, + ms: { + enabled: "msFullscreenEnabled", + element: "msFullscreenElement", + request: "msRequestFullscreen", + exit: "msExitFullscreen", + events: { + change: "MSFullscreenChange", + error: "MSFullscreenError" + } + } + }, + w3 = apis.w3; + + // Loop through each vendor's specific API + for (vendor in apis) { + // Check if document has the "enabled" property + if (apis[vendor].enabled in doc) { + // It seems this browser support the fullscreen API + api = apis[vendor]; + break; + } + } + + function dispatch( type, target ) { + var event = doc.createEvent( "Event" ); + + event.initEvent( type, true, false ); + target.dispatchEvent( event ); + } // end of dispatch() + + function handleChange( e ) { + e.stopPropagation(); + e.stopImmediatePropagation(); + + // Recopy the enabled and element values + doc[w3.enabled] = doc[api.enabled]; + doc[w3.element] = doc[api.element]; + + dispatch( w3.events.change, e.target ); + } // end of handleChange() + + function handleError( e ) { + dispatch( w3.events.error, e.target ); + } // end of handleError() + + // Prepare a resolver to use for the requestFullscreen and exitFullscreen's promises + // Use a closure since we need to check which method was used + function createResolver(method) { + return function resolver(resolve, reject) { + // Reject the promise if asked to exitFullscreen and there is no element currently in fullscreen + if (method === w3.exit && !doc[api.element]) { + setTimeout(function() { + reject(new TypeError()); + }, 1); + return; + } + + // When receiving an internal fullscreenchange event, fulfill the promise + function change() { + resolve(); + doc.removeEventListener(api.events.change, change, false); + } + + // When receiving an internal fullscreenerror event, reject the promise + function error() { + reject(new TypeError()); + doc.removeEventListener(api.events.error, error, false); + } + + doc.addEventListener(api.events.change, change, false); + doc.addEventListener(api.events.error, error, false); + }; + } + + // Pollute only if the API doesn't already exists + if (pollute && !(w3.enabled in doc) && api) { + // Add listeners for fullscreen events + doc.addEventListener( api.events.change, handleChange, false ); + doc.addEventListener( api.events.error, handleError, false ); + + // Copy the default value + doc[w3.enabled] = doc[api.enabled]; + doc[w3.element] = doc[api.element]; + + // Match the reference for exitFullscreen + doc[w3.exit] = function() { + var result = doc[api.exit](); + return !result && window.Promise ? new Promise(createResolver(w3.exit)) : result; + }; + + // Add the request method to the Element's prototype + Element.prototype[w3.request] = function () { + var result = this[api.request].apply( this, arguments ); + return !result && window.Promise ? new Promise(createResolver(w3.request)) : result; + }; + } + + // Return the API found (or undefined if the Fullscreen API is unavailable) + return api; + +}( document )); \ No newline at end of file diff --git a/public/javascripts/spacedeck_sections.js b/public/javascripts/spacedeck_sections.js index 6846a94e..86affe73 100644 --- a/public/javascripts/spacedeck_sections.js +++ b/public/javascripts/spacedeck_sections.js @@ -162,6 +162,8 @@ var SpacedeckSections = { media_search_target: "google", search_loading: false, + fullscreen: false, + viewport_zoom: 1, viewport_zoom_percent: 100, bounds_zoom: 1, @@ -381,6 +383,15 @@ var SpacedeckSections = { var hsv = rgb_to_hsv(rgba.r, rgba.g, rgba.b); this.active_style.background_color_hsv = hsv; }.bind(this)); + + + document.addEventListener('fullscreenchange', (event) => { + if (document.fullscreenElement) { + this.fullscreen = true; + } else { + this.fullscreen = false; + } + }); }, if_editable: function(fn) { @@ -587,6 +598,16 @@ var SpacedeckSections = { this.advanced_properties = !this.advanced_properties; }, + toggle_fullscreen: function() { + this.deselect(); + this.opened_dialog = "none"; + if (document.fullscreenElement) { + document.exitFullscreen(); + } else { + document.documentElement.requestFullscreen(); + } + }, + open_dialog: function(id, evt) { if (evt) { evt.stopPropagation(); diff --git a/views/partials/tool/toolbar-elements.html b/views/partials/tool/toolbar-elements.html index 061c575f..149b004c 100644 --- a/views/partials/tool/toolbar-elements.html +++ b/views/partials/tool/toolbar-elements.html @@ -121,5 +121,12 @@ <%= __('present') %> + + diff --git a/views/spacedeck.ejs b/views/spacedeck.ejs index 20b841fb..364fb800 100644 --- a/views/spacedeck.ejs +++ b/views/spacedeck.ejs @@ -28,6 +28,7 @@ +