From a4d84e57f89a6498f3bee48f595ea4a44c04d4d3 Mon Sep 17 00:00:00 2001 From: Beka Westberg Date: Mon, 6 Sep 2021 16:28:20 +0000 Subject: [PATCH] fix: dragging blocks from the flyout that only have XML hooks (#5422) * fix: positioning of flyout blocks * fix: move flyout to JSON system * cleanup: remove test code from playground --- core/flyout_base.js | 27 ++----- core/serialization/blocks.js | 4 +- tests/playground.html | 139 ----------------------------------- 3 files changed, 10 insertions(+), 160 deletions(-) diff --git a/core/flyout_base.js b/core/flyout_base.js index 2a999cf1f06..4256485745e 100644 --- a/core/flyout_base.js +++ b/core/flyout_base.js @@ -599,8 +599,8 @@ Flyout.prototype.createFlyoutInfo_ = function(parsedContent) { switch (contentInfo['kind'].toUpperCase()) { case 'BLOCK': { - var blockInfo = /** @type {!toolbox.BlockInfo} */ (contentInfo); - var block = this.createFlyoutBlock_(blockInfo); + const blockInfo = /** @type {!toolbox.BlockInfo} */ (contentInfo); + const block = this.createFlyoutBlock_(blockInfo); contents.push({type: 'block', block: block}); this.addBlockGap_(blockInfo, gaps, defaultGap); break; @@ -633,7 +633,7 @@ Flyout.prototype.createFlyoutInfo_ = function(parsedContent) { /** * Gets the flyout definition for the dynamic category. * @param {string} categoryName The name of the dynamic category. - * @return {!Blockly.utils.toolbox.FlyoutDefinition} The definition of the + * @return {!toolbox.FlyoutDefinition} The definition of the * flyout in one of its many forms. * @private */ @@ -1073,22 +1073,11 @@ Flyout.prototype.placeNewBlock_ = function(oldBlock) { throw Error('oldBlock is not rendered.'); } - let block; - if (oldBlock.mutationToDom && !oldBlock.saveExtraState) { - // Create the new block by cloning the block in the flyout (via XML). - // This cast assumes that the oldBlock can not be an insertion marker. - const xml = /** @type {!Element} */ (Xml.blockToDom(oldBlock, true)); - // The target workspace would normally resize during domToBlock, which will - // lead to weird jumps. Save it for terminateDrag. - targetWorkspace.setResizesEnabled(false); - // Using domToBlock instead of domToWorkspace means that the new block will be - // placed at position (0, 0) in main workspace units. - block = /** @type {!BlockSvg} */ (Xml.domToBlock(xml, targetWorkspace)); - } else { - const json = /** @type {!blocks.State} */ (blocks.save(oldBlock)); - targetWorkspace.setResizesEnabled(false); - block = /** @type {!BlockSvg} */ (blocks.load(json, targetWorkspace)); - } + // Clone the block. + const json = /** @type {!blocks.State} */ (blocks.save(oldBlock)); + // Normallly this resizes leading to weird jumps. Save it for terminateDrag. + targetWorkspace.setResizesEnabled(false); + const block = /** @type {!BlockSvg} */ (blocks.load(json, targetWorkspace)); // The offset in pixels between the main workspace's origin and the upper left // corner of the injection div. diff --git a/core/serialization/blocks.js b/core/serialization/blocks.js index f2dd78d4e0d..20633a3022f 100644 --- a/core/serialization/blocks.js +++ b/core/serialization/blocks.js @@ -399,8 +399,8 @@ const loadPrivate = function( * @param {!State} state The state object to reference. */ const loadCoords = function(block, state) { - const x = state['x'] === undefined ? 10 : state['x']; - const y = state['y'] === undefined ? 10 : state['y']; + const x = state['x'] === undefined ? 0 : state['x']; + const y = state['y'] === undefined ? 0 : state['y']; block.moveBy(x, y); }; diff --git a/tests/playground.html b/tests/playground.html index c797162dd99..c94c05c2f98 100644 --- a/tests/playground.html +++ b/tests/playground.html @@ -196,19 +196,6 @@ } function initToolbox(workspace) { - workspace.registerToolboxCategoryCallback('JSON', function() { - return [ - { - 'kind': 'block', - 'type': 'lists_create_with_json' - }, - { - 'kind': 'block', - 'type': 'lists_create_with_json', - 'extraState': {'itemCount': 2} - } - ] - }); var toolboxSuffix = getToolboxSuffix(); if (toolboxSuffix == 'test-blocks' && typeof window.toolboxTestBlocksInit !== 'undefined') { @@ -460,130 +447,6 @@ 'next': { } }); - -Blockly.Blocks['lists_create_with_json'] = { - /** - * Block for creating a list with any number of elements of any type. - * @this {Blockly.Block} - */ - init: function() { - this.setHelpUrl(Blockly.Msg['LISTS_CREATE_WITH_HELPURL']); - this.setStyle('list_blocks'); - this.itemCount_ = 3; - this.updateShape_(); - this.setOutput(true, 'Array'); - this.setMutator(new Blockly.Mutator(['lists_create_with_item'])); - this.setTooltip(Blockly.Msg['LISTS_CREATE_WITH_TOOLTIP']); - }, - /** - * Returns the state of this block as a JSON serializable object. - * @return {{itemCount: number}} The state of this block, ie the item count. - */ - saveExtraState: function() { - return { - 'itemCount': this.itemCount_, - }; - }, - /** - * Applies the given state to this block. - * @param {*} state The state to apply to this block, ie the item count. - */ - loadExtraState: function(state) { - this.itemCount_ = state['itemCount']; - this.updateShape_(); - }, - /** - * Populate the mutator's dialog with this block's components. - * @param {!Blockly.Workspace} workspace Mutator's workspace. - * @return {!Blockly.Block} Root block in mutator. - * @this {Blockly.Block} - */ - decompose: function(workspace) { - var containerBlock = workspace.newBlock('lists_create_with_container'); - containerBlock.initSvg(); - var connection = containerBlock.getInput('STACK').connection; - for (var i = 0; i < this.itemCount_; i++) { - var itemBlock = workspace.newBlock('lists_create_with_item'); - itemBlock.initSvg(); - connection.connect(itemBlock.previousConnection); - connection = itemBlock.nextConnection; - } - return containerBlock; - }, - /** - * Reconfigure this block based on the mutator dialog's components. - * @param {!Blockly.Block} containerBlock Root block in mutator. - * @this {Blockly.Block} - */ - compose: function(containerBlock) { - var itemBlock = containerBlock.getInputTargetBlock('STACK'); - // Count number of inputs. - var connections = []; - while (itemBlock && !itemBlock.isInsertionMarker()) { - connections.push(itemBlock.valueConnection_); - itemBlock = itemBlock.nextConnection && - itemBlock.nextConnection.targetBlock(); - } - // Disconnect any children that don't belong. - for (var i = 0; i < this.itemCount_; i++) { - var connection = this.getInput('ADD' + i).connection.targetConnection; - if (connection && connections.indexOf(connection) == -1) { - connection.disconnect(); - } - } - this.itemCount_ = connections.length; - this.updateShape_(); - // Reconnect any child blocks. - for (var i = 0; i < this.itemCount_; i++) { - Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i); - } - }, - /** - * Store pointers to any connected child blocks. - * @param {!Blockly.Block} containerBlock Root block in mutator. - * @this {Blockly.Block} - */ - saveConnections: function(containerBlock) { - var itemBlock = containerBlock.getInputTargetBlock('STACK'); - var i = 0; - while (itemBlock) { - var input = this.getInput('ADD' + i); - itemBlock.valueConnection_ = input && input.connection.targetConnection; - i++; - itemBlock = itemBlock.nextConnection && - itemBlock.nextConnection.targetBlock(); - } - }, - /** - * Modify this block to have the correct number of inputs. - * @private - * @this {Blockly.Block} - */ - updateShape_: function() { - if (this.itemCount_ && this.getInput('EMPTY')) { - this.removeInput('EMPTY'); - } else if (!this.itemCount_ && !this.getInput('EMPTY')) { - this.appendDummyInput('EMPTY') - .appendField(Blockly.Msg['LISTS_CREATE_EMPTY_TITLE']); - } - // Add new inputs. - for (var i = 0; i < this.itemCount_; i++) { - if (!this.getInput('ADD' + i)) { - var input = this.appendValueInput('ADD' + i) - .setAlign(Blockly.ALIGN_RIGHT); - if (i == 0) { - input.appendField(Blockly.Msg['LISTS_CREATE_WITH_INPUT_WITH']); - } - } - } - // Remove deleted inputs. - while (this.getInput('ADD' + i)) { - this.removeInput('ADD' + i); - i++; - } - } -}; -