MDL-67513 forum: View conversations while fullscreen grading
authorNeill Magill <neill.magill@nottingham.ac.uk>
Tue, 25 Aug 2020 06:47:15 +0000 (07:47 +0100)
committerNeill Magill <neill.magill@nottingham.ac.uk>
Thu, 12 Nov 2020 08:30:54 +0000 (08:30 +0000)
Before this change when a modal was shown and an element on the page
was fullscreen the modal would be created behind it.

This change ensures that the modal will be inside an element that is
fullscreen so that it will be correctly displayed.

lib/amd/build/fullscreen.min.js [new file with mode: 0644]
lib/amd/build/fullscreen.min.js.map [new file with mode: 0644]
lib/amd/build/modal.min.js
lib/amd/build/modal.min.js.map
lib/amd/build/modal_backdrop.min.js
lib/amd/build/modal_backdrop.min.js.map
lib/amd/src/fullscreen.js [new file with mode: 0644]
lib/amd/src/modal.js
lib/amd/src/modal_backdrop.js

diff --git a/lib/amd/build/fullscreen.min.js b/lib/amd/build/fullscreen.min.js
new file mode 100644 (file)
index 0000000..b227c0a
Binary files /dev/null and b/lib/amd/build/fullscreen.min.js differ
diff --git a/lib/amd/build/fullscreen.min.js.map b/lib/amd/build/fullscreen.min.js.map
new file mode 100644 (file)
index 0000000..82ff7a4
Binary files /dev/null and b/lib/amd/build/fullscreen.min.js.map differ
index 1374a94..5aef006 100644 (file)
Binary files a/lib/amd/build/modal.min.js and b/lib/amd/build/modal.min.js differ
index 3b050c2..11c184f 100644 (file)
Binary files a/lib/amd/build/modal.min.js.map and b/lib/amd/build/modal.min.js.map differ
index dfedcae..ec09403 100644 (file)
Binary files a/lib/amd/build/modal_backdrop.min.js and b/lib/amd/build/modal_backdrop.min.js differ
index 9b2bf43..27718d9 100644 (file)
Binary files a/lib/amd/build/modal_backdrop.min.js.map and b/lib/amd/build/modal_backdrop.min.js.map differ
diff --git a/lib/amd/src/fullscreen.js b/lib/amd/src/fullscreen.js
new file mode 100644 (file)
index 0000000..4ac2acc
--- /dev/null
@@ -0,0 +1,48 @@
+// 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/>.
+
+/**
+ * Detects if an element is fullscreen.
+ *
+ * @module     core/fullscreen
+ * @class      fullscreen
+ * @package    core
+ * @copyright  2020 University of Nottingham
+ * @author     Neill Magill <neill.magill@nottingham.ac.uk>
+ * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+/**
+ * Gets the element that is fullscreen or null if no element is fullscreen.
+ *
+ * @returns {HTMLElement}
+ */
+export const getElement = () => {
+    let element = null;
+    if (document.fullscreenElement) {
+        element = document.fullscreenElement;
+    } else if (document.mozFullscreenElement) {
+        // Fallback for older Firefox.
+        element = document.mozFullscreenElement;
+    } else if (document.msFullscreenElement) {
+        // Fallback for Edge and IE.
+        element = document.msFullscreenElement;
+    } else if (document.webkitFullscreenElement) {
+        // Fallback for Chrome, Edge and Safari.
+        element = document.webkitFullscreenElement;
+    }
+
+    return element;
+};
index 37ce574..3ca46d8 100644 (file)
@@ -34,7 +34,21 @@ define([
     'core/local/aria/focuslock',
     'core/pending',
     'core/aria',
-], function($, Templates, Notification, KeyCodes, CustomEvents, ModalBackdrop, Event, ModalEvents, FocusLock, Pending, Aria) {
+    'core/fullscreen'
+], function(
+    $,
+    Templates,
+    Notification,
+    KeyCodes,
+    CustomEvents,
+    ModalBackdrop,
+    Event,
+    ModalEvents,
+    FocusLock,
+    Pending,
+    Aria,
+    Fullscreen
+) {
 
     var SELECTORS = {
         CONTAINER: '[data-region="modal-container"]',
@@ -117,17 +131,20 @@ define([
     };
 
     /**
-     * Add the modal to the page, if it hasn't already been added. This includes running any
+     * Attach the modal to the correct part of the page.
+     *
+     * If it hasn't already been added it runs any
      * javascript that has been cached until now.
      *
      * @method attachToDOM
      */
     Modal.prototype.attachToDOM = function() {
+        this.getAttachmentPoint().append(this.root);
+
         if (this.isAttached) {
             return;
         }
 
-        $('body').append(this.root);
         FocusLock.trapFocus(this.root[0]);
 
         // If we'd cached any JS then we can run it how that the modal is
@@ -625,6 +642,15 @@ define([
         return this.getRoot().hasClass('fade');
     };
 
+    /**
+     * Gets the jQuery wrapped node that the Modal should be attached to.
+     *
+     * @returns {jQuery}
+     */
+    Modal.prototype.getAttachmentPoint = function() {
+        return $(Fullscreen.getElement() || document.body);
+    };
+
     /**
      * Display this modal. The modal will be attached to the DOM if it hasn't
      * already been.
@@ -645,9 +671,7 @@ define([
             this.hideFooter();
         }
 
-        if (!this.isAttached) {
-            this.attachToDOM();
-        }
+        this.attachToDOM();
 
         return this.getBackdrop()
         .then(function(backdrop) {
@@ -689,6 +713,7 @@ define([
     Modal.prototype.hide = function() {
         this.getBackdrop().done(function(backdrop) {
             FocusLock.untrapFocus();
+
             if (!this.countOtherVisibleModals()) {
                 // Hide the backdrop if we're the last open modal.
                 backdrop.hide();
@@ -710,6 +735,9 @@ define([
                 this.getRoot().removeClass('show').addClass('hide');
             }
 
+            // Ensure the modal is moved onto the body node.
+            $(document.body).append(this.getRoot());
+
             this.root.trigger(ModalEvents.hidden, this);
         }.bind(this));
     };
index 75a7b26..9cc7448 100644 (file)
@@ -22,8 +22,8 @@
  * @copyright  2016 Ryan Wyllie <ryan@moodle.com>
  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  */
-define(['jquery', 'core/templates', 'core/notification'],
-     function($, Templates, Notification) {
+define(['jquery', 'core/templates', 'core/notification', 'core/fullscreen'],
+     function($, Templates, Notification, Fullscreen) {
 
     var SELECTORS = {
         ROOT: '[data-region="modal-backdrop"]',
@@ -53,17 +53,27 @@ define(['jquery', 'core/templates', 'core/notification'],
         return this.root;
     };
 
+     /**
+      * Gets the jQuery wrapped node that the Modal should be attached to.
+      *
+      * @returns {jQuery}
+      */
+     ModalBackdrop.prototype.getAttachmentPoint = function() {
+         return $(Fullscreen.getElement() || document.body);
+     };
+
     /**
      * Add the modal backdrop to the page, if it hasn't already been added.
      *
      * @method attachToDOM
      */
     ModalBackdrop.prototype.attachToDOM = function() {
+        this.getAttachmentPoint().append(this.root);
+
         if (this.isAttached) {
             return;
         }
 
-        $('body').append(this.root);
         this.isAttached = true;
     };
 
@@ -108,9 +118,7 @@ define(['jquery', 'core/templates', 'core/notification'],
             return;
         }
 
-        if (!this.isAttached) {
-            this.attachToDOM();
-        }
+        this.attachToDOM();
 
         this.root.removeClass('hide').addClass('show');
     };
@@ -133,6 +141,9 @@ define(['jquery', 'core/templates', 'core/notification'],
         } else {
             this.getRoot().removeClass('show').addClass('hide');
         }
+
+        // Ensure the modal is moved back onto the body node.
+        $(document.body).append(this.getRoot());
     };
 
     /**