From ad4c6a020ff275988c1e65fd101073c1baf01943 Mon Sep 17 00:00:00 2001 From: Tacodiva <27910867+Tacodiva@users.noreply.github.com> Date: Fri, 16 Feb 2024 12:45:26 +1100 Subject: [PATCH] Implement idea suggested in #6665 --- addons/faster-project-loading/module.js | 25 +++++++++++ addons/faster-project-loading/userscript.js | 13 +++--- addons/progress-bar/userscript.js | 46 +++++++++++++++------ 3 files changed, 63 insertions(+), 21 deletions(-) create mode 100644 addons/faster-project-loading/module.js diff --git a/addons/faster-project-loading/module.js b/addons/faster-project-loading/module.js new file mode 100644 index 0000000000..56c73c26a9 --- /dev/null +++ b/addons/faster-project-loading/module.js @@ -0,0 +1,25 @@ + + +export const BACKPACK_URL = "https://backpack.scratch.mit.edu/"; + +// Inserting sprites from the backpack requests a ZIP archive from backpack.scratch.mit.edu, so we want to allow those +export const SPRITE_FILE_EXTENSION = ".zip"; + + +/** + * Returns true if a web worker request is being caused by the Scratch bug + * https://github.com/scratchfoundation/scratch-gui/issues/8805. + * @param {*} message The message being sent to the web worker. + * @returns {boolean} + */ +export function isBadRequest(message) { + if (!message) return false; + + if (typeof message.id !== "string" || typeof message.url !== "string") return false; + + if (!message.url.startsWith(BACKPACK_URL)) return false; + + if (message.url.endsWith(SPRITE_FILE_EXTENSION)) return false; + + return true; +} diff --git a/addons/faster-project-loading/userscript.js b/addons/faster-project-loading/userscript.js index 9f5bf9d5c2..1a442a7472 100644 --- a/addons/faster-project-loading/userscript.js +++ b/addons/faster-project-loading/userscript.js @@ -1,13 +1,12 @@ // This is a fix for https://github.com/scratchfoundation/scratch-gui/issues/8805 +import { BACKPACK_URL, SPRITE_FILE_EXTENSION, isBadRequest } from './module.js' + export default async function ({ addon }) { - const BACKPACK_URL = "https://backpack.scratch.mit.edu/"; - // Inserting sprites from the backpack requests a ZIP archive from backpack.scratch.mit.edu, so we want to allow those - const SPRITE_FILE_EXTENSION = ".zip"; // Dropping a code item from the backpack into a specific sprite within the sprite-pane (NOT into the code area) // requests a JSON file (https://backpack.scratch.mit.edu/{hash}.json) which we shouldn't block const CODE_FILE_EXTENSION = ".json"; - + await new Promise(r => setTimeout(r, 100)); const originalOpen = XMLHttpRequest.prototype.open; XMLHttpRequest.prototype.open = function (method, url, ...moreArgs) { if ( @@ -31,10 +30,8 @@ export default async function ({ addon }) { const originalPostMessage = Worker.prototype.postMessage; Worker.prototype.postMessage = function (message, options, ...moreArgs) { - if (!addon.self.disabled && message && typeof message.id === "string" && typeof message.url === "string") { - if (message.url.startsWith(BACKPACK_URL) && !message.url.endsWith(SPRITE_FILE_EXTENSION)) { - throw new Error("Request blocked by Scratch Addons faster project loading."); - } + if (!addon.self.disabled && isBadRequest(message)) { + throw new Error("Request blocked by Scratch Addons faster project loading."); } originalPostMessage.call(this, message, options, ...moreArgs); }; diff --git a/addons/progress-bar/userscript.js b/addons/progress-bar/userscript.js index dabd317698..a809664531 100644 --- a/addons/progress-bar/userscript.js +++ b/addons/progress-bar/userscript.js @@ -1,3 +1,6 @@ + +import { isBadRequest } from '../faster-project-loading/module.js' + export default async function ({ addon, console, msg }) { const useTopBar = addon.settings.get("topbar"); @@ -34,6 +37,9 @@ export default async function ({ addon, console, msg }) { let resetTimeout; + // A boolean indicating if the bug scratch-gui#8805 has happened. + let hasBadRequests = false; + function setProgress(progress) { if (progress < 0) progress = 0; if (progress > 1) progress = 1; @@ -74,6 +80,7 @@ export default async function ({ addon, console, msg }) { startObserver(); totalTasks = 0; finishedTasks = 0; + hasBadRequests = false; } function updateTasks() { @@ -173,24 +180,37 @@ export default async function ({ addon, console, msg }) { // Scratch uses a Worker to fetch project assets. // As the worker may be constructed before we run, we have to patch postMessage to monitor message passing. let foundWorker = false; + const originalPostMessage = Worker.prototype.postMessage; Worker.prototype.postMessage = function (message, options) { if (!addon.self.disabled && message && typeof message.id === "string" && typeof message.url === "string") { // This is a message passed to the worker to start an asset download. setLoadingPhase(LOAD_ASSETS); - totalTasks++; - updateTasks(); - - // Add our own message handler once for this worker to monitor when assets have finished loading. - if (!foundWorker) { - foundWorker = true; - this.addEventListener("message", (e) => { - const data = e.data; - if (Array.isArray(data)) { - finishedTasks += data.length; - updateTasks(); - } - }); + + function addTask() { + ++totalTasks; + updateTasks(); + } + + if (isBadRequest(message)) { + addTask(); + hasBadRequests |= true; + } else { + // Only add the task if a bad request hasn't already added it + if (!hasBadRequests) + addTask(); + + // Add our own message handler once for this worker to monitor when assets have finished loading. + if (!foundWorker) { + foundWorker = true; + this.addEventListener("message", (e) => { + const data = e.data; + if (Array.isArray(data)) { + finishedTasks += data.length; + updateTasks(); + } + }); + } } }