mirror of
https://github.com/google/blockly.git
synced 2026-05-12 23:20:10 +02:00
feat: add serialization and deserialization of comments (#5216)
* Add tests for (de)seralizing icons * Add logic for (de)serializing icons * fix: add docs for saveIcons * fix: add timeout for setting comment visible
This commit is contained in:
@@ -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');
|
||||
@@ -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)
|
||||
@@ -99,6 +101,7 @@ const save = function(
|
||||
}
|
||||
saveAttributes(block, state);
|
||||
saveExtraState(block, state);
|
||||
saveIcons(block, state);
|
||||
saveFields(block, state);
|
||||
if (addInputBlocks) {
|
||||
saveInputBlocks(block, state);
|
||||
@@ -171,6 +174,25 @@ 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.
|
||||
@@ -178,7 +200,7 @@ const saveExtraState = function(block, state) {
|
||||
*/
|
||||
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++) {
|
||||
@@ -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);
|
||||
@@ -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.
|
||||
|
||||
@@ -269,6 +269,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) {
|
||||
|
||||
@@ -1830,5 +1830,4 @@ var runSerializerTestSuite = (serializer, deserializer, testSuite) => {
|
||||
};
|
||||
|
||||
runSerializerTestSuite(null, null, Serializer);
|
||||
Serializer.Icons.skip = true;
|
||||
runSerializerTestSuite(state => state, state => state, Serializer);
|
||||
|
||||
Reference in New Issue
Block a user