Skip to content

Commit

Permalink
Implement idea suggested in ScratchAddons#6665
Browse files Browse the repository at this point in the history
  • Loading branch information
Tacodiva committed Feb 16, 2024
1 parent aa12349 commit ad4c6a0
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 21 deletions.
25 changes: 25 additions & 0 deletions addons/faster-project-loading/module.js
Original file line number Diff line number Diff line change
@@ -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;
}
13 changes: 5 additions & 8 deletions addons/faster-project-loading/userscript.js
Original file line number Diff line number Diff line change
@@ -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 (
Expand All @@ -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);
};
Expand Down
46 changes: 33 additions & 13 deletions addons/progress-bar/userscript.js
Original file line number Diff line number Diff line change
@@ -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");

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -74,6 +80,7 @@ export default async function ({ addon, console, msg }) {
startObserver();
totalTasks = 0;
finishedTasks = 0;
hasBadRequests = false;
}

function updateTasks() {
Expand Down Expand Up @@ -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();
}
});
}
}
}

Expand Down

0 comments on commit ad4c6a0

Please sign in to comment.