mirror of
https://github.com/google/blockly.git
synced 2026-01-07 00:50:27 +01:00
Adding Blockly.Xml.appendDomToWorkspace() (#962)
This is a copy (with additional comments) of PR #822 (and also #961) by @qnoirhomme with unrelated files removed. See #822 for full review.
This commit is contained in:
committed by
GitHub
parent
ef34ee5433
commit
6e1ffe09c2
58
core/xml.js
58
core/xml.js
@@ -279,6 +279,7 @@ Blockly.Xml.textToDom = function(text) {
|
||||
* Decode an XML DOM and create blocks on the workspace.
|
||||
* @param {!Element} xml XML DOM.
|
||||
* @param {!Blockly.Workspace} workspace The workspace.
|
||||
* @return {Array.<string>} An array containing new block ids.
|
||||
*/
|
||||
Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
if (xml instanceof Blockly.Workspace) {
|
||||
@@ -292,6 +293,7 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
if (workspace.RTL) {
|
||||
width = workspace.getWidth();
|
||||
}
|
||||
var newBlockIds = []; // A list of block ids added by this call.
|
||||
Blockly.Field.startCache();
|
||||
// Safari 7.1.3 is known to provide node lists with extra references to
|
||||
// children beyond the lists' length. Trust the length, do not use the
|
||||
@@ -315,6 +317,7 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
// that means an undo is in progress. Such a block is expected
|
||||
// to be moved to a nested destination in the next operation.
|
||||
var block = Blockly.Xml.domToBlock(xmlChild, workspace);
|
||||
newBlockIds.push(block.id);
|
||||
var blockX = parseInt(xmlChild.getAttribute('x'), 10);
|
||||
var blockY = parseInt(xmlChild.getAttribute('y'), 10);
|
||||
if (!isNaN(blockX) && !isNaN(blockY)) {
|
||||
@@ -334,6 +337,61 @@ Blockly.Xml.domToWorkspace = function(xml, workspace) {
|
||||
if (workspace.setResizesEnabled) {
|
||||
workspace.setResizesEnabled(true);
|
||||
}
|
||||
return newBlockIds;
|
||||
};
|
||||
|
||||
/**
|
||||
* Decode an XML DOM and create blocks on the workspace. Position the new
|
||||
* blocks immediately below prior blocks, aligned by their starting edge.
|
||||
* @param {!Element} xml The XML DOM.
|
||||
* @param {!Blockly.Workspace} workspace The workspace to add to.
|
||||
* @return {Array.<string>} An array containing new block ids.
|
||||
*/
|
||||
Blockly.Xml.appendDomToWorkspace = function(xml, workspace) {
|
||||
var bbox; //bounding box of the current blocks
|
||||
// first check if we have a workspaceSvg otherwise the block have no shape
|
||||
// and the position does not matter
|
||||
if (workspace.hasOwnProperty('scale')) {
|
||||
var savetab = Blockly.BlockSvg.TAB_WIDTH;
|
||||
try {
|
||||
Blockly.BlockSvg.TAB_WIDTH = 0;
|
||||
var bbox = workspace.getBlocksBoundingBox();
|
||||
} finally {
|
||||
Blockly.BlockSvg.TAB_WIDTH = savetab;
|
||||
}
|
||||
}
|
||||
// load the new blocks into the workspace and get the ids of the new blocks
|
||||
var newBlockIds = Blockly.Xml.domToWorkspace(xml,workspace);
|
||||
if (bbox && bbox.height) { // check if any previous block
|
||||
var offsetY = 0; // offset to add to y of the new block
|
||||
var offsetX = 0;
|
||||
var farY = bbox.y + bbox.height; //bottom position
|
||||
var topX = bbox.x; // x of bounding box
|
||||
// check position of the new blocks
|
||||
var newX = Infinity; // x of top corner
|
||||
var newY = Infinity; // y of top corner
|
||||
for (var i = 0; i < newBlockIds.length; i++) {
|
||||
var blockXY = workspace.getBlockById(newBlockIds[i]).getRelativeToSurfaceXY();
|
||||
if (blockXY.y < newY) {
|
||||
newY = blockXY.y;
|
||||
}
|
||||
if (blockXY.x < newX) { //if we align also on x
|
||||
newX = blockXY.x;
|
||||
}
|
||||
}
|
||||
offsetY = farY - newY + Blockly.BlockSvg.SEP_SPACE_Y;
|
||||
offsetX = topX - newX;
|
||||
// move the new blocks to append them at the bottom
|
||||
var width; // Not used in LTR.
|
||||
if (workspace.RTL) {
|
||||
width = workspace.getWidth();
|
||||
}
|
||||
for (var i = 0; i < newBlockIds.length; i++) {
|
||||
var block = workspace.getBlockById(newBlockIds[i]);
|
||||
block.moveBy(workspace.RTL ? width - offsetX : offsetX, offsetY);
|
||||
}
|
||||
}
|
||||
return newBlockIds;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -90,3 +90,34 @@ function test_domToPrettyText() {
|
||||
assertEquals('Round trip', XML_TEXT.replace(/\s+/g, ''),
|
||||
text.replace(/\s+/g, ''));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the that appendDomToWorkspace works in a headless mode.
|
||||
* Also see test_appendDomToWorkspace() in workspace_svg_test.js.
|
||||
*/
|
||||
unction test_appendDomToWorkspace() {
|
||||
Blockly.Blocks.test_block = {
|
||||
init: function() {
|
||||
this.jsonInit({
|
||||
message0: 'test',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
var dom = Blockly.Xml.textToDom(
|
||||
'<xml xmlns="http://www.w3.org/1999/xhtml">' +
|
||||
' <block type="test_block" inline="true" x="21" y="23">' +
|
||||
' </block>' +
|
||||
'</xml>');
|
||||
var workspace = new Blockly.Workspace();
|
||||
Blockly.Xml.appendDomToWorkspace(dom, workspace);
|
||||
assertEquals('Block count', 1, workspace.getAllBlocks().length);
|
||||
var newBlockIds = Blockly.Xml.appendDomToWorkspace(dom, workspace);
|
||||
assertEquals('Block count', 2, workspace.getAllBlocks().length);
|
||||
assertEquals('Number of new block ids',1,newBlockIds.length);
|
||||
} finally {
|
||||
delete Blockly.Blocks.test_block;
|
||||
workspace.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,3 +70,26 @@ function test_flatWorkspace() {
|
||||
workspace.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
/** Tests the alignment of appendDomToWorkspace with WorkspaceSvg. */
|
||||
function test_appendDomToWorkspace() {
|
||||
var workspace = helper_createWorkspaceWithToolbox();
|
||||
try {
|
||||
var dom = Blockly.Xml.textToDom(
|
||||
'<xml xmlns="http://www.w3.org/1999/xhtml">' +
|
||||
' <block type="math_random_float" inline="true" x="21" y="23">' +
|
||||
' </block>' +
|
||||
'</xml>');
|
||||
Blockly.Xml.appendDomToWorkspace(dom, workspace);
|
||||
assertEquals('Block count', 1, workspace.getAllBlocks().length);
|
||||
Blockly.Xml.appendDomToWorkspace(dom, workspace);
|
||||
assertEquals('Block count', 2, workspace.getAllBlocks().length);
|
||||
var blocks = workspace.getAllBlocks();
|
||||
assertEquals('Block 1 position x',21,blocks[0].getRelativeToSurfaceXY().x);
|
||||
assertEquals('Block 1 position y',23,blocks[0].getRelativeToSurfaceXY().y);
|
||||
assertEquals('Block 2 position x',21,blocks[1].getRelativeToSurfaceXY().x);
|
||||
assertEquals('Block 2 position y',23 + blocks[0].getHeightWidth().height + Blockly.BlockSvg.SEP_SPACE_Y,blocks[1].getRelativeToSurfaceXY().y);
|
||||
} finally {
|
||||
workspace.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user