From 44ba0226c933251aa407ece9131228ebd6ecfa27 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Thu, 14 May 2020 17:05:43 -0700 Subject: [PATCH] Add ignoring insertion markers in xml gen (#3883) * Add ignoring insertion markers in xml gen --- core/xml.js | 39 +++++- tests/mocha/insertion_marker_test.js | 185 ++++++++++++++++++++++++++- 2 files changed, 218 insertions(+), 6 deletions(-) diff --git a/core/xml.js b/core/xml.js index 0120ed279..45b3e0ca6 100644 --- a/core/xml.js +++ b/core/xml.js @@ -77,10 +77,20 @@ Blockly.Xml.variablesToDom = function(variableList) { * @return {!Element} Tree of XML elements. */ Blockly.Xml.blockToDomWithXY = function(block, opt_noId) { + if (block.isInsertionMarker()) { // Skip over insertion markers. + block = block.getChildren(false)[0]; + if (!block) { + // Disappears when appended. Cast to ANY b/c DocumentFragment -> Element + // is invalid. We have to cast to ANY in between. + return /** @type{?} */ (new DocumentFragment()); + } + } + var width; // Not used in LTR. if (block.workspace.RTL) { width = block.workspace.getWidth(); } + var element = Blockly.Xml.blockToDom(block, opt_noId); var xy = block.getRelativeToSurfaceXY(); element.setAttribute('x', @@ -131,6 +141,19 @@ Blockly.Xml.allFieldsToDom_ = function(block, element) { * @return {!Element} Tree of XML elements. */ Blockly.Xml.blockToDom = function(block, opt_noId) { + // Skip over insertion markers. + if (block.isInsertionMarker()) { + var child = block.getChildren(false)[0]; + if (child) { + return Blockly.Xml.blockToDom(child); + } else { + // Disappears when appended. Cast to ANY b/c DocumentFragment -> Element + // is invalid. We have to cast to ANY in between. + return /** @type{?} */ (new DocumentFragment()); + } + } + + var element = Blockly.utils.xml.createElement(block.isShadow() ? 'shadow' : 'block'); element.setAttribute('type', block.type); @@ -186,8 +209,11 @@ Blockly.Xml.blockToDom = function(block, opt_noId) { container.appendChild(Blockly.Xml.cloneShadow_(shadow, opt_noId)); } if (childBlock) { - container.appendChild(Blockly.Xml.blockToDom(childBlock, opt_noId)); - empty = false; + var elem = Blockly.Xml.blockToDom(childBlock, opt_noId); + if (elem.nodeType == Blockly.utils.dom.NodeType.ELEMENT_NODE) { + container.appendChild(elem); + empty = false; + } } } container.setAttribute('name', input.name); @@ -217,9 +243,12 @@ Blockly.Xml.blockToDom = function(block, opt_noId) { var nextBlock = block.getNextBlock(); if (nextBlock) { - var container = Blockly.utils.xml.createElement('next'); - container.appendChild(Blockly.Xml.blockToDom(nextBlock, opt_noId)); - element.appendChild(container); + var elem = Blockly.Xml.blockToDom(nextBlock, opt_noId); + if (elem.nodeType == Blockly.utils.dom.NodeType.ELEMENT_NODE) { + var container = Blockly.utils.xml.createElement('next'); + container.appendChild(elem); + element.appendChild(container); + } } var shadow = block.nextConnection && block.nextConnection.getShadowDom(); if (shadow && (!nextBlock || !nextBlock.isShadow())) { diff --git a/tests/mocha/insertion_marker_test.js b/tests/mocha/insertion_marker_test.js index fd3a5bc6b..afe34f2c7 100644 --- a/tests/mocha/insertion_marker_test.js +++ b/tests/mocha/insertion_marker_test.js @@ -6,7 +6,7 @@ suite('InsertionMarkers', function() { setup(function() { - this.workspace = new Blockly.Workspace(); + this.workspace = Blockly.inject('blocklyDiv', {}); Blockly.defineBlocksWithJsonArray([ { "type": "stack_block", @@ -200,4 +200,187 @@ suite('InsertionMarkers', function() { this.assertGen(xml, 'stack[a];\n'); }); }); + suite('Serialization', function() { + setup(function() { + this.assertXml = function(xml, expectXml) { + Blockly.Xml.domToWorkspace(xml, this.workspace); + var block = this.workspace.getBlockById('insertion'); + block.setInsertionMarker(true); + var xml = Blockly.Xml.workspaceToDom(this.workspace); + Blockly.Xml.domToWorkspace(xml, this.workspace); + xml = Blockly.Xml.domToText(xml); + chai.assert.equal(xml, expectXml); + }; + }); + teardown(function() { + delete this.assertXml; + }); + test('Marker Surrounds', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + // Note how the x and y are not 20, they are slightly lower and end-er + // because these are the coords of the wrapped block. + this.assertXml(xml, + '' + + '' + + ''); + }); + test('Marker Enclosed', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + this.assertXml(xml, + '' + + '' + + ''); + }); + test('Marker Enclosed and Surrounds', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + this.assertXml(xml, + '' + + '' + + '' + + '' + + '' + + '' + + ''); + }); + test('Marker Prev', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + // Note how the y coord is not at 20, it is lower. This is because these + // are the coords of the next block. + this.assertXml(xml, + '' + + '' + + ''); + }); + test('Marker Next', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + this.assertXml(xml, + '' + + '' + + ''); + }); + test('Marker Middle of Stack', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + this.assertXml(xml, + '' + + '' + + '' + + '' + + '' + + '' + + ''); + }); + test('Marker On Output', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + // Note how the x value is not at 20. This is because these are the coords + // of the wrapped block. + this.assertXml(xml, + '' + + '' + + ''); + }); + test('Marker On Input', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + this.assertXml(xml, + '' + + '' + + ''); + }); + test('Marker Middle of Row', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ' ' + + ''); + this.assertXml(xml, + '' + + '' + + '' + + '' + + '' + + '' + + ''); + }); + test('Marker Detatched', function() { + var xml = Blockly.Xml.textToDom( + '' + + ' ' + + ' ' + + ''); + this.assertXml(xml, + '' + + '' + + ''); + }); + }); });