fix(script): properly load jQuery and Bootstrap in sequence

Ensures jQuery is fully loaded before attempting to load Bootstrap, improving the reliability of modal handling and iframe interactions. This change corrects potential race conditions where Bootstrap functions might be accessed before jQuery is available. This improves the stability and predictability of modal displays and iframe content interactions.
This commit is contained in:
Kumi 2024-09-23 09:00:01 +02:00
parent 110ac67686
commit 4ac9f46986
Signed by: kumi
GPG key ID: ECBCC9082395383F

267
script.js
View file

@ -42,173 +42,176 @@
});
}
waitForGlobalVariable("bootstrap")
waitForGlobalVariable("$")
.then(() => {
console.log("Bootstrap loaded successfully");
waitForGlobalVariable("bootstrap")
.then(() => {
console.log("Bootstrap loaded successfully");
var myModal = $("#fullScreenModal");
var myModal = $("#fullScreenModal");
myModal[0].addEventListener("shown.bs.modal", function () {
const modalIframe = window.$("#modal-iframe");
myModal[0].addEventListener("shown.bs.modal", function () {
const modalIframe = window.$("#modal-iframe");
modalIframe.css("width", "100%");
modalIframe.css("height", "100%");
modalIframe.css("border", "none");
modalIframe.css("width", "100%");
modalIframe.css("height", "100%");
modalIframe.css("border", "none");
// Add event handler to iframe load events
modalIframe[0].addEventListener("load", function () {
const newLocation = modalIframe[0].contentWindow.location.href;
// Add event handler to iframe load events
modalIframe[0].addEventListener("load", function () {
const newLocation = modalIframe[0].contentWindow.location.href;
// If the iframe now contains a course page, open it in the parent window
if (newLocation.includes("/course/view.php?id=")) {
window.top.location.href = newLocation;
};
});
});
// If the iframe now contains a course page, open it in the parent window
if (newLocation.includes("/course/view.php?id=")) {
window.top.location.href = newLocation;
};
});
});
var scriptId = "script-" + Math.random().toString(36).substring(2, 9);
currentScript.id = scriptId;
var scriptId = "script-" + Math.random().toString(36).substring(2, 9);
currentScript.id = scriptId;
var contentUrl = "/mod/exp360/view_content.php?id=" + $(currentScript).attr("data-activity-id");
var contentUrl = "/mod/exp360/view_content.php?id=" + $(currentScript).attr("data-activity-id");
function openInModal(url, block) {
$("#modal-iframe").attr("src", url);
if (block) {
$("#fullScreenModal").attr("data-block", block);
} else {
$("#fullScreenModal").removeAttr("data-block");
}
}
function openInModal(url, block) {
$("#modal-iframe").attr("src", url);
if (block) {
$("#fullScreenModal").attr("data-block", block);
} else {
$("#fullScreenModal").removeAttr("data-block");
}
}
function showContent(url, block) {
bootstrap.Modal.getOrCreateInstance(
document.getElementById("fullScreenModal")
).show();
if (url) {
openInModal(url, block);
}
}
function showContent(url, block) {
bootstrap.Modal.getOrCreateInstance(
document.getElementById("fullScreenModal")
).show();
if (url) {
openInModal(url, block);
}
}
function hideContent() {
bootstrap.Modal.getOrCreateInstance(
document.getElementById("fullScreenModal")
).hide();
openInModal("about:blank");
}
function hideContent() {
bootstrap.Modal.getOrCreateInstance(
document.getElementById("fullScreenModal")
).hide();
openInModal("about:blank");
}
async function nextContent() {
var modal = $("#fullScreenModal");
var currentLi = $("#" + modal.attr("data-block"));
async function nextContent() {
var modal = $("#fullScreenModal");
var currentLi = $("#" + modal.attr("data-block"));
var nextLi = currentLi.next("li.section");
var nextLi = currentLi.next("li.section");
var aLink = nextLi.find("a.stretched-link");
var aLink = nextLi.find("a.stretched-link");
if (aLink.length > 0) {
let hrefValue = aLink.attr("href");
if (aLink.length > 0) {
let hrefValue = aLink.attr("href");
if (hrefValue.includes("feedback")) {
hrefValue = hrefValue.replace("view", "complete");
hrefValue = hrefValue + "&embed=1";
} else if (hrefValue.includes("/quiz/")) {
hrefValue = hrefValue.replace("view", "attempt");
if (hrefValue.includes("feedback")) {
hrefValue = hrefValue.replace("view", "complete");
hrefValue = hrefValue + "&embed=1";
} else if (hrefValue.includes("/quiz/")) {
hrefValue = hrefValue.replace("view", "attempt");
try {
const response = await fetch(hrefValue);
hrefValue = response.url;
} catch (error) {
console.error('Error fetching the URL:', error);
try {
const response = await fetch(hrefValue);
hrefValue = response.url;
} catch (error) {
console.error('Error fetching the URL:', error);
}
hrefValue = hrefValue + "&embed=1";
}
return openInModal(hrefValue, nextLi.attr("id"));
} else {
var button = nextLi.find("button.btn-primary");
if (button.length > 0) {
return button.click();
}
}
hrefValue = hrefValue + "&embed=1";
hideContent();
}
return openInModal(hrefValue, nextLi.attr("id"));
} else {
var button = nextLi.find("button.btn-primary");
if (button.length > 0) {
return button.click();
function openUrlInQuizModal(href) {
$("#regular-modal-iframe").attr("src", href);
$("#regularModal").modal("show");
}
}
hideContent();
}
// Function to open a quiz modal
async function openQuizModal(number, openNext = true) {
openNextFlag = openNext; // Store the flag in the global variable
function openUrlInQuizModal(href) {
$("#regular-modal-iframe").attr("src", href);
$("#regularModal").modal("show");
}
let href = getFeedbackLinks()[number - 1];
const quizLink = $(`a.stretched-link[href="${href}"]`).closest("li.section");
// Function to open a quiz modal
async function openQuizModal(number, openNext = true) {
openNextFlag = openNext; // Store the flag in the global variable
if (href.includes("/feedback/")) {
href = href.replace("view", "complete");
} else if (href.includes("/quiz/")) {
href = href.replace("view", "attempt");
try {
const response = await fetch(href);
href = response.url;
} catch (error) {
console.error('Error fetching the URL:', error);
}
}
let href = getFeedbackLinks()[number - 1];
const quizLink = $(`a.stretched-link[href="${href}"]`).closest("li.section");
href = href + "&embed=1&modal=1";
openUrlInQuizModal(href);
if (href.includes("/feedback/")) {
href = href.replace("view", "complete");
} else if (href.includes("/quiz/")) {
href = href.replace("view", "attempt");
try {
const response = await fetch(href);
href = response.url;
} catch (error) {
console.error('Error fetching the URL:', error);
if (openNext) {
// Set the data-block attribute to the block containing the current quiz
$("#fullScreenModal").attr("data-block", quizLink.attr("id"));
}
}
}
href = href + "&embed=1&modal=1";
openUrlInQuizModal(href);
// Function to close the quiz modal
function closeQuizModal() {
$("#regularModal").modal("hide");
$("#regular-modal-iframe").attr("src", "about:blank");
if (openNext) {
// Set the data-block attribute to the block containing the current quiz
$("#fullScreenModal").attr("data-block", quizLink.attr("id"));
}
}
if (openNextFlag) {
nextContent(); // Open the next activity
}
}
// Function to close the quiz modal
function closeQuizModal() {
$("#regularModal").modal("hide");
$("#regular-modal-iframe").attr("src", "about:blank");
function goToCourse(id) {
window.top.location.href = "/course/view.php?id=" + id;
}
if (openNextFlag) {
nextContent(); // Open the next activity
}
}
// Attach global functions to window.top
window.top.nextContent = nextContent;
window.top.openQuizModal = openQuizModal;
window.top.openModal = openQuizModal;
window.top.closeQuizModal = closeQuizModal;
window.top.goToQuiz = window.top.nextContent;
window.top.goToCourse = goToCourse;
function goToCourse(id) {
window.top.location.href = "/course/view.php?id=" + id;
}
var contentName = $(currentScript).attr("data-activity-name");
// Attach global functions to window.top
window.top.nextContent = nextContent;
window.top.openQuizModal = openQuizModal;
window.top.openModal = openQuizModal;
window.top.closeQuizModal = closeQuizModal;
window.top.goToQuiz = window.top.nextContent;
window.top.goToCourse = goToCourse;
$(currentScript)
.parent()
.append(
`<button id="contentButton-` +
scriptId +
`" class="btn btn-primary" type="button">` +
contentName +
`</button>`
);
var contentName = $(currentScript).attr("data-activity-name");
$(currentScript)
.parent()
.append(
`<button id="contentButton-` +
scriptId +
`" class="btn btn-primary" type="button">` +
contentName +
`</button>`
);
var button = $("#contentButton-" + scriptId);
button.click(function () {
showContent(
contentUrl,
$(currentScript).closest("li.section").attr("id")
);
});
var button = $("#contentButton-" + scriptId);
button.click(function () {
showContent(
contentUrl,
$(currentScript).closest("li.section").attr("id")
);
});
})
})
.catch((error) => {
console.error(error.message);