Skip to content

Commit

Permalink
Handle comments attached to variable blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
apple502j committed Jun 30, 2020
1 parent 5d5196f commit 255d105
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
28 changes: 24 additions & 4 deletions src/serialization/sb3.js
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,8 @@ const deserializeFields = function (fields) {
* @return {object} input is modified and returned
*/
const deserializeBlocks = function (blocks) {
// oldToNew is used to fix comments attached to variable blocks: see #1893
const oldToNew = {};
for (const blockId in blocks) {
if (!Object.prototype.hasOwnProperty.call(blocks, blockId)) {
continue;
Expand All @@ -811,14 +813,14 @@ const deserializeBlocks = function (blocks) {
// delete the old entry in object.blocks and replace it w/the
// deserialized object
delete blocks[blockId];
deserializeInputDesc(block, null, false, blocks);
oldToNew[blockId] = deserializeInputDesc(block, null, false, blocks);
continue;
}
block.id = blockId; // add id back to block since it wasn't serialized
block.inputs = deserializeInputs(block.inputs, blockId, blocks);
block.fields = deserializeFields(block.fields);
}
return blocks;
return ({blocks, oldToNew});
};


Expand Down Expand Up @@ -930,12 +932,15 @@ const parseScratchObject = function (object, runtime, extensions, zip, assets) {
// @todo: For now, load all Scratch objects (stage/sprites) as a Sprite.
const sprite = new Sprite(blocks, runtime);

// Used later when parsing comments
let oldToNew = {};

// Sprite/stage name from JSON.
if (object.hasOwnProperty('name')) {
sprite.name = object.name;
}
if (object.hasOwnProperty('blocks')) {
deserializeBlocks(object.blocks);
oldToNew = deserializeBlocks(object.blocks).oldToNew;
// Take a second pass to create objects and add extensions
for (const blockId in object.blocks) {
if (!object.blocks.hasOwnProperty(blockId)) continue;
Expand Down Expand Up @@ -1031,7 +1036,22 @@ const parseScratchObject = function (object, runtime, extensions, zip, assets) {
comment.minimized
);
if (comment.blockId) {
newComment.blockId = comment.blockId;
if (oldToNew.hasOwnProperty(comment.blockId)) {
// ID for the block is changed during deserialization
newComment.blockId = oldToNew[comment.blockId];
} else {
newComment.blockId = comment.blockId;
}
// does the block really exist? if so, add reference to the comment
const block = target.blocks.getBlock(newComment.blockId);
if (block) {
block.comment = commentId;
} else {
// LLK/scratch-vm#2501
log.warn(`${commentId} is attached to a block with ID ${newComment.blockId
}, but the block does not exist.`);
continue;
}
}
target.comments[newComment.id] = newComment;
}
Expand Down
6 changes: 3 additions & 3 deletions test/unit/serialization_sb3.js
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,7 @@ test('deserializeBlocks', t => {
.then(() => {
const blocks = vm.runtime.targets[1].blocks._blocks;
const serialized = sb3.serializeBlocks(blocks)[0];
const deserialized = sb3.deserializeBlocks(serialized);
const deserialized = sb3.deserializeBlocks(serialized).blocks;
t.equal(Object.keys(deserialized).length, Object.keys(blocks).length, 'same number of blocks');
t.end();
});
Expand All @@ -271,8 +271,8 @@ test('deserializeBlocks on already deserialized input', t => {
.then(() => {
const blocks = vm.runtime.targets[1].blocks._blocks;
const serialized = sb3.serializeBlocks(blocks)[0];
const deserialized = sb3.deserializeBlocks(serialized);
const deserializedAgain = sb3.deserializeBlocks(deserialized);
const deserialized = sb3.deserializeBlocks(serialized).blocks;
const deserializedAgain = sb3.deserializeBlocks(deserialized).blocks;
t.deepEqual(deserialized, deserializedAgain, 'no change from second pass of deserialize');
t.end();
});
Expand Down

0 comments on commit 255d105

Please sign in to comment.