diff --git a/core/events/block_events.js b/core/events/block_events.js deleted file mode 100644 index 8be1dae302e..00000000000 --- a/core/events/block_events.js +++ /dev/null @@ -1,573 +0,0 @@ -/** - * @license - * Copyright 2018 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @fileoverview Classes for all types of block events. - * @author fenichel@google.com (Rachel Fenichel) - */ -'use strict'; - -goog.provide('Blockly.Events.BlockBase'); -goog.provide('Blockly.Events.BlockChange'); -goog.provide('Blockly.Events.BlockCreate'); -goog.provide('Blockly.Events.BlockDelete'); -goog.provide('Blockly.Events.BlockMove'); -goog.provide('Blockly.Events.Change'); // Deprecated. -goog.provide('Blockly.Events.Create'); // Deprecated. -goog.provide('Blockly.Events.Delete'); // Deprecated. -goog.provide('Blockly.Events.Move'); // Deprecated. - -goog.require('Blockly.connectionTypes'); -goog.require('Blockly.Events'); -goog.require('Blockly.Events.Abstract'); -goog.require('Blockly.registry'); -goog.require('Blockly.utils.Coordinate'); -goog.require('Blockly.utils.object'); -goog.require('Blockly.utils.xml'); -goog.require('Blockly.Xml'); - -goog.requireType('Blockly.Block'); - - -/** - * Abstract class for a block event. - * @param {!Blockly.Block=} opt_block The block this event corresponds to. - * Undefined for a blank event. - * @extends {Blockly.Events.Abstract} - * @constructor - */ -Blockly.Events.BlockBase = function(opt_block) { - Blockly.Events.BlockBase.superClass_.constructor.call(this); - this.isBlank = typeof opt_block == 'undefined'; - - /** - * The block ID for the block this event pertains to - * @type {string} - */ - this.blockId = this.isBlank ? '' : opt_block.id; - - /** - * The workspace identifier for this event. - * @type {string} - */ - this.workspaceId = this.isBlank ? '' : opt_block.workspace.id; -}; -Blockly.utils.object.inherits(Blockly.Events.BlockBase, - Blockly.Events.Abstract); - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.BlockBase.prototype.toJson = function() { - var json = Blockly.Events.BlockBase.superClass_.toJson.call(this); - json['blockId'] = this.blockId; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.BlockBase.prototype.fromJson = function(json) { - Blockly.Events.BlockBase.superClass_.fromJson.call(this, json); - this.blockId = json['blockId']; -}; - -/** - * Class for a block change event. - * @param {!Blockly.Block=} opt_block The changed block. Undefined for a blank - * event. - * @param {string=} opt_element One of 'field', 'comment', 'disabled', etc. - * @param {?string=} opt_name Name of input or field affected, or null. - * @param {*=} opt_oldValue Previous value of element. - * @param {*=} opt_newValue New value of element. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockChange = function(opt_block, opt_element, opt_name, opt_oldValue, - opt_newValue) { - Blockly.Events.Change.superClass_.constructor.call(this, opt_block); - if (!opt_block) { - return; // Blank event to be populated by fromJson. - } - this.element = typeof opt_element == 'undefined' ? '' : opt_element; - this.name = typeof opt_name == 'undefined' ? '' : opt_name; - this.oldValue = typeof opt_oldValue == 'undefined' ? '' : opt_oldValue; - this.newValue = typeof opt_newValue == 'undefined' ? '' : opt_newValue; -}; -Blockly.utils.object.inherits(Blockly.Events.BlockChange, Blockly.Events.BlockBase); - -/** - * Class for a block change event. - * @param {!Blockly.Block=} opt_block The changed block. Undefined for a blank - * event. - * @param {string=} opt_element One of 'field', 'comment', 'disabled', etc. - * @param {?string=} opt_name Name of input or field affected, or null. - * @param {*=} opt_oldValue Previous value of element. - * @param {*=} opt_newValue New value of element. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Change = Blockly.Events.BlockChange; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.BlockChange.prototype.type = Blockly.Events.CHANGE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.BlockChange.prototype.toJson = function() { - var json = Blockly.Events.BlockChange.superClass_.toJson.call(this); - json['element'] = this.element; - if (this.name) { - json['name'] = this.name; - } - json['oldValue'] = this.oldValue; - json['newValue'] = this.newValue; - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.BlockChange.prototype.fromJson = function(json) { - Blockly.Events.BlockChange.superClass_.fromJson.call(this, json); - this.element = json['element']; - this.name = json['name']; - this.oldValue = json['oldValue']; - this.newValue = json['newValue']; -}; - -/** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ -Blockly.Events.BlockChange.prototype.isNull = function() { - return this.oldValue == this.newValue; -}; - -/** - * Run a change event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.BlockChange.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - var block = workspace.getBlockById(this.blockId); - if (!block) { - console.warn("Can't change non-existent block: " + this.blockId); - return; - } - if (block.mutator) { - // Close the mutator (if open) since we don't want to update it. - block.mutator.setVisible(false); - } - var value = forward ? this.newValue : this.oldValue; - switch (this.element) { - case 'field': - var field = block.getField(this.name); - if (field) { - field.setValue(value); - } else { - console.warn("Can't set non-existent field: " + this.name); - } - break; - case 'comment': - block.setCommentText(/** @type {string} */ (value) || null); - break; - case 'collapsed': - block.setCollapsed(!!value); - break; - case 'disabled': - block.setEnabled(!value); - break; - case 'inline': - block.setInputsInline(!!value); - break; - case 'mutation': - var oldMutation = ''; - if (block.mutationToDom) { - var oldMutationDom = block.mutationToDom(); - oldMutation = oldMutationDom && Blockly.Xml.domToText(oldMutationDom); - } - if (block.domToMutation) { - var dom = Blockly.Xml.textToDom(/** @type {string} */ (value) || ''); - block.domToMutation(dom); - } - Blockly.Events.fire(new Blockly.Events.BlockChange( - block, 'mutation', null, oldMutation, value)); - break; - default: - console.warn('Unknown change type: ' + this.element); - } -}; - -/** - * Class for a block creation event. - * @param {!Blockly.Block=} opt_block The created block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Create = function(opt_block) { - Blockly.Events.Create.superClass_.constructor.call(this, opt_block); - if (!opt_block) { - return; // Blank event to be populated by fromJson. - } - if (opt_block.isShadow()) { - // Moving shadow blocks is handled via disconnection. - this.recordUndo = false; - } - - if (opt_block.workspace.rendered) { - this.xml = Blockly.Xml.blockToDomWithXY(opt_block); - } else { - this.xml = Blockly.Xml.blockToDom(opt_block); - } - this.ids = Blockly.Events.getDescendantIds(opt_block); -}; -Blockly.utils.object.inherits(Blockly.Events.Create, Blockly.Events.BlockBase); - -/** - * Class for a block creation event. - * @param {!Blockly.Block=} block The created block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockCreate = Blockly.Events.Create; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Create.prototype.type = Blockly.Events.CREATE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Create.prototype.toJson = function() { - var json = Blockly.Events.Create.superClass_.toJson.call(this); - json['xml'] = Blockly.Xml.domToText(this.xml); - json['ids'] = this.ids; - if (!this.recordUndo) { - json['recordUndo'] = this.recordUndo; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Create.prototype.fromJson = function(json) { - Blockly.Events.Create.superClass_.fromJson.call(this, json); - this.xml = Blockly.Xml.textToDom(json['xml']); - this.ids = json['ids']; - if (json['recordUndo'] !== undefined) { - this.recordUndo = json['recordUndo']; - } -}; - -/** - * Run a creation event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Create.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - if (forward) { - var xml = Blockly.utils.xml.createElement('xml'); - xml.appendChild(this.xml); - Blockly.Xml.domToWorkspace(xml, workspace); - } else { - for (var i = 0, id; (id = this.ids[i]); i++) { - var block = workspace.getBlockById(id); - if (block) { - block.dispose(false); - } else if (id == this.blockId) { - // Only complain about root-level block. - console.warn("Can't uncreate non-existent block: " + id); - } - } - } -}; - -/** - * Class for a block deletion event. - * @param {!Blockly.Block=} opt_block The deleted block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Delete = function(opt_block) { - Blockly.Events.Delete.superClass_.constructor.call(this, opt_block); - if (!opt_block) { - return; // Blank event to be populated by fromJson. - } - if (opt_block.getParent()) { - throw Error('Connected blocks cannot be deleted.'); - } - if (opt_block.isShadow()) { - // Respawning shadow blocks is handled via disconnection. - this.recordUndo = false; - } - - if (opt_block.workspace.rendered) { - this.oldXml = Blockly.Xml.blockToDomWithXY(opt_block); - } else { - this.oldXml = Blockly.Xml.blockToDom(opt_block); - } - this.ids = Blockly.Events.getDescendantIds(opt_block); -}; -Blockly.utils.object.inherits(Blockly.Events.Delete, Blockly.Events.BlockBase); - -/** - * Class for a block deletion event. - * @param {?Blockly.Block} block The deleted block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockDelete = Blockly.Events.Delete; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Delete.prototype.type = Blockly.Events.DELETE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Delete.prototype.toJson = function() { - var json = Blockly.Events.Delete.superClass_.toJson.call(this); - json['oldXml'] = Blockly.Xml.domToText(this.oldXml); - json['ids'] = this.ids; - if (!this.recordUndo) { - json['recordUndo'] = this.recordUndo; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Delete.prototype.fromJson = function(json) { - Blockly.Events.Delete.superClass_.fromJson.call(this, json); - this.oldXml = Blockly.Xml.textToDom(json['oldXml']); - this.ids = json['ids']; - if (json['recordUndo'] !== undefined) { - this.recordUndo = json['recordUndo']; - } -}; - -/** - * Run a deletion event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Delete.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - if (forward) { - for (var i = 0, id; (id = this.ids[i]); i++) { - var block = workspace.getBlockById(id); - if (block) { - block.dispose(false); - } else if (id == this.blockId) { - // Only complain about root-level block. - console.warn("Can't delete non-existent block: " + id); - } - } - } else { - var xml = Blockly.utils.xml.createElement('xml'); - xml.appendChild(this.oldXml); - Blockly.Xml.domToWorkspace(xml, workspace); - } -}; - -/** - * Class for a block move event. Created before the move. - * @param {!Blockly.Block=} opt_block The moved block. Undefined for a blank - * event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.Move = function(opt_block) { - Blockly.Events.Move.superClass_.constructor.call(this, opt_block); - if (!opt_block) { - return; // Blank event to be populated by fromJson. - } - if (opt_block.isShadow()) { - // Moving shadow blocks is handled via disconnection. - this.recordUndo = false; - } - - var location = this.currentLocation_(); - this.oldParentId = location.parentId; - this.oldInputName = location.inputName; - this.oldCoordinate = location.coordinate; -}; -Blockly.utils.object.inherits(Blockly.Events.Move, Blockly.Events.BlockBase); - -/** - * Class for a block move event. Created before the move. - * @param {?Blockly.Block} block The moved block. Null for a blank event. - * @extends {Blockly.Events.BlockBase} - * @constructor - */ -Blockly.Events.BlockMove = Blockly.Events.Move; - -/** - * Type of this event. - * @type {string} - */ -Blockly.Events.Move.prototype.type = Blockly.Events.MOVE; - -/** - * Encode the event as JSON. - * @return {!Object} JSON representation. - */ -Blockly.Events.Move.prototype.toJson = function() { - var json = Blockly.Events.Move.superClass_.toJson.call(this); - if (this.newParentId) { - json['newParentId'] = this.newParentId; - } - if (this.newInputName) { - json['newInputName'] = this.newInputName; - } - if (this.newCoordinate) { - json['newCoordinate'] = Math.round(this.newCoordinate.x) + ',' + - Math.round(this.newCoordinate.y); - } - if (!this.recordUndo) { - json['recordUndo'] = this.recordUndo; - } - return json; -}; - -/** - * Decode the JSON event. - * @param {!Object} json JSON representation. - */ -Blockly.Events.Move.prototype.fromJson = function(json) { - Blockly.Events.Move.superClass_.fromJson.call(this, json); - this.newParentId = json['newParentId']; - this.newInputName = json['newInputName']; - if (json['newCoordinate']) { - var xy = json['newCoordinate'].split(','); - this.newCoordinate = - new Blockly.utils.Coordinate(Number(xy[0]), Number(xy[1])); - } - if (json['recordUndo'] !== undefined) { - this.recordUndo = json['recordUndo']; - } -}; - -/** - * Record the block's new location. Called after the move. - */ -Blockly.Events.Move.prototype.recordNew = function() { - var location = this.currentLocation_(); - this.newParentId = location.parentId; - this.newInputName = location.inputName; - this.newCoordinate = location.coordinate; -}; - -/** - * Returns the parentId and input if the block is connected, - * or the XY location if disconnected. - * @return {!Object} Collection of location info. - * @private - */ -Blockly.Events.Move.prototype.currentLocation_ = function() { - var workspace = this.getEventWorkspace_(); - var block = workspace.getBlockById(this.blockId); - var location = {}; - var parent = block.getParent(); - if (parent) { - location.parentId = parent.id; - var input = parent.getInputWithBlock(block); - if (input) { - location.inputName = input.name; - } - } else { - location.coordinate = block.getRelativeToSurfaceXY(); - } - return location; -}; - -/** - * Does this event record any change of state? - * @return {boolean} False if something changed. - */ -Blockly.Events.Move.prototype.isNull = function() { - return this.oldParentId == this.newParentId && - this.oldInputName == this.newInputName && - Blockly.utils.Coordinate.equals(this.oldCoordinate, this.newCoordinate); -}; - -/** - * Run a move event. - * @param {boolean} forward True if run forward, false if run backward (undo). - */ -Blockly.Events.Move.prototype.run = function(forward) { - var workspace = this.getEventWorkspace_(); - var block = workspace.getBlockById(this.blockId); - if (!block) { - console.warn("Can't move non-existent block: " + this.blockId); - return; - } - var parentId = forward ? this.newParentId : this.oldParentId; - var inputName = forward ? this.newInputName : this.oldInputName; - var coordinate = forward ? this.newCoordinate : this.oldCoordinate; - var parentBlock = null; - if (parentId) { - parentBlock = workspace.getBlockById(parentId); - if (!parentBlock) { - console.warn("Can't connect to non-existent block: " + parentId); - return; - } - } - if (block.getParent()) { - block.unplug(); - } - if (coordinate) { - var xy = block.getRelativeToSurfaceXY(); - block.moveBy(coordinate.x - xy.x, coordinate.y - xy.y); - } else { - var blockConnection = block.outputConnection || block.previousConnection; - var parentConnection; - var connectionType = blockConnection.type; - if (inputName) { - var input = parentBlock.getInput(inputName); - if (input) { - parentConnection = input.connection; - } - } else if (connectionType == Blockly.connectionTypes.PREVIOUS_STATEMENT) { - parentConnection = parentBlock.nextConnection; - } - if (parentConnection) { - blockConnection.connect(parentConnection); - } else { - console.warn("Can't connect to non-existent input: " + inputName); - } - } -}; - -Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.CREATE, - Blockly.Events.Create); -Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.DELETE, - Blockly.Events.Delete); -Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.CHANGE, - Blockly.Events.BlockChange); -Blockly.registry.register(Blockly.registry.Type.EVENT, Blockly.Events.MOVE, - Blockly.Events.Move); diff --git a/core/events/events_block_base.js b/core/events/events_block_base.js new file mode 100644 index 00000000000..1f22a4ed86d --- /dev/null +++ b/core/events/events_block_base.js @@ -0,0 +1,66 @@ +/** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Base class for all types of block events. + * @author fenichel@google.com (Rachel Fenichel) + */ +'use strict'; + +goog.module('Blockly.Events.BlockBase'); +goog.module.declareLegacyNamespace(); + +const Abstract = goog.require('Blockly.Events.Abstract'); +/* eslint-disable-next-line no-unused-vars */ +const Block = goog.requireType('Blockly.Block'); +const object = goog.require('Blockly.utils.object'); + + +/** + * Abstract class for a block event. + * @param {!Block=} opt_block The block this event corresponds to. + * Undefined for a blank event. + * @extends {Abstract} + * @constructor + */ +const BlockBase = function(opt_block) { + BlockBase.superClass_.constructor.call(this); + this.isBlank = typeof opt_block == 'undefined'; + + /** + * The block ID for the block this event pertains to + * @type {string} + */ + this.blockId = this.isBlank ? '' : opt_block.id; + + /** + * The workspace identifier for this event. + * @type {string} + */ + this.workspaceId = this.isBlank ? '' : opt_block.workspace.id; +}; +object.inherits(BlockBase, Abstract); + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +BlockBase.prototype.toJson = function() { + const json = BlockBase.superClass_.toJson.call(this); + json['blockId'] = this.blockId; + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +BlockBase.prototype.fromJson = function(json) { + BlockBase.superClass_.fromJson.call(this, json); + this.blockId = json['blockId']; +}; + +exports = BlockBase; diff --git a/core/events/events_block_change.js b/core/events/events_block_change.js new file mode 100644 index 00000000000..3814a0d27ea --- /dev/null +++ b/core/events/events_block_change.js @@ -0,0 +1,148 @@ +/** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Class for a block change event. + * @author fenichel@google.com (Rachel Fenichel) + */ +'use strict'; + +goog.module('Blockly.Events.BlockChange'); +goog.module.declareLegacyNamespace(); + +/* eslint-disable-next-line no-unused-vars */ +const Block = goog.requireType('Blockly.Block'); +const Events = goog.require('Blockly.Events'); +const Xml = goog.require('Blockly.Xml'); +const object = goog.require('Blockly.utils.object'); +const registry = goog.require('Blockly.registry'); + + +/** + * Class for a block change event. + * @param {!Block=} opt_block The changed block. Undefined for a blank + * event. + * @param {string=} opt_element One of 'field', 'comment', 'disabled', etc. + * @param {?string=} opt_name Name of input or field affected, or null. + * @param {*=} opt_oldValue Previous value of element. + * @param {*=} opt_newValue New value of element. + * @extends {Events.BlockBase} + * @constructor + */ +const BlockChange = function( + opt_block, opt_element, opt_name, opt_oldValue, opt_newValue) { + BlockChange.superClass_.constructor.call(this, opt_block); + if (!opt_block) { + return; // Blank event to be populated by fromJson. + } + this.element = typeof opt_element == 'undefined' ? '' : opt_element; + this.name = typeof opt_name == 'undefined' ? '' : opt_name; + this.oldValue = typeof opt_oldValue == 'undefined' ? '' : opt_oldValue; + this.newValue = typeof opt_newValue == 'undefined' ? '' : opt_newValue; +}; +object.inherits(BlockChange, Events.BlockBase); + +/** + * Type of this event. + * @type {string} + */ +BlockChange.prototype.type = Events.BLOCK_CHANGE; + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +BlockChange.prototype.toJson = function() { + const json = BlockChange.superClass_.toJson.call(this); + json['element'] = this.element; + if (this.name) { + json['name'] = this.name; + } + json['oldValue'] = this.oldValue; + json['newValue'] = this.newValue; + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +BlockChange.prototype.fromJson = function(json) { + BlockChange.superClass_.fromJson.call(this, json); + this.element = json['element']; + this.name = json['name']; + this.oldValue = json['oldValue']; + this.newValue = json['newValue']; +}; + +/** + * Does this event record any change of state? + * @return {boolean} False if something changed. + */ +BlockChange.prototype.isNull = function() { + return this.oldValue == this.newValue; +}; + +/** + * Run a change event. + * @param {boolean} forward True if run forward, false if run backward (undo). + */ +BlockChange.prototype.run = function(forward) { + const workspace = this.getEventWorkspace_(); + const block = workspace.getBlockById(this.blockId); + if (!block) { + console.warn('Can\'t change non-existent block: ' + this.blockId); + return; + } + if (block.mutator) { + // Close the mutator (if open) since we don't want to update it. + block.mutator.setVisible(false); + } + const value = forward ? this.newValue : this.oldValue; + switch (this.element) { + case 'field': { + const field = block.getField(this.name); + if (field) { + field.setValue(value); + } else { + console.warn('Can\'t set non-existent field: ' + this.name); + } + break; + } + case 'comment': + block.setCommentText(/** @type {string} */ (value) || null); + break; + case 'collapsed': + block.setCollapsed(!!value); + break; + case 'disabled': + block.setEnabled(!value); + break; + case 'inline': + block.setInputsInline(!!value); + break; + case 'mutation': { + let oldMutation = ''; + if (block.mutationToDom) { + const oldMutationDom = block.mutationToDom(); + oldMutation = oldMutationDom && Xml.domToText(oldMutationDom); + } + if (block.domToMutation) { + const dom = Xml.textToDom(/** @type {string} */ + (value) || ''); + block.domToMutation(dom); + } + Events.fire(new BlockChange(block, 'mutation', null, oldMutation, value)); + break; + } + default: + console.warn('Unknown change type: ' + this.element); + } +}; + +registry.register(registry.Type.EVENT, Events.CHANGE, BlockChange); + +exports = BlockChange; diff --git a/core/events/events_block_create.js b/core/events/events_block_create.js new file mode 100644 index 00000000000..2a6afb003fc --- /dev/null +++ b/core/events/events_block_create.js @@ -0,0 +1,111 @@ +/** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Class for a block creation event. + * @author fenichel@google.com (Rachel Fenichel) + */ +'use strict'; + +goog.module('Blockly.Events.BlockCreate'); +goog.module.declareLegacyNamespace(); + +/* eslint-disable-next-line no-unused-vars */ +const Block = goog.requireType('Blockly.Block'); +const BlockBase = goog.require('Blockly.Events.BlockBase'); +const Events = goog.require('Blockly.Events'); +const Xml = goog.require('Blockly.Xml'); +const object = goog.require('Blockly.utils.object'); +const registry = goog.require('Blockly.registry'); +const xml = goog.require('Blockly.utils.xml'); + + +/** + * Class for a block creation event. + * @param {!Block=} opt_block The created block. Undefined for a blank + * event. + * @extends {BlockBase} + * @constructor + */ +const BlockCreate = function(opt_block) { + BlockCreate.superClass_.constructor.call(this, opt_block); + if (!opt_block) { + return; // Blank event to be populated by fromJson. + } + if (opt_block.isShadow()) { + // Moving shadow blocks is handled via disconnection. + this.recordUndo = false; + } + + if (opt_block.workspace.rendered) { + this.xml = Xml.blockToDomWithXY(opt_block); + } else { + this.xml = Xml.blockToDom(opt_block); + } + this.ids = Events.getDescendantIds(opt_block); +}; +object.inherits(BlockCreate, BlockBase); + +/** + * Type of this event. + * @type {string} + */ +BlockCreate.prototype.type = Events.BLOCK_CREATE; + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +BlockCreate.prototype.toJson = function() { + const json = BlockCreate.superClass_.toJson.call(this); + json['xml'] = Xml.domToText(this.xml); + json['ids'] = this.ids; + if (!this.recordUndo) { + json['recordUndo'] = this.recordUndo; + } + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +BlockCreate.prototype.fromJson = function(json) { + BlockCreate.superClass_.fromJson.call(this, json); + this.xml = Xml.textToDom(json['xml']); + this.ids = json['ids']; + if (json['recordUndo'] !== undefined) { + this.recordUndo = json['recordUndo']; + } +}; + +/** + * Run a creation event. + * @param {boolean} forward True if run forward, false if run backward (undo). + */ +BlockCreate.prototype.run = function(forward) { + const workspace = this.getEventWorkspace_(); + if (forward) { + const xmlEl = xml.createElement('xml'); + xmlEl.appendChild(this.xml); + Xml.domToWorkspace(xmlEl, workspace); + } else { + for (let i = 0; i < this.ids.length; i++) { + const id = this.ids[i]; + const block = workspace.getBlockById(id); + if (block) { + block.dispose(false); + } else if (id == this.blockId) { + // Only complain about root-level block. + console.warn('Can\'t uncreate non-existent block: ' + id); + } + } + } +}; + +registry.register(registry.Type.EVENT, Events.CREATE, BlockCreate); + +exports = BlockCreate; diff --git a/core/events/events_block_delete.js b/core/events/events_block_delete.js new file mode 100644 index 00000000000..f44caa7f019 --- /dev/null +++ b/core/events/events_block_delete.js @@ -0,0 +1,114 @@ +/** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Class for a block delete event. + * @author fenichel@google.com (Rachel Fenichel) + */ +'use strict'; + +goog.module('Blockly.Events.BlockDelete'); +goog.module.declareLegacyNamespace(); + +/* eslint-disable-next-line no-unused-vars */ +const Block = goog.requireType('Blockly.Block'); +const BlockBase = goog.require('Blockly.Events.BlockBase'); +const Events = goog.require('Blockly.Events'); +const Xml = goog.require('Blockly.Xml'); +const object = goog.require('Blockly.utils.object'); +const registry = goog.require('Blockly.registry'); +const xml = goog.require('Blockly.utils.xml'); + + +/** + * Class for a block deletion event. + * @param {!Block=} opt_block The deleted block. Undefined for a blank + * event. + * @extends {BlockBase} + * @constructor + */ +const BlockDelete = function(opt_block) { + BlockDelete.superClass_.constructor.call(this, opt_block); + if (!opt_block) { + return; // Blank event to be populated by fromJson. + } + if (opt_block.getParent()) { + throw Error('Connected blocks cannot be deleted.'); + } + if (opt_block.isShadow()) { + // Respawning shadow blocks is handled via disconnection. + this.recordUndo = false; + } + + if (opt_block.workspace.rendered) { + this.oldXml = Xml.blockToDomWithXY(opt_block); + } else { + this.oldXml = Xml.blockToDom(opt_block); + } + this.ids = Events.getDescendantIds(opt_block); +}; +object.inherits(BlockDelete, BlockBase); + +/** + * Type of this event. + * @type {string} + */ +BlockDelete.prototype.type = Events.BLOCK_DELETE; + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +BlockDelete.prototype.toJson = function() { + const json = BlockDelete.superClass_.toJson.call(this); + json['oldXml'] = Xml.domToText(this.oldXml); + json['ids'] = this.ids; + if (!this.recordUndo) { + json['recordUndo'] = this.recordUndo; + } + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +BlockDelete.prototype.fromJson = function(json) { + BlockDelete.superClass_.fromJson.call(this, json); + this.oldXml = Xml.textToDom(json['oldXml']); + this.ids = json['ids']; + if (json['recordUndo'] !== undefined) { + this.recordUndo = json['recordUndo']; + } +}; + +/** + * Run a deletion event. + * @param {boolean} forward True if run forward, false if run backward (undo). + */ +BlockDelete.prototype.run = function(forward) { + const workspace = this.getEventWorkspace_(); + if (forward) { + for (let i = 0; i < this.ids.length; i++) { + const id = this.ids[i]; + const block = workspace.getBlockById(id); + if (block) { + block.dispose(false); + } else if (id == this.blockId) { + // Only complain about root-level block. + console.warn('Can\'t delete non-existent block: ' + id); + } + } + } else { + const xmlEl = xml.createElement('xml'); + xmlEl.appendChild(this.oldXml); + Xml.domToWorkspace(xmlEl, workspace); + } +}; + +registry.register(registry.Type.EVENT, Events.DELETE, BlockDelete); + +exports = BlockDelete; diff --git a/core/events/events_block_move.js b/core/events/events_block_move.js new file mode 100644 index 00000000000..f026c080b2b --- /dev/null +++ b/core/events/events_block_move.js @@ -0,0 +1,188 @@ +/** + * @license + * Copyright 2018 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @fileoverview Class for a block move event. + * @author fenichel@google.com (Rachel Fenichel) + */ +'use strict'; + +goog.module('Blockly.Events.BlockMove'); +goog.module.declareLegacyNamespace(); + +/* eslint-disable-next-line no-unused-vars */ +const Block = goog.requireType('Blockly.Block'); +const BlockBase = goog.require('Blockly.Events.BlockBase'); +const Coordinate = goog.require('Blockly.utils.Coordinate'); +const Events = goog.require('Blockly.Events'); +const connectionTypes = goog.require('Blockly.connectionTypes'); +const object = goog.require('Blockly.utils.object'); +const registry = goog.require('Blockly.registry'); + + +/** + * Class for a block move event. Created before the move. + * @param {!Block=} opt_block The moved block. Undefined for a blank + * event. + * @extends {BlockBase} + * @constructor + */ +const BlockMove = function(opt_block) { + BlockMove.superClass_.constructor.call(this, opt_block); + if (!opt_block) { + return; // Blank event to be populated by fromJson. + } + if (opt_block.isShadow()) { + // Moving shadow blocks is handled via disconnection. + this.recordUndo = false; + } + + const location = this.currentLocation_(); + this.oldParentId = location.parentId; + this.oldInputName = location.inputName; + this.oldCoordinate = location.coordinate; +}; +object.inherits(BlockMove, BlockBase); + +/** + * Type of this event. + * @type {string} + */ +BlockMove.prototype.type = Events.BLOCK_MOVE; + +/** + * Encode the event as JSON. + * @return {!Object} JSON representation. + */ +BlockMove.prototype.toJson = function() { + const json = BlockMove.superClass_.toJson.call(this); + if (this.newParentId) { + json['newParentId'] = this.newParentId; + } + if (this.newInputName) { + json['newInputName'] = this.newInputName; + } + if (this.newCoordinate) { + json['newCoordinate'] = Math.round(this.newCoordinate.x) + ',' + + Math.round(this.newCoordinate.y); + } + if (!this.recordUndo) { + json['recordUndo'] = this.recordUndo; + } + return json; +}; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +BlockMove.prototype.fromJson = function(json) { + BlockMove.superClass_.fromJson.call(this, json); + this.newParentId = json['newParentId']; + this.newInputName = json['newInputName']; + if (json['newCoordinate']) { + const xy = json['newCoordinate'].split(','); + this.newCoordinate = new Coordinate(Number(xy[0]), Number(xy[1])); + } + if (json['recordUndo'] !== undefined) { + this.recordUndo = json['recordUndo']; + } +}; + +/** + * Record the block's new location. Called after the move. + */ +BlockMove.prototype.recordNew = function() { + const location = this.currentLocation_(); + this.newParentId = location.parentId; + this.newInputName = location.inputName; + this.newCoordinate = location.coordinate; +}; + +/** + * Returns the parentId and input if the block is connected, + * or the XY location if disconnected. + * @return {!Object} Collection of location info. + * @private + */ +BlockMove.prototype.currentLocation_ = function() { + const workspace = this.getEventWorkspace_(); + const block = workspace.getBlockById(this.blockId); + const location = {}; + const parent = block.getParent(); + if (parent) { + location.parentId = parent.id; + const input = parent.getInputWithBlock(block); + if (input) { + location.inputName = input.name; + } + } else { + location.coordinate = block.getRelativeToSurfaceXY(); + } + return location; +}; + +/** + * Does this event record any change of state? + * @return {boolean} False if something changed. + */ +BlockMove.prototype.isNull = function() { + return this.oldParentId == this.newParentId && + this.oldInputName == this.newInputName && + Coordinate.equals(this.oldCoordinate, this.newCoordinate); +}; + +/** + * Run a move event. + * @param {boolean} forward True if run forward, false if run backward (undo). + */ +BlockMove.prototype.run = function(forward) { + const workspace = this.getEventWorkspace_(); + const block = workspace.getBlockById(this.blockId); + if (!block) { + console.warn('Can\'t move non-existent block: ' + this.blockId); + return; + } + const parentId = forward ? this.newParentId : this.oldParentId; + const inputName = forward ? this.newInputName : this.oldInputName; + const coordinate = forward ? this.newCoordinate : this.oldCoordinate; + let parentBlock; + if (parentId) { + parentBlock = workspace.getBlockById(parentId); + if (!parentBlock) { + console.warn('Can\'t connect to non-existent block: ' + parentId); + return; + } + } + if (block.getParent()) { + block.unplug(); + } + if (coordinate) { + const xy = block.getRelativeToSurfaceXY(); + block.moveBy(coordinate.x - xy.x, coordinate.y - xy.y); + } else { + const blockConnection = block.outputConnection || block.previousConnection; + let parentConnection; + const connectionType = blockConnection.type; + if (inputName) { + const input = parentBlock.getInput(inputName); + if (input) { + parentConnection = input.connection; + } + } else if (connectionType == connectionTypes.PREVIOUS_STATEMENT) { + parentConnection = parentBlock.nextConnection; + } + if (parentConnection) { + blockConnection.connect(parentConnection); + } else { + console.warn('Can\'t connect to non-existent input: ' + inputName); + } + } +}; + +registry.register(registry.Type.EVENT, Events.MOVE, BlockMove); + +exports = BlockMove; diff --git a/tests/deps.js b/tests/deps.js index 9a432a8ee98..d81b13de24f 100644 --- a/tests/deps.js +++ b/tests/deps.js @@ -34,10 +34,14 @@ goog.addDependency('../../core/css.js', ['Blockly.Css'], [], {'lang': 'es6', 'mo goog.addDependency('../../core/delete_area.js', ['Blockly.DeleteArea'], ['Blockly.BlockSvg', 'Blockly.DragTarget', 'Blockly.IDeleteArea', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/drag_target.js', ['Blockly.DragTarget'], ['Blockly.IDragTarget'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/dropdowndiv.js', ['Blockly.DropDownDiv'], ['Blockly.common', 'Blockly.utils.Rect', 'Blockly.utils.dom', 'Blockly.utils.math', 'Blockly.utils.style']); -goog.addDependency('../../core/events/block_events.js', ['Blockly.Events.BlockBase', 'Blockly.Events.BlockChange', 'Blockly.Events.BlockCreate', 'Blockly.Events.BlockDelete', 'Blockly.Events.BlockMove', 'Blockly.Events.Change', 'Blockly.Events.Create', 'Blockly.Events.Delete', 'Blockly.Events.Move'], ['Blockly.Events', 'Blockly.Events.Abstract', 'Blockly.Xml', 'Blockly.connectionTypes', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object', 'Blockly.utils.xml']); goog.addDependency('../../core/events/events.js', ['Blockly.Events'], ['Blockly.registry', 'Blockly.utils']); goog.addDependency('../../core/events/events_abstract.js', ['Blockly.Events.Abstract'], ['Blockly.Events'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/events/events_block_base.js', ['Blockly.Events.BlockBase'], ['Blockly.Events.Abstract', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/events/events_block_change.js', ['Blockly.Events.BlockChange'], ['Blockly.Events', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/events/events_block_create.js', ['Blockly.Events.BlockCreate'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'}); +goog.addDependency('../../core/events/events_block_delete.js', ['Blockly.Events.BlockDelete'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.Xml', 'Blockly.registry', 'Blockly.utils.object', 'Blockly.utils.xml'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/events/events_block_drag.js', ['Blockly.Events.BlockDrag'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object']); +goog.addDependency('../../core/events/events_block_move.js', ['Blockly.Events.BlockMove'], ['Blockly.Events', 'Blockly.Events.BlockBase', 'Blockly.connectionTypes', 'Blockly.registry', 'Blockly.utils.Coordinate', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/events/events_bubble_open.js', ['Blockly.Events.BubbleOpen'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/events/events_click.js', ['Blockly.Events.Click'], ['Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); goog.addDependency('../../core/events/events_marker_move.js', ['Blockly.Events.MarkerMove'], ['Blockly.ASTNode', 'Blockly.Events', 'Blockly.Events.UiBase', 'Blockly.registry', 'Blockly.utils.object'], {'lang': 'es6', 'module': 'goog'}); diff --git a/tests/mocha/event_test.js b/tests/mocha/event_test.js index 81ab69519d4..febcaf1c389 100644 --- a/tests/mocha/event_test.js +++ b/tests/mocha/event_test.js @@ -109,32 +109,10 @@ suite('Events', function() { }); }); - test('Create', function() { - var event = new Blockly.Events.Create(this.block); - sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.CREATE, - this.workspace.id, this.TEST_BLOCK_ID, - { - 'recordUndo': true, - 'group': '', - }); - }); - test('Block create', function() { var event = new Blockly.Events.BlockCreate(this.block); sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.CREATE, - this.workspace.id, this.TEST_BLOCK_ID, - { - 'recordUndo': true, - 'group': '', - }); - }); - - test('Delete', function() { - var event = new Blockly.Events.Delete(this.block); - sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.DELETE, + assertEventEquals(event, Blockly.Events.BLOCK_CREATE, this.workspace.id, this.TEST_BLOCK_ID, { 'recordUndo': true, @@ -145,7 +123,7 @@ suite('Events', function() { test('Block delete', function() { var event = new Blockly.Events.BlockDelete(this.block); sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.DELETE, + assertEventEquals(event, Blockly.Events.BLOCK_DELETE, this.workspace.id, this.TEST_BLOCK_ID, { 'recordUndo': true, @@ -181,30 +159,14 @@ suite('Events', function() { }, true); }); - suite('Move', function() { - test('Move by coordinate', function() { - var coordinate = new Blockly.utils.Coordinate(3, 4); - this.block.xy_ = coordinate; - - var event = new Blockly.Events.Move(this.block); - sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id, - this.TEST_BLOCK_ID, { - 'oldParentId': undefined, - 'oldInputName': undefined, - 'oldCoordinate': coordinate, - 'recordUndo': true, - 'group': '' - }); - }); - - test('Block move by coordinate', function() { + suite('Block Move', function() { + test('by coordinate', function() { var coordinate = new Blockly.utils.Coordinate(3, 4); this.block.xy_ = coordinate; var event = new Blockly.Events.BlockMove(this.block); sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id, + assertEventEquals(event, Blockly.Events.BLOCK_MOVE, this.workspace.id, this.TEST_BLOCK_ID, { 'oldParentId': undefined, 'oldInputName': undefined, @@ -214,44 +176,25 @@ suite('Events', function() { }); }); - suite('Move by parent', function() { - setup(function() { + test('by parent', function() { + try { this.parentBlock = createSimpleTestBlock(this.workspace); - this.block.parentBlock_ = this.parentBlock; this.block.xy_ = new Blockly.utils.Coordinate(3, 4); - }); - teardown(function() { - // This needs to be cleared, otherwise workspace.dispose will fail. - this.block.parentBlock_ = null; - }); - - test('Move by parent', function() { - var event = new Blockly.Events.Move(this.block); - sinon.assert.calledTwice(this.genUidStub); - assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id, - this.TEST_BLOCK_ID, { - 'oldParentId': this.TEST_PARENT_ID, - 'oldInputName': undefined, - 'oldCoordinate': undefined, - 'recordUndo': true, - 'group': '' - }); - }); - - test('Block move by parent', function() { var event = new Blockly.Events.BlockMove(this.block); sinon.assert.calledTwice(this.genUidStub); - assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id, - this.TEST_BLOCK_ID, - { + assertEventEquals(event, Blockly.Events.BLOCK_MOVE, this.workspace.id, + this.TEST_BLOCK_ID, { 'oldParentId': this.TEST_PARENT_ID, 'oldInputName': undefined, 'oldCoordinate': undefined, 'recordUndo': true, 'group': '' }); - }); + } finally { + // This needs to be cleared, otherwise workspace.dispose will fail. + this.block.parentBlock_ = null; + } }); }); }); @@ -279,28 +222,11 @@ suite('Events', function() { }); }); - test('Change', function() { - var event = new Blockly.Events.Change( - this.block, 'field', 'FIELD_NAME', 'old', 'new'); - sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.CHANGE, - this.workspace.id, this.TEST_BLOCK_ID, - { - 'varId': undefined, - 'element': 'field', - 'name': 'FIELD_NAME', - 'oldValue': 'old', - 'newValue': 'new', - 'recordUndo': true, - 'group': '', - }); - }); - test('Block change', function() { var event = new Blockly.Events.BlockChange( this.block, 'field', 'FIELD_NAME', 'old', 'new'); sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.CHANGE, + assertEventEquals(event, Blockly.Events.BLOCK_CHANGE, this.workspace.id, this.TEST_BLOCK_ID, { 'varId': undefined, @@ -313,32 +239,10 @@ suite('Events', function() { }); }); - test('Create', function() { - var event = new Blockly.Events.Create(this.block); - sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.CREATE, - this.workspace.id, this.TEST_BLOCK_ID, - { - 'recordUndo': false, - 'group': '', - }); - }); - test('Block create', function() { var event = new Blockly.Events.BlockCreate(this.block); sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.CREATE, - this.workspace.id, this.TEST_BLOCK_ID, - { - 'recordUndo': false, - 'group': '', - }); - }); - - test('Delete', function() { - var event = new Blockly.Events.Delete(this.block); - sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.DELETE, + assertEventEquals(event, Blockly.Events.BLOCK_CREATE, this.workspace.id, this.TEST_BLOCK_ID, { 'recordUndo': false, @@ -349,7 +253,7 @@ suite('Events', function() { test('Block delete', function() { var event = new Blockly.Events.BlockDelete(this.block); sinon.assert.calledOnce(this.genUidStub); - assertEventEquals(event, Blockly.Events.DELETE, + assertEventEquals(event, Blockly.Events.BLOCK_DELETE, this.workspace.id, this.TEST_BLOCK_ID, { 'recordUndo': false, @@ -357,35 +261,14 @@ suite('Events', function() { }); }); - suite('Move', function() { - setup(function() { + test('Block move', function() { + try { this.parentBlock = createSimpleTestBlock(this.workspace); this.block.parentBlock_ = this.parentBlock; this.block.xy_ = new Blockly.utils.Coordinate(3, 4); - }); - - teardown(function() { - // This needs to be cleared, otherwise workspace.dispose will fail. - this.block.parentBlock_ = null; - }); - - test('Move', function() { - var event = new Blockly.Events.Move(this.block); - sinon.assert.calledTwice(this.genUidStub); - assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id, - this.TEST_BLOCK_ID, { - 'oldParentId': this.TEST_PARENT_ID, - 'oldInputName': undefined, - 'oldCoordinate': undefined, - 'recordUndo': false, - 'group': '' - }); - }); - - test('Block move', function() { var event = new Blockly.Events.BlockMove(this.block); sinon.assert.calledTwice(this.genUidStub); - assertEventEquals(event, Blockly.Events.MOVE, this.workspace.id, + assertEventEquals(event, Blockly.Events.BLOCK_MOVE, this.workspace.id, this.TEST_BLOCK_ID, { 'oldParentId': this.TEST_PARENT_ID, @@ -394,7 +277,10 @@ suite('Events', function() { 'recordUndo': false, 'group': '' }); - }); + } finally { + // This needs to be cleared, otherwise workspace.dispose will fail. + this.block.parentBlock_ = null; + } }); }); @@ -408,25 +294,10 @@ suite('Events', function() { this.workspace, 'field_variable_test_block'); }); - test('Change', function() { - var event = new Blockly.Events.Change( - this.block, 'field', 'VAR', 'id1', 'id2'); - assertEventEquals(event, Blockly.Events.CHANGE, this.workspace.id, - this.TEST_BLOCK_ID, - { - 'element': 'field', - 'name': 'VAR', - 'oldValue': 'id1', - 'newValue': 'id2', - 'recordUndo': true, - 'group': '' - }); - }); - test('Block change', function() { var event = new Blockly.Events.BlockChange( this.block, 'field', 'VAR', 'id1', 'id2'); - assertEventEquals(event, Blockly.Events.CHANGE, this.workspace.id, + assertEventEquals(event, Blockly.Events.BLOCK_CHANGE, this.workspace.id, this.TEST_BLOCK_ID, { 'element': 'field', @@ -889,7 +760,7 @@ suite('Events', function() { chai.assert.equal(filteredEvents[1].newCoordinate.y, 1); }); - test('Merge move events', function() { + test('Merge block move events', function() { var block = this.workspace.newBlock('field_variable_test_block', '1'); var events = []; addMoveEvent(events, block, 0, 0); @@ -900,11 +771,11 @@ suite('Events', function() { chai.assert.equal(filteredEvents[0].newCoordinate.y, 1); }); - test('Merge change events', function() { + test('Merge block change events', function() { var block1 = this.workspace.newBlock('field_variable_test_block', '1'); var events = [ - new Blockly.Events.Change(block1, 'field', 'VAR', 'item', 'item1'), - new Blockly.Events.Change(block1, 'field', 'VAR', 'item1', 'item2') + new Blockly.Events.BlockChange(block1, 'field', 'VAR', 'item', 'item1'), + new Blockly.Events.BlockChange(block1, 'field', 'VAR', 'item1', 'item2') ]; var filteredEvents = Blockly.Events.filter(events, true); chai.assert.equal(filteredEvents.length, 1); // second change event merged into first @@ -1042,11 +913,11 @@ suite('Events', function() { sinon.assert.calledTwice(genUidStub); assertNthCallEventArgEquals( - this.eventsFireSpy, 0, Blockly.Events.Delete, + this.eventsFireSpy, 0, Blockly.Events.BlockDelete, {oldXml: expectedOldXml, group: ''}, workspaceSvg.id, expectedId); assertNthCallEventArgEquals( - changeListenerSpy, 0, Blockly.Events.Delete, + changeListenerSpy, 0, Blockly.Events.BlockDelete, {oldXml: expectedOldXml, group: ''}, workspaceSvg.id, expectedId); @@ -1086,7 +957,7 @@ suite('Events', function() { {group: TEST_GROUP_ID, varId: TEST_VAR_ID, varName: TEST_VAR_NAME}, this.workspace.id, undefined); assertNthCallEventArgEquals( - this.changeListenerSpy, 1, Blockly.Events.Create, + this.changeListenerSpy, 1, Blockly.Events.BlockCreate, {group: TEST_GROUP_ID}, this.workspace.id, TEST_BLOCK_ID); // Expect the workspace to have a variable with ID 'test_var_id'. @@ -1131,7 +1002,7 @@ suite('Events', function() { {group: TEST_GROUP_ID, varId: TEST_VAR_ID, varName: TEST_VAR_NAME}, this.workspace.id, undefined); assertNthCallEventArgEquals( - this.changeListenerSpy, 1, Blockly.Events.Create, + this.changeListenerSpy, 1, Blockly.Events.BlockCreate, {group: TEST_GROUP_ID}, this.workspace.id, TEST_BLOCK_ID); // Finished loading event should not be part of event group. diff --git a/tests/mocha/trashcan_test.js b/tests/mocha/trashcan_test.js index 9e0122d71ee..3a8bed2455b 100644 --- a/tests/mocha/trashcan_test.js +++ b/tests/mocha/trashcan_test.js @@ -10,7 +10,7 @@ suite("Trashcan", function() { '' + xmlString + ''); xml = xml.children[0]; - var event = new Blockly.Events.Delete(); + var event = new Blockly.Events.BlockDelete(); event.oldXml = xml; event.workspaceId = workspace.id; Blockly.Events.fire(event);