MDL-66370 mod_forum: Make a full screen layout
authorAndrew Nicols <andrew@nicols.co.uk>
Fri, 9 Aug 2019 05:10:38 +0000 (13:10 +0800)
committerMathew May <mathewm@hotmail.co.nz>
Mon, 28 Oct 2019 05:55:13 +0000 (13:55 +0800)
Part of MDL-66074

mod/forum/amd/build/local/layout/fullscreen.min.js [new file with mode: 0644]
mod/forum/amd/build/local/layout/fullscreen.min.js.map [new file with mode: 0644]
mod/forum/amd/build/local/layouts.min.js [new file with mode: 0644]
mod/forum/amd/build/local/layouts.min.js.map [new file with mode: 0644]
mod/forum/amd/src/local/layout/fullscreen.js [new file with mode: 0644]
mod/forum/amd/src/local/layouts.js [new file with mode: 0644]
theme/boost/scss/moodle.scss
theme/boost/scss/moodle/layout.scss [new file with mode: 0644]
theme/boost/style/moodle.css
theme/classic/style/moodle.css

diff --git a/mod/forum/amd/build/local/layout/fullscreen.min.js b/mod/forum/amd/build/local/layout/fullscreen.min.js
new file mode 100644 (file)
index 0000000..d63959b
Binary files /dev/null and b/mod/forum/amd/build/local/layout/fullscreen.min.js differ
diff --git a/mod/forum/amd/build/local/layout/fullscreen.min.js.map b/mod/forum/amd/build/local/layout/fullscreen.min.js.map
new file mode 100644 (file)
index 0000000..567d9e5
Binary files /dev/null and b/mod/forum/amd/build/local/layout/fullscreen.min.js.map differ
diff --git a/mod/forum/amd/build/local/layouts.min.js b/mod/forum/amd/build/local/layouts.min.js
new file mode 100644 (file)
index 0000000..0b553e4
Binary files /dev/null and b/mod/forum/amd/build/local/layouts.min.js differ
diff --git a/mod/forum/amd/build/local/layouts.min.js.map b/mod/forum/amd/build/local/layouts.min.js.map
new file mode 100644 (file)
index 0000000..89fd7f1
Binary files /dev/null and b/mod/forum/amd/build/local/layouts.min.js.map differ
diff --git a/mod/forum/amd/src/local/layout/fullscreen.js b/mod/forum/amd/src/local/layout/fullscreen.js
new file mode 100644 (file)
index 0000000..048e63b
--- /dev/null
@@ -0,0 +1,207 @@
+// This file is part of Moodle - http://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Full screen window layout.
+ *
+ * @copyright  2019 Andrew Nicols <andrew@nicols.co.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+import {addIconToContainer} from 'core/loadingicon';
+
+/**
+ * @param {string} templateName
+ * @param {object} context
+ * @return {object}
+ */
+const getComposedLayout = ({
+    fullscreen = true,
+    showLoader = true,
+} = {}) => {
+    const container = document.createElement('div');
+    document.body.append(container);
+    container.classList.add('layout');
+    container.classList.add('fullscreen');
+    container.setAttribute('aria-role', 'application');
+
+    // Lock scrolling on the document body.
+    lockBodyScroll();
+
+    const helpers = getLayoutHelpers(container);
+
+    if (showLoader) {
+        helpers.showLoadingIcon();
+    }
+
+    if (fullscreen) {
+        helpers.requestFullscreen();
+    }
+
+    return helpers;
+};
+
+const getLayoutHelpers = (layoutNode) => {
+    const contentNode = document.createElement('div');
+    layoutNode.append(contentNode);
+
+    const loadingNode = document.createElement('div');
+    layoutNode.append(loadingNode);
+
+    /**
+     * Close and destroy the window container.
+     */
+    const close = () => {
+        exitFullscreen();
+        unlockBodyScroll();
+
+        layoutNode.remove();
+    };
+
+    /**
+     * Attempt to make the conatiner full screen.
+     */
+    const requestFullscreen = () => {
+        if (layoutNode.requestFullscreen) {
+            layoutNode.requestFullscreen();
+        } else if (layoutNode.msRequestFullscreen) {
+            layoutNode.msRequestFullscreen();
+        } else if (layoutNode.mozRequestFullscreen) {
+            layoutNode.mozRequestFullscreen();
+        } else if (layoutNode.webkitRequestFullscreen) {
+            layoutNode.webkitRequestFullscreen();
+        } else {
+            // Not supported.
+            // Hack to make this act like full-screen as much as possible.
+            layoutNode.setTop(0);
+        }
+    };
+
+    /**
+     * Exit full screen but do not close the container fully.
+     */
+    const exitFullscreen = () => {
+        if (document.exitRequestFullScreen) {
+            if (document.fullScreenElement !== layoutNode) {
+                return;
+            }
+            document.exitRequestFullScreen();
+        } else if (document.msExitFullscreen) {
+            if (document.msFullscreenElement !== layoutNode) {
+                return;
+            }
+            document.msExitFullscreen();
+        } else if (document.mozCancelFullScreen) {
+            if (document.mozFullScreenElement !== layoutNode) {
+                return;
+            }
+            document.mozCancelFullScreen();
+        } else if (document.webkitExitFullscreen) {
+            if (document.webkitFullscreenElement !== layoutNode) {
+                return;
+            }
+            document.webkitExitFullscreen();
+        }
+    };
+
+    const toggleFullscreen = () => {
+        if (document.exitRequestFullScreen) {
+            if (document.fullScreenElement === layoutNode) {
+                exitFullscreen();
+            } else {
+                requestFullscreen();
+            }
+        } else if (document.msExitFullscreen) {
+            if (document.msFullscreenElement === layoutNode) {
+                exitFullscreen();
+            } else {
+                requestFullscreen();
+            }
+        } else if (document.mozCancelFullScreen) {
+            if (document.mozFullScreenElement === layoutNode) {
+                exitFullscreen();
+            } else {
+                requestFullscreen();
+            }
+        } else if (document.webkitExitFullscreen) {
+            if (document.webkitFullscreenElement === layoutNode) {
+                exitFullscreen();
+            } else {
+                requestFullscreen();
+            }
+        }
+    };
+
+    /**
+     * Get the Node which is fullscreen.
+     *
+     * @return {Element}
+     */
+    const getContainer = () => {
+        return contentNode;
+    };
+
+    const setContent = (content) => {
+        hideLoadingIcon();
+
+        // Note: It would be better to use replaceWith, but this is not compatible with IE.
+        let child = contentNode.lastElementChild;
+        while (child) {
+            contentNode.removeChild(child);
+            child = contentNode.lastElementChild;
+        }
+        contentNode.append(content);
+    };
+
+    const showLoadingIcon = () => {
+        addIconToContainer(loadingNode);
+    };
+
+    const hideLoadingIcon = () => {
+        // Hide the loading container.
+        let child = loadingNode.lastElementChild;
+        while (child) {
+            loadingNode.removeChild(child);
+            child = loadingNode.lastElementChild;
+        }
+    };
+
+    /**
+     * @return {Object}
+     */
+    return {
+        close,
+
+        toggleFullscreen,
+        requestFullscreen,
+        exitFullscreen,
+
+        getContainer,
+        setContent,
+
+        showLoadingIcon,
+        hideLoadingIcon,
+    };
+};
+
+const lockBodyScroll = () => {
+    document.querySelector('body').classList.add('overflow-hidden');
+};
+
+const unlockBodyScroll = () => {
+    document.querySelector('body').classList.remove('overflow-hidden');
+};
+
+export const createLayout = getComposedLayout;
diff --git a/mod/forum/amd/src/local/layouts.js b/mod/forum/amd/src/local/layouts.js
new file mode 100644 (file)
index 0000000..e33d869
--- /dev/null
@@ -0,0 +1,5 @@
+import {createLayout as createFullScreenWindow} from './layout/fullscreen';
+
+export {
+    createFullScreenWindow
+};
index 1b9da99..d79cd5a 100644 (file)
@@ -40,4 +40,5 @@ $breadcrumb-divider-rtl: "◀" !default;
 @import "moodle/tool_usertours";
 @import "moodle/bs2-compat";
 @import "moodle/print";
-@import "moodle/modal";
\ No newline at end of file
+@import "moodle/modal";
+@import "moodle/layout";
diff --git a/theme/boost/scss/moodle/layout.scss b/theme/boost/scss/moodle/layout.scss
new file mode 100644 (file)
index 0000000..b0ba1cb
--- /dev/null
@@ -0,0 +1,30 @@
+.layout {
+    &.fullscreen {
+        height: 100%;
+        position: fixed;
+        top: 0;
+        left: 0;
+        z-index: $zindex-modal;
+        overflow-x: hidden;
+        transition: 0.5s;
+        width: 100%;
+        margin: 0;
+        opacity: 1;
+        background-color: $modal-content-bg;
+
+        .loading-icon {
+            margin-left: auto;
+            margin-right: auto;
+            text-align: center;
+            display: inline-block;
+            width: 100%;
+            top: 40%;
+            position: fixed;
+            .icon {
+                width: 1em;
+                height: 1em;
+                font-size: 4em;
+            }
+        }
+    }
+}
index 741ae8f..7a37435 100644 (file)
@@ -18086,6 +18086,31 @@ span[data-flexitour="container"][x-placement="right"], span[data-flexitour="cont
     left: 50%;
     transform: translate(-50%, -50%); }
 
+.layout.fullscreen {
+  height: 100%;
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 1050;
+  overflow-x: hidden;
+  transition: 0.5s;
+  width: 100%;
+  margin: 0;
+  opacity: 1;
+  background-color: #fff; }
+  .layout.fullscreen .loading-icon {
+    margin-left: auto;
+    margin-right: auto;
+    text-align: center;
+    display: inline-block;
+    width: 100%;
+    top: 40%;
+    position: fixed; }
+    .layout.fullscreen .loading-icon .icon {
+      width: 1em;
+      height: 1em;
+      font-size: 4em; }
+
 body {
   -webkit-font-smoothing: antialiased; }
 
index 6620b42..6347365 100644 (file)
@@ -18326,6 +18326,31 @@ span[data-flexitour="container"][x-placement="right"], span[data-flexitour="cont
     left: 50%;
     transform: translate(-50%, -50%); }
 
+.layout.fullscreen {
+  height: 100%;
+  position: fixed;
+  top: 0;
+  left: 0;
+  z-index: 1050;
+  overflow-x: hidden;
+  transition: 0.5s;
+  width: 100%;
+  margin: 0;
+  opacity: 1;
+  background-color: #fff; }
+  .layout.fullscreen .loading-icon {
+    margin-left: auto;
+    margin-right: auto;
+    text-align: center;
+    display: inline-block;
+    width: 100%;
+    top: 40%;
+    position: fixed; }
+    .layout.fullscreen .loading-icon .icon {
+      width: 1em;
+      height: 1em;
+      font-size: 4em; }
+
 .navbar {
   box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08); }