diff --git a/src/core/ChefWorker.js b/src/core/ChefWorker.js index 5e45bd61..ac5d922a 100644 --- a/src/core/ChefWorker.js +++ b/src/core/ChefWorker.js @@ -12,6 +12,12 @@ import Chef from "./Chef.js"; // Set up Chef instance self.chef = new Chef(); +// Tell the app that the worker has loaded and is ready to operate +self.postMessage({ + action: "workerLoaded", + data: {} +}); + /** * Respond to message from parent thread. * diff --git a/src/web/App.js b/src/web/App.js index 946889f7..6bbb5e0b 100755 --- a/src/web/App.js +++ b/src/web/App.js @@ -54,6 +54,8 @@ App.prototype.setup = function() { this.resetLayout(); this.setCompileMessage(); this.loadURIParams(); + + this.appLoaded = true; this.loaded(); }; @@ -62,6 +64,10 @@ App.prototype.setup = function() { * Fires once all setup activities have completed. */ App.prototype.loaded = function() { + // Check that both the app and the worker have loaded successfully before + // removing the loading screen. + if (!this.worderLoaded || !this.appLoaded) return; + // Trigger CSS animations to remove preloader document.body.classList.add("loaded"); @@ -97,25 +103,20 @@ App.prototype.handleError = function(err) { App.prototype.setBakingStatus = function(bakingStatus) { this.baking = bakingStatus; - let inputLoadingIcon = document.querySelector("#input .title .loading-icon"), - outputLoadingIcon = document.querySelector("#output .title .loading-icon"), - inputElement = document.querySelector("#input-text"), - outputElement = document.querySelector("#output-text"); + let outputLoader = document.getElementById("output-loader"), + outputElement = document.getElementById("output-text"); if (bakingStatus) { - inputLoadingIcon.style.display = "inline-block"; - outputLoadingIcon.style.display = "inline-block"; - inputElement.classList.add("disabled"); - inputElement.disabled = true; - outputElement.classList.add("disabled"); - outputElement.disabled = true; + this.bakingStatusTimeout = setTimeout(function() { + outputElement.disabled = true; + outputLoader.style.visibility = "visible"; + outputLoader.style.opacity = 1; + }, 200); } else { - inputLoadingIcon.style.display = "none"; - outputLoadingIcon.style.display = "none"; - inputElement.classList.remove("disabled"); - inputElement.disabled = false; - outputElement.classList.remove("disabled"); + clearTimeout(this.bakingStatusTimeout); outputElement.disabled = false; + outputLoader.style.opacity = 0; + outputLoader.style.visibility = "hidden"; } }; @@ -160,6 +161,10 @@ App.prototype.handleChefMessage = function(e) { break; case "silentBakeComplete": break; + case "workerLoaded": + this.worderLoaded = true; + this.loaded(); + break; default: console.error("Unrecognised message from ChefWorker", e); break; diff --git a/src/web/ControlsWaiter.js b/src/web/ControlsWaiter.js index b419f95b..886cb46c 100755 --- a/src/web/ControlsWaiter.js +++ b/src/web/ControlsWaiter.js @@ -79,9 +79,6 @@ ControlsWaiter.prototype.setAutoBake = function(value) { */ ControlsWaiter.prototype.bakeClick = function() { this.app.bake(); - const outputText = document.getElementById("output-text"); - outputText.focus(); - outputText.setSelectionRange(0, 0); }; @@ -90,9 +87,6 @@ ControlsWaiter.prototype.bakeClick = function() { */ ControlsWaiter.prototype.stepClick = function() { this.app.bake(true); - const outputText = document.getElementById("output-text"); - outputText.focus(); - outputText.setSelectionRange(0, 0); }; diff --git a/src/web/html/index.html b/src/web/html/index.html index 69ea7139..a1fef8fb 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -76,7 +76,7 @@
-
+
@@ -148,7 +148,6 @@
-
@@ -165,7 +164,6 @@
-
@@ -179,6 +177,9 @@
+
+
+
diff --git a/src/web/stylesheets/layout/_io.css b/src/web/stylesheets/layout/_io.css index a4b739c0..9caca010 100644 --- a/src/web/stylesheets/layout/_io.css +++ b/src/web/stylesheets/layout/_io.css @@ -22,8 +22,6 @@ background-color: transparent; white-space: pre-wrap; word-wrap: break-word; - - transition: all 0.5s ease; } #output-html { @@ -65,6 +63,20 @@ border: none; } +#output-loader { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + margin: 0; + background-color: var(--primary-background-colour); + visibility: hidden; + opacity: 0; + + transition: all 0.5s ease; +} + .io-btn-group { float: right; margin-top: -4px; @@ -89,23 +101,3 @@ .dropping-file { border: 5px dashed var(--drop-file-border-colour) !important; } - -@keyframes spinner { - from { - transform: rotate(0deg); - } - to { - transform: rotate(359deg); - } -} - -.loading-icon::before { - content: "\21bb"; -} - -.loading-icon { - animation-name: spinner; - animation-duration: 1000ms; - animation-iteration-count: infinite; - animation-timing-function: linear; -} diff --git a/src/web/stylesheets/preloader.css b/src/web/stylesheets/preloader.css index 0caa1de0..a160ec88 100644 --- a/src/web/stylesheets/preloader.css +++ b/src/web/stylesheets/preloader.css @@ -16,7 +16,7 @@ background-color: var(--secondary-border-colour); } -#preloader { +.loader { display: block; position: relative; left: 50%; @@ -28,20 +28,19 @@ border: 3px solid transparent; border-top-color: #3498db; border-radius: 50%; - z-index: 1500; animation: spin 2s linear infinite; } -#preloader:before, -#preloader:after { +.loader:before, +.loader:after { content: ""; position: absolute; border: 3px solid transparent; border-radius: 50%; } -#preloader:before { +.loader:before { top: 5px; left: 5px; right: 5px; @@ -50,7 +49,7 @@ animation: spin 3s linear infinite; } -#preloader:after { +.loader:after { top: 13px; left: 13px; right: 13px; @@ -77,7 +76,6 @@ /* Loaded */ -.loaded #preloader, .loaded #preloader-msg { opacity: 0; transition: all 0.3s ease-out;