Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 25 additions & 13 deletions core/serialization/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ goog.module.declareLegacyNamespace();
const Block = goog.requireType('Blockly.Block');
// eslint-disable-next-line no-unused-vars
const Connection = goog.requireType('Blockly.Connection');
const Events = goog.require('Blockly.Events');
// eslint-disable-next-line no-unused-vars
const Workspace = goog.requireType('Blockly.Workspace');
const Xml = goog.require('Blockly.Xml');
Expand Down Expand Up @@ -71,9 +72,8 @@ exports.State = State;
* addNextBlocks: If true, children of the block which are connected to the
* block's next connection (if it exists) will be serialized.
* True by default.
* @return {?State} The serialized state of the
* block, or null if the block could not be serialied (eg it was an
* insertion marker).
* @return {?State} The serialized state of the block, or null if the block
* could not be serialied (eg it was an insertion marker).
*/
const save = function(
block,
Expand Down Expand Up @@ -262,21 +262,33 @@ const saveConnection = function(connection) {
* Loads the block represented by the given state into the given workspace.
* @param {!State} state The state of a block to deserialize into the workspace.
* @param {!Workspace} workspace The workspace to add the block to.
* @param {{recordUndo: (boolean|undefined)}=} param1
* recordUndo: If true, events triggered by this function will be undo-able
* by the user. False by default.
* @return {!Block} The block that was just loaded.
*/
const load = function(state, workspace) {
const load = function(state, workspace, {recordUndo = false} = {}) {
const prevRecordUndo = Events.recordUndo;
Events.recordUndo = recordUndo;
const existingGroup = Events.getGroup();
if (!existingGroup) {
Events.setGroup(true);
}

// We only want to fire an event for the top block.
Blockly.Events.disable();
Events.disable();

const block = loadInternal(state, workspace);

Blockly.Events.enable();
Blockly.Events.fire(
new (Blockly.Events.get(Blockly.Events.BLOCK_CREATE))(block));
Events.enable();
Events.fire(new (Events.get(Events.BLOCK_CREATE))(block));

Events.setGroup(existingGroup);
Events.recordUndo = prevRecordUndo;

// Adding connections to the connection db is expensive. This defers that
// operation to decrease load time.
if (block instanceof Blockly.BlockSvg) {
if (workspace.rendered) {
setTimeout(() => {
if (!block.disposed) {
block.setConnectionTracking(true);
Expand Down Expand Up @@ -313,7 +325,7 @@ const loadInternal = function(state, workspace, parentConnection = undefined) {
loadFields(block, state);
loadInputBlocks(block, state);
loadNextBlocks(block, state);
initBlock(block);
initBlock(block, workspace.rendered);
return block;
};

Expand Down Expand Up @@ -453,16 +465,16 @@ const loadConnection = function(connection, connectionState) {
/**
* Initializes the give block, eg init the model, inits the svg, renders, etc.
* @param {!Block} block The block to initialize.
* @param {boolean} rendered Whether the block is a rendered or headless block.
*/
const initBlock = function(block) {
if (block instanceof Blockly.BlockSvg) {
const initBlock = function(block, rendered) {
if (rendered) {
// Adding connections to the connection db is expensive. This defers that
// operation to decrease load time.
block.setConnectionTracking(false);

block.initSvg();
block.render(false);
block.updateDisabled();
} else {
block.initModel();
}
Expand Down
16 changes: 15 additions & 1 deletion core/serialization/variables.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
goog.module('Blockly.serialization.variables');
goog.module.declareLegacyNamespace();

const Events = goog.require('Blockly.Events');
// eslint-disable-next-line no-unused-vars
const VariableModel = goog.requireType('Blockly.VariableModel');
// eslint-disable-next-line no-unused-vars
Expand Down Expand Up @@ -54,9 +55,22 @@ exports.save = save;
* @param {!State} state The state of a variable to deserialize into the
* workspace.
* @param {!Workspace} workspace The workspace to add the variable to.
* @param {{recordUndo: (boolean|undefined)}=} param1
* recordUndo: If true, events triggered by this function will be undo-able
* by the user. False by default.
*/
const load = function(state, workspace) {
const load = function(state, workspace, {recordUndo = false} = {}) {
const prevRecordUndo = Events.recordUndo;
Events.recordUndo = recordUndo;
const existingGroup = Events.getGroup();
if (!existingGroup) {
Events.setGroup(true);
}

workspace.createVariable(state['name'], state['type'], state['id']);

Events.setGroup(existingGroup);
Events.recordUndo = prevRecordUndo;
};
/** @package */
exports.load = load;
54 changes: 42 additions & 12 deletions core/serialization/workspaces.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
goog.module('Blockly.serialization.workspaces');
goog.module.declareLegacyNamespace();

const Events = goog.require('Blockly.Events');
// eslint-disable-next-line no-unused-vars
const Workspace = goog.require('Blockly.Workspace');
const blocks = goog.require('Blockly.serialization.blocks');
const dom = goog.require('Blockly.utils.dom');
const variables = goog.require('Blockly.serialization.variables');


Expand All @@ -28,24 +30,27 @@ const save = function(workspace) {
const state = Object.create(null);

// TODO: Switch this to use plugin serialization system (once it is built).
const variableState = [];
const variableStates = [];
const vars = workspace.getAllVariables();
for (let i = 0; i < vars.length; i++) {
variableState.push(variables.save(vars[i]));
variableStates.push(variables.save(vars[i]));
}
if (variableState.length) {
state['variables'] = variableState;
if (variableStates.length) {
state['variables'] = variableStates;
}

const blockState = [];
const blockStates = [];
for (let block of workspace.getTopBlocks(false)) {
blockState.push(
blocks.save(block, {addCoordinates: true}));
const blockState =
blocks.save(block, {addCoordinates: true});
if (blockState) {
blockStates.push(blockState);
}
}
if (blockState.length) {
if (blockStates.length) {
// This is an object to support adding language version later.
state['blocks'] = {
'blocks': blockState
'blocks': blockStates
};
}

Expand All @@ -58,23 +63,48 @@ exports.save = save;
* @param {!Object<string, *>} state The state of the workspace to deserialize
* into the workspace.
* @param {!Workspace} workspace The workspace to add the new state to.
* @param {{recordUndo: (boolean|undefined)}=} param1
* recordUndo: If true, events triggered by this function will be undo-able
* by the user. False by default.
*/
const load = function(state, workspace) {
const load = function(state, workspace, {recordUndo = false} = {}) {
// TODO: Switch this to use plugin serialization system (once it is built).
// TODO: Add something for clearing the state before deserializing.

const prevRecordUndo = Events.recordUndo;
Events.recordUndo = recordUndo;
const existingGroup = Events.getGroup();
if (!existingGroup) {
Events.setGroup(true);
}

dom.startTextWidthCache();
if (workspace.setResizesEnabled) {
workspace.setResizesEnabled(false);
}

if (state['variables']) {
const variableStates = state['variables'];
for (let i = 0; i < variableStates.length; i++) {
variables.load(variableStates[i], workspace);
variables.load(variableStates[i], workspace, {recordUndo});
}
}

if (state['blocks']) {
const blockStates = state['blocks']['blocks'];
for (let i = 0; i < blockStates.length; i++) {
blocks.load(blockStates[i], workspace);
blocks.load(blockStates[i], workspace, {recordUndo});
}
}

if (workspace.setResizesEnabled) {
workspace.setResizesEnabled(true);
}
dom.stopTextWidthCache();

Events.fire(new (Events.get(Events.FINISHED_LOADING))(workspace));

Events.setGroup(existingGroup);
Events.recordUndo = prevRecordUndo;
};
exports.load = load;
Loading