Commit 853908e0 authored by Evan W. Patton's avatar Evan W. Patton

Store block positions during upgrades

Blocks workspace upgraders sometimes operate on the workspace in XML
form rather than workspace form. When we did the Blockly update in May
2017, we moved updating the positions of blocks to occur immediately
before the first render of the workspace rather than at workspace load
time. This results in all blocks being at 0, 0 if the project relied
on a component where the upgrader used XML because the blocks do not
get positioned until after the upgrade has run.

This code wraps the blockToDOMWithXY function to update the position
of the block during serialization to XML if rendering is turned off,
i.e. we are loading the workspace.

Fixes #920

Change-Id: Ie19cbe4207e6c36979c2adb767748bb54def4551
parent 2da38fa8
...@@ -79,6 +79,29 @@ Blockly.Xml.domToWorkspaceHeadless = function(xml, workspace) { ...@@ -79,6 +79,29 @@ Blockly.Xml.domToWorkspaceHeadless = function(xml, workspace) {
workspace.updateVariableList(false); workspace.updateVariableList(false);
}; };
/**
* Encode a block subtree as XML with XY coordinates.
* @param {!Blockly.Block} block The root block to encode.
* @param {boolean} opt_noId True if the encoder should skip the block id.
* @return {!Element} Tree of XML elements.
*/
Blockly.Xml.blockToDomWithXY = (function(f) {
return function(block, opt_noId) {
var element = f(block, opt_noId);
if (!Blockly.Block.isRenderingOn) {
// isRenderingOn is off during loading, so we are serializing in the middle of loading a file.
// Save the XY coordinate of the block so that we don't end up with all blocks at (0, 0).
// App Inventor only positions the blocks at the very end to reduce repositioning churn going
// to/from the Blockly workspace representation. Ideally we wouldn't go between the two
// representation because DOM manipulations are costly.
var width = block.workspace.RTL ? block.workspace.getWidth() : 0;
element.setAttribute('x', block.workspace.RTL ? width - block.x : block.x);
element.setAttribute('y', block.y);
}
return element;
};
})(Blockly.Xml.blockToDomWithXY);
if (Blockly.Instrument.isOn) { if (Blockly.Instrument.isOn) {
Blockly.Xml.domToWorkspace = (function(func) { Blockly.Xml.domToWorkspace = (function(func) {
......
...@@ -52,6 +52,18 @@ page.open('blocklyeditor/src/demos/yail/yail_testing_index.html', function(statu ...@@ -52,6 +52,18 @@ page.open('blocklyeditor/src/demos/yail/yail_testing_index.html', function(statu
}, expected, formJson, blocks, args[1], args[2]); // args[1] and args[2] are blocks Version and YaV }, expected, formJson, blocks, args[1], args[2]); // args[1] and args[2] are blocks Version and YaV
// Assert that the block position of the global variable matches the pre-upgraded position.
passed = passed && page.evaluate(function() {
var topBlocks = Blockly.mainWorkspace.getTopBlocks();
for (var i = 0, block; i < topBlocks.length; i++) {
block = topBlocks[i];
if (block.type === 'global_declaration') {
return block.x === 16 && block.y === 182;
}
}
return false;
});
//This is the actual result of the test //This is the actual result of the test
console.log(passed); console.log(passed);
//Exit the phantom process //Exit the phantom process
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment