--- /dev/null
+// 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;
+};
'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"]',
};
/**
- * 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
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.
this.hideFooter();
}
- if (!this.isAttached) {
- this.attachToDOM();
- }
+ this.attachToDOM();
return this.getBackdrop()
.then(function(backdrop) {
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();
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));
};
* @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"]',
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;
};
return;
}
- if (!this.isAttached) {
- this.attachToDOM();
- }
+ this.attachToDOM();
this.root.removeClass('hide').addClass('show');
};
} else {
this.getRoot().removeClass('show').addClass('hide');
}
+
+ // Ensure the modal is moved back onto the body node.
+ $(document.body).append(this.getRoot());
};
/**