From 7e29bbef17bd247515137eaaf81174de6d599c8f Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Mon, 22 May 2023 19:59:56 -0500 Subject: [PATCH] Add default extension URL for compatibility with Scratch Lab animated text projects --- src/serialization/sb3.js | 7 +- .../tw-default-extension-urls.js | 11 +++ test/integration/tw_default_extension_url.js | 79 +++++++++++++++++++ 3 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 src/serialization/tw-default-extension-urls.js create mode 100644 test/integration/tw_default_extension_url.js diff --git a/src/serialization/sb3.js b/src/serialization/sb3.js index c86faaea..59d2e1c9 100644 --- a/src/serialization/sb3.js +++ b/src/serialization/sb3.js @@ -16,6 +16,7 @@ const MathUtil = require('../util/math-util'); const StringUtil = require('../util/string-util'); const VariableUtil = require('../util/variable-util'); const compress = require('./tw-compress-sb3'); +const defaultExtensionURLs = require('./tw-default-extension-urls'); const {loadCostume} = require('../import/load-costume.js'); const {loadSound} = require('../import/load-sound.js'); @@ -1338,7 +1339,7 @@ const replaceUnsafeCharsInVariableIds = function (targets) { const deserialize = function (json, runtime, zip, isSingleSprite) { const extensions = { extensionIDs: new Set(), - extensionURLs: new Map() + extensionURLs: new Map(Object.entries(defaultExtensionURLs)) }; // Store the origin field (e.g. project originated at CSFirst) so that we can save it again. @@ -1350,7 +1351,9 @@ const deserialize = function (json, runtime, zip, isSingleSprite) { // Extract custom extension IDs, if they exist. if (json.extensionURLs) { - extensions.extensionURLs = new Map(Object.entries(json.extensionURLs)); + for (const [id, url] of Object.entries(json.extensionURLs)) { + extensions.extensionURLs.set(id, url); + } } // First keep track of the current target order in the json, diff --git a/src/serialization/tw-default-extension-urls.js b/src/serialization/tw-default-extension-urls.js new file mode 100644 index 00000000..22f248e8 --- /dev/null +++ b/src/serialization/tw-default-extension-urls.js @@ -0,0 +1,11 @@ +// If a project uses an extension but does not specify a URL, it will default to +// the URL given here, if any. This is useful for compatibility with other mods. + +const defaults = { + // Box2D (`griffpatch`) is not listed here because our extension is not actually + // compatible with the original version due to fields vs inputs. + + text: 'https://extensions.turbowarp.org/lab/text.js' +}; + +module.exports = defaults; diff --git a/test/integration/tw_default_extension_url.js b/test/integration/tw_default_extension_url.js new file mode 100644 index 00000000..77b42ea9 --- /dev/null +++ b/test/integration/tw_default_extension_url.js @@ -0,0 +1,79 @@ +const {test} = require('tap'); +const {deserialize} = require('../../src/serialization/sb3'); +const Runtime = require('../../src/engine/runtime'); + +// Note that at some point it is likely that this extension will break +test('text extension defaults to URL', async t => { + t.plan(2); + const rt = new Runtime(); + const deserialized = await deserialize({ + targets: [ + { + isStage: true, + name: 'Stage', + variables: {}, + lists: {}, + broadcasts: {}, + blocks: { + a: { + opcode: 'text_clearText', + next: null, + parent: null, + inputs: {}, + fields: {}, + shadow: false, + topLevel: true, + x: 203, + y: 250 + }, + b: { + opcode: 'pen_clear', + next: null, + parent: null, + inputs: {}, + fields: {}, + shadow: false, + topLevel: true, + x: 203, + y: 250 + }, + c: { + opcode: 'griffpatch_doTick', + next: null, + parent: null, + inputs: {}, + fields: {}, + shadow: false, + topLevel: true, + x: 203, + y: 250 + } + }, + comments: {}, + currentCostume: 0, + costumes: [], + sounds: [], + volume: 100, + layerOrder: 0, + tempo: 60, + videoTransparency: 50, + videoState: 'on', + textToSpeechLanguage: null + } + ], + monitors: [], + // this list intentionally wrong to make sure we don't rely on its contents + extensions: [], + extensionURLs: { + griffpatch: 'https://extensions.turbowarp.org/fake-box2d-url.js' + }, + meta: { + semver: '3.0.0', + vm: '0.2.0', + agent: '' + } + }, rt); + t.equal(deserialized.extensions.extensionURLs.get('text'), 'https://extensions.turbowarp.org/lab/text.js'); + t.equal(deserialized.extensions.extensionURLs.get('griffpatch'), 'https://extensions.turbowarp.org/fake-box2d-url.js'); + t.end(); +});