diff --git a/CHANGELOG.md b/CHANGELOG.md index 2d1badd1..dd8a9447 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ _This release is scheduled to be released on 2023-04-01._ - Update dates in Calendar widgets every minute - Cleanup jest coverage for patches - Update `stylelint` dependencies, switch to `stylelint-config-standard` and handle `stylelint` issues +- Convert load callbacks to async/await - Convert module start to async/await - Convert translator callbacks to async/await - Convert app-start/-stop callbacks to async/awaits diff --git a/js/loader.js b/js/loader.js index a9c8ad5f..1571dd20 100644 --- a/js/loader.js +++ b/js/loader.js @@ -33,7 +33,7 @@ const Loader = (function () { // This is done after all the modules so we can // overwrite all the defined styles. - loadFile(config.customCss, function () { + loadFile(config.customCss).then(() => { // custom.css loaded. Start all modules. startModules(); }); @@ -152,7 +152,7 @@ const Loader = (function () { if (loadedModuleFiles.indexOf(url) !== -1) { afterLoad(); } else { - loadFile(url, function () { + loadFile(url).then(() => { loadedModuleFiles.push(url); afterLoad(); }); @@ -171,9 +171,9 @@ const Loader = (function () { mObj.setData(module); - mObj.loadScripts(function () { + mObj.loadScripts().then(() => { Log.log("Scripts loaded for: " + module.name); - mObj.loadStyles(function () { + mObj.loadStyles().then(() => { Log.log("Styles loaded for: " + module.name); mObj.loadTranslations().then(() => { Log.log("Translations loaded for: " + module.name); @@ -188,52 +188,45 @@ const Loader = (function () { * Load a script or stylesheet by adding it to the dom. * * @param {string} fileName Path of the file we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - const loadFile = function (fileName, callback) { + const loadFile = async function (fileName) { const extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); let script, stylesheet; switch (extension.toLowerCase()) { case "js": - Log.log("Load script: " + fileName); - script = document.createElement("script"); - script.type = "text/javascript"; - script.src = fileName; - script.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - script.onerror = function () { - Log.error("Error on loading script:", fileName); - if (typeof callback === "function") { - callback(); - } - }; - - document.getElementsByTagName("body")[0].appendChild(script); - break; + return new Promise((resolve) => { + Log.log("Load script: " + fileName); + script = document.createElement("script"); + script.type = "text/javascript"; + script.src = fileName; + script.onload = function () { + resolve(); + }; + script.onerror = function () { + Log.error("Error on loading script:", fileName); + resolve(); + }; + document.getElementsByTagName("body")[0].appendChild(script); + }); case "css": - Log.log("Load stylesheet: " + fileName); - stylesheet = document.createElement("link"); - stylesheet.rel = "stylesheet"; - stylesheet.type = "text/css"; - stylesheet.href = fileName; - stylesheet.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - stylesheet.onerror = function () { - Log.error("Error on loading stylesheet:", fileName); - if (typeof callback === "function") { - callback(); - } - }; + return new Promise((resolve) => { + Log.log("Load stylesheet: " + fileName); - document.getElementsByTagName("head")[0].appendChild(stylesheet); - break; + stylesheet = document.createElement("link"); + stylesheet.rel = "stylesheet"; + stylesheet.type = "text/css"; + stylesheet.href = fileName; + stylesheet.onload = function () { + resolve(); + }; + stylesheet.onerror = function () { + Log.error("Error on loading stylesheet:", fileName); + resolve(); + }; + document.getElementsByTagName("head")[0].appendChild(stylesheet); + }); } }; @@ -252,35 +245,32 @@ const Loader = (function () { * * @param {string} fileName Path of the file we want to load. * @param {Module} module The module that calls the loadFile function. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - loadFile: function (fileName, module, callback) { + loadFileForModule: async function (fileName, module) { if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) { Log.log("File already loaded: " + fileName); - callback(); - return; + return Promise.resolve(); } if (fileName.indexOf("http://") === 0 || fileName.indexOf("https://") === 0 || fileName.indexOf("/") !== -1) { // This is an absolute or relative path. // Load it and then return. loadedFiles.push(fileName.toLowerCase()); - loadFile(fileName, callback); - return; + return loadFile(fileName); } if (vendor[fileName] !== undefined) { // This file is available in the vendor folder. // Load it from this vendor folder. loadedFiles.push(fileName.toLowerCase()); - loadFile(config.paths.vendor + "/" + vendor[fileName], callback); - return; + return loadFile(config.paths.vendor + "/" + vendor[fileName]); } // File not loaded yet. // Load it based on the module path. loadedFiles.push(fileName.toLowerCase()); - loadFile(module.file(fileName), callback); + return loadFile(module.file(fileName)); } }; })(); diff --git a/js/module.js b/js/module.js index 3786f61f..91e0d72e 100644 --- a/js/module.js +++ b/js/module.js @@ -261,43 +261,42 @@ const Module = Class.extend({ /** * Load all required stylesheets by requesting the MM object to load the files. * - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadStyles: function (callback) { - this.loadDependencies("getStyles", callback); + loadStyles: function () { + return this.loadDependencies("getStyles"); }, /** * Load all required scripts by requesting the MM object to load the files. * - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadScripts: function (callback) { - this.loadDependencies("getScripts", callback); + loadScripts: function () { + return this.loadDependencies("getScripts"); }, /** * Helper method to load all dependencies. * * @param {string} funcName Function name to call to get scripts or styles. - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadDependencies: function (funcName, callback) { + loadDependencies: async function (funcName) { let dependencies = this[funcName](); - const loadNextDependency = () => { + const loadNextDependency = async () => { if (dependencies.length > 0) { const nextDependency = dependencies[0]; - Loader.loadFile(nextDependency, this, () => { - dependencies = dependencies.slice(1); - loadNextDependency(); - }); + await Loader.loadFileForModule(nextDependency, this); + dependencies = dependencies.slice(1); + await loadNextDependency(); } else { - callback(); + return Promise.resolve(); } }; - loadNextDependency(); + await loadNextDependency(); }, /**