diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index 0ea88c87..5c6c485c 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -1303,6 +1303,30 @@ export function sendStatusMessage(msg) { console.debug(msg); } +const debounceTimeouts = {}; + +/** + * Debouncer to stop functions from being executed multiple times in a + * short space of time + * https://davidwalsh.name/javascript-debounce-function + * + * @param {function} func - The function to be executed after the debounce time + * @param {number} wait - The time (ms) to wait before executing the function + * @param {string} id - Unique ID to reference the timeout for the function + * @param {object} scope - The object to bind to the debounced function + * @param {array} args - Array of arguments to be passed to func + * @returns {function} + */ +export function debounce(func, wait, id, scope, args) { + return function() { + const later = function() { + func.apply(scope, args); + }; + clearTimeout(debounceTimeouts[id]); + debounceTimeouts[id] = setTimeout(later, wait); + }; +} + /* * Polyfills diff --git a/src/web/App.mjs b/src/web/App.mjs index 606b2aff..96638f83 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -4,7 +4,7 @@ * @license Apache-2.0 */ -import Utils from "../core/Utils"; +import Utils, { debounce } from "../core/Utils"; import {fromBase64} from "../core/lib/Base64"; import Manager from "./Manager"; import HTMLCategory from "./HTMLCategory"; @@ -41,7 +41,6 @@ class App { this.autoBakePause = false; this.progress = 0; this.ingId = 0; - this.timeouts = {}; } @@ -295,7 +294,7 @@ class App { minSize: minimise ? [0, 0, 0] : [240, 310, 450], gutterSize: 4, expandToMin: true, - onDrag: this.debounce(function() { + onDrag: debounce(function() { this.manager.recipe.adjustWidth(); this.manager.input.calcMaxTabs(); this.manager.output.calcMaxTabs(); @@ -723,6 +722,7 @@ class App { this.updateTitle(false, null, true); } + /** * Update the page title to contain the new recipe * @@ -766,29 +766,6 @@ class App { this.loadURIParams(); } - - /** - * Debouncer to stop functions from being executed multiple times in a - * short space of time - * https://davidwalsh.name/javascript-debounce-function - * - * @param {function} func - The function to be executed after the debounce time - * @param {number} wait - The time (ms) to wait before executing the function - * @param {string} id - Unique ID to reference the timeout for the function - * @param {object} scope - The object to bind to the debounced function - * @param {array} args - Array of arguments to be passed to func - * @returns {function} - */ - debounce(func, wait, id, scope, args) { - return function() { - const later = function() { - func.apply(scope, args); - }; - clearTimeout(this.timeouts[id]); - this.timeouts[id] = setTimeout(later, wait); - }.bind(this); - } - } export default App; diff --git a/src/web/stylesheets/layout/_structure.css b/src/web/stylesheets/layout/_structure.css index 62ea1f9d..01777437 100755 --- a/src/web/stylesheets/layout/_structure.css +++ b/src/web/stylesheets/layout/_structure.css @@ -45,7 +45,7 @@ div#output { position: relative; } -#operations { +#operations.split { overflow: auto; } diff --git a/src/web/waiters/BackgroundWorkerWaiter.mjs b/src/web/waiters/BackgroundWorkerWaiter.mjs index a7f9b83a..3779553a 100644 --- a/src/web/waiters/BackgroundWorkerWaiter.mjs +++ b/src/web/waiters/BackgroundWorkerWaiter.mjs @@ -4,7 +4,7 @@ * @license Apache-2.0 */ -import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker"; +import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker.js"; /** * Waiter to handle conversations with a ChefWorker in the background. diff --git a/src/web/waiters/InputWaiter.mjs b/src/web/waiters/InputWaiter.mjs index e519b963..6fc240b3 100644 --- a/src/web/waiters/InputWaiter.mjs +++ b/src/web/waiters/InputWaiter.mjs @@ -5,9 +5,9 @@ * @license Apache-2.0 */ -import LoaderWorker from "worker-loader?inline&fallback=false!../workers/LoaderWorker"; -import InputWorker from "worker-loader?inline&fallback=false!../workers/InputWorker"; -import Utils from "../../core/Utils.mjs"; +import LoaderWorker from "worker-loader?inline&fallback=false!../workers/LoaderWorker.js"; +import InputWorker from "worker-loader?inline&fallback=false!../workers/InputWorker.mjs"; +import Utils, { debounce } from "../../core/Utils.mjs"; import { toBase64 } from "../../core/lib/Base64.mjs"; import { isImage } from "../../core/lib/FileType.mjs"; @@ -270,7 +270,7 @@ class InputWaiter { this.showLoadingInfo(r.data, true); break; case "setInput": - this.app.debounce(this.set, 50, "setInput", this, [r.data.inputObj, r.data.silent])(); + debounce(this.set, 50, "setInput", this, [r.data.inputObj, r.data.silent])(); break; case "inputAdded": this.inputAdded(r.data.changeTab, r.data.inputNum); @@ -316,7 +316,7 @@ class InputWaiter { */ bakeAll() { this.app.progress = 0; - this.app.debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, ["loading"]); + debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, ["loading"]); this.inputWorker.postMessage({ action: "bakeAll" }); @@ -681,7 +681,7 @@ class InputWaiter { * @param {event} e */ debounceInputChange(e) { - this.app.debounce(this.inputChange, 50, "inputChange", this, [e])(); + debounce(this.inputChange, 50, "inputChange", this, [e])(); } /** diff --git a/src/web/waiters/OutputWaiter.mjs b/src/web/waiters/OutputWaiter.mjs index 4a08fe8d..cea2b514 100755 --- a/src/web/waiters/OutputWaiter.mjs +++ b/src/web/waiters/OutputWaiter.mjs @@ -5,10 +5,10 @@ * @license Apache-2.0 */ -import Utils from "../../core/Utils.mjs"; +import Utils, { debounce } from "../../core/Utils.mjs"; import Dish from "../../core/Dish.mjs"; import FileSaver from "file-saver"; -import ZipWorker from "worker-loader?inline&fallback=false!../workers/ZipWorker"; +import ZipWorker from "worker-loader?inline&fallback=false!../workers/ZipWorker.mjs"; /** * Waiter to handle events related to the output @@ -369,7 +369,7 @@ class OutputWaiter { } this.setOutputInfo(length, lines, output.data.duration); - this.backgroundMagic(); + debounce(this.backgroundMagic, 50, "backgroundMagic", this, [])(); } }.bind(this)); } @@ -717,7 +717,7 @@ class OutputWaiter { } } - this.app.debounce(this.set, 50, "setOutput", this, [inputNum])(); + debounce(this.set, 50, "setOutput", this, [inputNum])(); document.getElementById("output-html").scroll(0, 0); document.getElementById("output-text").scroll(0, 0); diff --git a/src/web/waiters/WindowWaiter.mjs b/src/web/waiters/WindowWaiter.mjs index 5b44ff98..cee2feec 100755 --- a/src/web/waiters/WindowWaiter.mjs +++ b/src/web/waiters/WindowWaiter.mjs @@ -4,6 +4,8 @@ * @license Apache-2.0 */ +import { debounce } from "../../core/Utils.mjs"; + /** * Waiter to handle events related to the window object. */ @@ -25,7 +27,7 @@ class WindowWaiter { * continuous resetting). */ windowResize() { - this.app.debounce(this.app.resetLayout, 200, "windowResize", this.app, [])(); + debounce(this.app.resetLayout, 200, "windowResize", this.app, [])(); } diff --git a/src/web/waiters/WorkerWaiter.mjs b/src/web/waiters/WorkerWaiter.mjs index f4a5475f..877c0e02 100644 --- a/src/web/waiters/WorkerWaiter.mjs +++ b/src/web/waiters/WorkerWaiter.mjs @@ -5,8 +5,9 @@ * @license Apache-2.0 */ -import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker"; -import DishWorker from "worker-loader?inline&fallback=false!../workers/DishWorker"; +import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker.js"; +import DishWorker from "worker-loader?inline&fallback=false!../workers/DishWorker.mjs"; +import { debounce } from "../../core/Utils.mjs"; /** * Waiter to handle conversations with the ChefWorker @@ -281,7 +282,7 @@ class WorkerWaiter { */ setBakingStatus(bakingStatus) { this.app.baking = bakingStatus; - this.app.debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, [bakingStatus ? "cancel" : "bake"])(); + debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, [bakingStatus ? "cancel" : "bake"])(); if (bakingStatus) this.manager.output.hideMagicButton(); }