Skip to content

Commit

Permalink
feat: add serialization and deserialization of comments (google#5216)
Browse files Browse the repository at this point in the history
* Add tests for (de)seralizing icons

* Add logic for (de)serializing icons

* fix: add docs for saveIcons

* fix: add timeout for setting comment visible
  • Loading branch information
BeksOmega authored and alschmiedt committed Sep 20, 2021
1 parent 91922aa commit 1b47953
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 4 deletions.
49 changes: 47 additions & 2 deletions core/serialization/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const Connection = goog.requireType('Blockly.Connection');
const Events = goog.require('Blockly.Events');
const {MissingBlockType, MissingConnection, BadConnectionCheck} =
goog.require('Blockly.serialization.exceptions');
const Size = goog.require('Blockly.utils.Size');
// eslint-disable-next-line no-unused-vars
const Workspace = goog.requireType('Blockly.Workspace');
const Xml = goog.require('Blockly.Xml');
Expand Down Expand Up @@ -54,6 +55,7 @@ exports.ConnectionState = ConnectionState;
* inline: (boolean|undefined),
* data: (string|undefined),
* extra-state: *,
* icons: (!Object<string, *>|undefined),
* fields: (!Object<string, *>|undefined),
* inputs: (!Object<string, !ConnectionState>|undefined),
* next: (!ConnectionState|undefined)
Expand Down Expand Up @@ -99,6 +101,7 @@ const save = function(
}
saveAttributes(block, state);
saveExtraState(block, state);
saveIcons(block, state);
saveFields(block, state);
if (addInputBlocks) {
saveInputBlocks(block, state);
Expand Down Expand Up @@ -171,14 +174,33 @@ const saveExtraState = function(block, state) {
}
};

/**
* Adds the state of all of the icons on the block to the given state object.
* @param {!Block} block The block to serialize the icon state of.
* @param {!State} state The state object to append to.
*/
const saveIcons = function(block, state) {
// TODO(#2105): Remove this logic and put it in the icon.
if (block.getCommentText()) {
state['icons'] = {
'comment': {
'text': block.getCommentText(),
'pinned': block.commentModel.pinned,
'height': Math.round(block.commentModel.size.height),
'width': Math.round(block.commentModel.size.width),
}
};
}
};

/**
* Adds the state of all of the fields on the block to the given state object.
* @param {!Block} block The block to serialize the field state of.
* @param {!State} state The state object to append to.
*/
const saveFields = function(block, state) {
let hasFieldState = false;
let fields = Object.create(null);
const fields = Object.create(null);
for (let i = 0; i < block.inputList.length; i++) {
const input = block.inputList[i];
for (let j = 0; j < input.fieldRow.length; j++) {
Expand Down Expand Up @@ -322,7 +344,7 @@ const loadInternal = function(state, workspace, parentConnection = undefined) {
loadAttributes(block, state);
loadExtraState(block, state);
tryToConnectParent(parentConnection, block, state);
// loadIcons(block, state);
loadIcons(block, state);
loadFields(block, state);
loadInputBlocks(block, state);
loadNextBlocks(block, state);
Expand Down Expand Up @@ -427,6 +449,29 @@ const tryToConnectParent = function(parentConnection, child, state) {
}
};

/**
* Applies icon state to the icons on the block, based on the given state
* object.
* @param {!Block} block The block to set the icon state of.
* @param {!State} state The state object to reference.
*/
const loadIcons = function(block, state) {
if (!state['icons']) {
return;
}
// TODO(#2105): Remove this logic and put it in the icon.
const comment = state['icons']['comment'];
if (comment) {
block.setCommentText(comment['text']);
block.commentModel.pinned = comment['pinned'];
block.commentModel.size = new Size(comment['width'], comment['height']);
if (comment['pinned'] && block.getCommentIcon && !block.isInFlyout) {
// Give the block a chance to be positioned and rendered before showing.
setTimeout(() => block.getCommentIcon().setVisible(true), 1);
}
}
};

/**
* Applies any field information available on the state object to the block.
* @param {!Block} block The block to set the field state of.
Expand Down
2 changes: 1 addition & 1 deletion tests/deps.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 61 additions & 0 deletions tests/mocha/jso_serialization_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,67 @@ suite('JSO Serialization', function() {
});
});

suite('Icons', function() {
suite('Comment', function() {
test('Basic', function() {
const block = this.workspace.newBlock('row_block');
block.setCommentText('test');
const jso = Blockly.serialization.blocks.save(block);
assertProperty(
jso,
'icons',
{
'comment': {
'text': 'test',
'pinned': false,
'height': 80,
'width': 160,
}
},
);
});

test('Pinned', function() {
const block = this.workspace.newBlock('row_block');
block.setCommentText('test');
block.commentModel.pinned = true;
const jso = Blockly.serialization.blocks.save(block);
assertProperty(
jso,
'icons',
{
'comment': {
'text': 'test',
'pinned': true,
'height': 80,
'width': 160,
}
},
);
});

test('Size', function() {
const block = this.workspace.newBlock('row_block');
block.setCommentText('test');
block.commentModel.size.height = 40;
block.commentModel.size.width = 320;
const jso = Blockly.serialization.blocks.save(block);
assertProperty(
jso,
'icons',
{
'comment': {
'text': 'test',
'pinned': false,
'height': 40,
'width': 320,
}
},
);
});
});
});

suite('Fields', function() {
class StringStateField extends Blockly.Field {
constructor(value, validator = undefined, config = undefined) {
Expand Down
1 change: 0 additions & 1 deletion tests/mocha/serializer_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1834,5 +1834,4 @@ var runSerializerTestSuite = (serializer, deserializer, testSuite) => {
};

runSerializerTestSuite(null, null, Serializer);
Serializer.Icons.skip = true;
runSerializerTestSuite(state => state, state => state, Serializer);

0 comments on commit 1b47953

Please sign in to comment.