feat: refactor event serialization to use static fromJson method (#6614)

* feat: add new path for deserialization of events

* chore: add tests for round-tripping events

* chore: add static fromJson methods to all events

* chore: add inline docs to new static methods

* chore: add deprecation warnings

* chore: cleanup

* chore: add deprecation and docs to abstract

* chore: format

* chore: cleanup from rebase

* chore: update docs comment
This commit is contained in:
Beka Westberg
2022-11-14 11:07:36 -08:00
committed by GitHub
parent 6122ab22c4
commit f64c934f04
48 changed files with 1382 additions and 29 deletions

View File

@@ -13,6 +13,7 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.Abstract');
import * as deprecation from '../utils/deprecation.js';
import * as common from '../common.js';
import type {Workspace} from '../workspace.js';
@@ -25,7 +26,10 @@ import * as eventUtils from './utils.js';
* @alias Blockly.Events.Abstract
*/
export abstract class Abstract {
/** Whether or not the event is blank (to be populated by fromJson). */
/**
* Whether or not the event was constructed without necessary parameters
* (to be populated by fromJson).
*/
abstract isBlank: boolean;
/** The workspace identifier for this event. */
@@ -74,6 +78,26 @@ export abstract class Abstract {
this.group = json['group'] || '';
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of Abstract (like all events), but we can't specify that due to the
* fact that parameters to static methods in subclasses must be
* supertypes of parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: AbstractEventJson, workspace: Workspace, event: any):
Abstract {
deprecation.warn(
'Blockly.Events.Abstract.prototype.fromJson', 'version 9', 'version 10',
'Blockly.Events.fromJson');
event.isBlank = false;
event.group = json['group'] || '';
event.workspaceId = workspace.id;
return event;
}
/**
* Does this event record any change of state?
*
@@ -88,8 +112,10 @@ export abstract class Abstract {
*
* @param _forward True if run forward, false if run backward (undo).
*/
run(_forward: boolean) {}
// Defined by subclasses.
run(_forward: boolean) {
// Defined by subclasses.
}
/**
* Get workspace the event belongs to.

View File

@@ -13,6 +13,8 @@ import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.BlockBase');
import type {Block} from '../block.js';
import * as deprecation from '../utils/deprecation.js';
import type {Workspace} from '../workspace.js';
import {Abstract as AbstractEvent, AbstractEventJson} from './events_abstract.js';
@@ -32,7 +34,7 @@ export class BlockBase extends AbstractEvent {
*/
constructor(opt_block?: Block) {
super();
this.isBlank = !!opt_block;
this.isBlank = !opt_block;
if (!opt_block) return;
@@ -48,7 +50,7 @@ export class BlockBase extends AbstractEvent {
*
* @returns JSON representation.
*/
override toJson(): AbstractEventJson {
override toJson(): BlockBaseJson {
const json = super.toJson() as BlockBaseJson;
if (!this.blockId) {
throw new Error(
@@ -65,9 +67,29 @@ export class BlockBase extends AbstractEvent {
* @param json JSON representation.
*/
override fromJson(json: BlockBaseJson) {
deprecation.warn(
'Blockly.Events.BlockBase.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.blockId = json['blockId'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of BlockBase, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: BlockBaseJson, workspace: Workspace, event?: any):
BlockBase {
const newEvent =
super.fromJson(json, workspace, event ?? new BlockBase()) as BlockBase;
newEvent.blockId = json['blockId'];
return newEvent;
}
}
export interface BlockBaseJson extends AbstractEventJson {

View File

@@ -14,7 +14,9 @@ goog.declareModuleId('Blockly.Events.BlockChange');
import type {Block} from '../block.js';
import type {BlockSvg} from '../block_svg.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {Workspace} from '../workspace.js';
import * as Xml from '../xml.js';
import {BlockBase, BlockBaseJson} from './events_block_base.js';
@@ -79,6 +81,9 @@ export class BlockChange extends BlockBase {
* @param json JSON representation.
*/
override fromJson(json: BlockChangeJson) {
deprecation.warn(
'Blockly.Events.BlockChange.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.element = json['element'];
this.name = json['name'];
@@ -86,6 +91,27 @@ export class BlockChange extends BlockBase {
this.newValue = json['newValue'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of BlockChange, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: BlockChangeJson, workspace: Workspace, event?: any):
BlockChange {
const newEvent =
super.fromJson(json, workspace, event ?? new BlockChange()) as
BlockChange;
newEvent.element = json['element'];
newEvent.name = json['name'];
newEvent.oldValue = json['oldValue'];
newEvent.newValue = json['newValue'];
return newEvent;
}
/**
* Does this event record any change of state?
*

View File

@@ -13,12 +13,14 @@ import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.BlockCreate');
import type {Block} from '../block.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import * as blocks from '../serialization/blocks.js';
import * as Xml from '../xml.js';
import {BlockBase, BlockBaseJson} from './events_block_base.js';
import * as eventUtils from './utils.js';
import {Workspace} from '../workspace.js';
/**
@@ -89,6 +91,9 @@ export class BlockCreate extends BlockBase {
* @param json JSON representation.
*/
override fromJson(json: BlockCreateJson) {
deprecation.warn(
'Blockly.Events.BlockCreate.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.xml = Xml.textToDom(json['xml']);
this.ids = json['ids'];
@@ -98,6 +103,29 @@ export class BlockCreate extends BlockBase {
}
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of BlockCreate, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: BlockCreateJson, workspace: Workspace, event?: any):
BlockCreate {
const newEvent =
super.fromJson(json, workspace, event ?? new BlockCreate()) as
BlockCreate;
newEvent.xml = Xml.textToDom(json['xml']);
newEvent.ids = json['ids'];
newEvent.json = json['json'] as blocks.State;
if (json['recordUndo'] !== undefined) {
newEvent.recordUndo = json['recordUndo'];
}
return newEvent;
}
/**
* Run a creation event.
*

View File

@@ -13,12 +13,14 @@ import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.BlockDelete');
import type {Block} from '../block.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import * as blocks from '../serialization/blocks.js';
import * as Xml from '../xml.js';
import {BlockBase, BlockBaseJson} from './events_block_base.js';
import * as eventUtils from './utils.js';
import {Workspace} from '../workspace.js';
/**
@@ -103,6 +105,9 @@ export class BlockDelete extends BlockBase {
* @param json JSON representation.
*/
override fromJson(json: BlockDeleteJson) {
deprecation.warn(
'Blockly.Events.BlockDelete.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.oldXml = Xml.textToDom(json['oldXml']);
this.ids = json['ids'];
@@ -114,6 +119,31 @@ export class BlockDelete extends BlockBase {
}
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of BlockDelete, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: BlockDeleteJson, workspace: Workspace, event?: any):
BlockDelete {
const newEvent =
super.fromJson(json, workspace, event ?? new BlockDelete()) as
BlockDelete;
newEvent.oldXml = Xml.textToDom(json['oldXml']);
newEvent.ids = json['ids'];
newEvent.wasShadow =
json['wasShadow'] || newEvent.oldXml.tagName.toLowerCase() === 'shadow';
newEvent.oldJson = json['oldJson'];
if (json['recordUndo'] !== undefined) {
newEvent.recordUndo = json['recordUndo'];
}
return newEvent;
}
/**
* Run a deletion event.
*

View File

@@ -13,10 +13,12 @@ import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.BlockDrag');
import type {Block} from '../block.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {AbstractEventJson} from './events_abstract.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import {Workspace} from '../workspace.js';
/**
@@ -83,11 +85,33 @@ export class BlockDrag extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: BlockDragJson) {
deprecation.warn(
'Blockly.Events.BlockDrag.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.isStart = json['isStart'];
this.blockId = json['blockId'];
this.blocks = json['blocks'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of BlockDrag, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses..
* @internal
*/
static fromJson(json: BlockDragJson, workspace: Workspace, event?: any):
BlockDrag {
const newEvent =
super.fromJson(json, workspace, event ?? new BlockDrag()) as BlockDrag;
newEvent.isStart = json['isStart'];
newEvent.blockId = json['blockId'];
newEvent.blocks = json['blocks'];
return newEvent;
}
}
export interface BlockDragJson extends AbstractEventJson {

View File

@@ -14,11 +14,13 @@ goog.declareModuleId('Blockly.Events.BlockMove');
import type {Block} from '../block.js';
import {ConnectionType} from '../connection_type.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {Coordinate} from '../utils/coordinate.js';
import {BlockBase, BlockBaseJson} from './events_block_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
interface BlockLocation {
@@ -68,6 +70,12 @@ export class BlockMove extends BlockBase {
*/
override toJson(): BlockMoveJson {
const json = super.toJson() as BlockMoveJson;
json['oldParentId'] = this.oldParentId;
json['oldInputName'] = this.oldInputName;
if (this.oldCoordinate) {
json['oldCoordinate'] = `${Math.round(this.oldCoordinate.x)}, ` +
`${Math.round(this.oldCoordinate.y)}`;
}
json['newParentId'] = this.newParentId;
json['newInputName'] = this.newInputName;
if (this.newCoordinate) {
@@ -86,7 +94,16 @@ export class BlockMove extends BlockBase {
* @param json JSON representation.
*/
override fromJson(json: BlockMoveJson) {
deprecation.warn(
'Blockly.Events.BlockMove.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.oldParentId = json['oldParentId'];
this.oldInputName = json['oldInputName'];
if (json['oldCoordinate']) {
const xy = json['oldCoordinate'].split(',');
this.oldCoordinate = new Coordinate(Number(xy[0]), Number(xy[1]));
}
this.newParentId = json['newParentId'];
this.newInputName = json['newInputName'];
if (json['newCoordinate']) {
@@ -98,6 +115,37 @@ export class BlockMove extends BlockBase {
}
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of BlockMove, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: BlockMoveJson, workspace: Workspace, event?: any):
BlockMove {
const newEvent =
super.fromJson(json, workspace, event ?? new BlockMove()) as BlockMove;
newEvent.oldParentId = json['oldParentId'];
newEvent.oldInputName = json['oldInputName'];
if (json['oldCoordinate']) {
const xy = json['oldCoordinate'].split(',');
newEvent.oldCoordinate = new Coordinate(Number(xy[0]), Number(xy[1]));
}
newEvent.newParentId = json['newParentId'];
newEvent.newInputName = json['newInputName'];
if (json['newCoordinate']) {
const xy = json['newCoordinate'].split(',');
newEvent.newCoordinate = new Coordinate(Number(xy[0]), Number(xy[1]));
}
if (json['recordUndo'] !== undefined) {
newEvent.recordUndo = json['recordUndo'];
}
return newEvent;
}
/** Record the block's new location. Called after the move. */
recordNew() {
const location = this.currentLocation_();
@@ -210,6 +258,9 @@ export class BlockMove extends BlockBase {
}
export interface BlockMoveJson extends BlockBaseJson {
oldParentId?: string;
oldInputName?: string;
oldCoordinate?: string;
newParentId?: string;
newInputName?: string;
newCoordinate?: string;

View File

@@ -14,9 +14,11 @@ goog.declareModuleId('Blockly.Events.BubbleOpen');
import type {AbstractEventJson} from './events_abstract.js';
import type {BlockSvg} from '../block_svg.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -81,11 +83,34 @@ export class BubbleOpen extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: BubbleOpenJson) {
deprecation.warn(
'Blockly.Events.BubbleOpen.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.isOpen = json['isOpen'];
this.bubbleType = json['bubbleType'];
this.blockId = json['blockId'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of BubbleOpen, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: BubbleOpenJson, workspace: Workspace, event?: any):
BubbleOpen {
const newEvent =
super.fromJson(json, workspace, event ?? new BubbleOpen()) as
BubbleOpen;
newEvent.isOpen = json['isOpen'];
newEvent.bubbleType = json['bubbleType'];
newEvent.blockId = json['blockId'];
return newEvent;
}
}
export enum BubbleType {

View File

@@ -13,11 +13,13 @@ import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.Click');
import type {Block} from '../block.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {AbstractEventJson} from './events_abstract.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import {Workspace} from '../workspace.js';
/**
@@ -77,10 +79,30 @@ export class Click extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: ClickJson) {
deprecation.warn(
'Blockly.Events.Click.prototype.fromJson', 'version 9', 'version 10',
'Blockly.Events.fromJson');
super.fromJson(json);
this.targetType = json['targetType'];
this.blockId = json['blockId'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of Click, but we can't specify that due to the fact that parameters to
* static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: ClickJson, workspace: Workspace, event?: any): Click {
const newEvent =
super.fromJson(json, workspace, event ?? new Click()) as Click;
newEvent.targetType = json['targetType'];
newEvent.blockId = json['blockId'];
return newEvent;
}
}
export enum ClickTarget {

View File

@@ -12,6 +12,7 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.CommentBase');
import * as deprecation from '../utils/deprecation.js';
import * as utilsXml from '../utils/xml.js';
import type {WorkspaceComment} from '../workspace_comment.js';
import * as Xml from '../xml.js';
@@ -20,6 +21,7 @@ import {Abstract as AbstractEvent, AbstractEventJson} from './events_abstract.js
import type {CommentCreate} from './events_comment_create.js';
import type {CommentDelete} from './events_comment_delete.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -81,10 +83,31 @@ export class CommentBase extends AbstractEvent {
* @param json JSON representation.
*/
override fromJson(json: CommentBaseJson) {
deprecation.warn(
'Blockly.Events.CommentBase.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.commentId = json['commentId'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of CommentBase, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: CommentBaseJson, workspace: Workspace, event?: any):
CommentBase {
const newEvent =
super.fromJson(json, workspace, event ?? new CommentBase()) as
CommentBase;
newEvent.commentId = json['commentId'];
return newEvent;
}
/**
* Helper function for Comment[Create|Delete]
*

View File

@@ -12,11 +12,13 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.CommentChange');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import type {WorkspaceComment} from '../workspace_comment.js';
import {CommentBase, CommentBaseJson} from './events_comment_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -78,11 +80,33 @@ export class CommentChange extends CommentBase {
* @param json JSON representation.
*/
override fromJson(json: CommentChangeJson) {
deprecation.warn(
'Blockly.Events.CommentChange.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.oldContents_ = json['oldContents'];
this.newContents_ = json['newContents'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of CommentChange, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: CommentChangeJson, workspace: Workspace, event?: any):
CommentChange {
const newEvent =
super.fromJson(json, workspace, event ?? new CommentChange()) as
CommentChange;
newEvent.oldContents_ = json['oldContents'];
newEvent.newContents_ = json['newContents'];
return newEvent;
}
/**
* Does this event record any change of state?
*

View File

@@ -12,12 +12,14 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.CommentCreate');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import type {WorkspaceComment} from '../workspace_comment.js';
import * as Xml from '../xml.js';
import {CommentBase, CommentBaseJson} from './events_comment_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -67,10 +69,31 @@ export class CommentCreate extends CommentBase {
* @param json JSON representation.
*/
override fromJson(json: CommentCreateJson) {
deprecation.warn(
'Blockly.Events.CommentCreate.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.xml = Xml.textToDom(json['xml']);
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of CommentCreate, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: CommentCreateJson, workspace: Workspace, event?: any):
CommentCreate {
const newEvent =
super.fromJson(json, workspace, event ?? new CommentCreate()) as
CommentCreate;
newEvent.xml = Xml.textToDom(json['xml']);
return newEvent;
}
/**
* Run a creation event.
*

View File

@@ -15,8 +15,10 @@ goog.declareModuleId('Blockly.Events.CommentDelete');
import * as registry from '../registry.js';
import type {WorkspaceComment} from '../workspace_comment.js';
import {CommentBase} from './events_comment_base.js';
import {CommentBase, CommentBaseJson} from './events_comment_base.js';
import * as eventUtils from './utils.js';
import * as Xml from '../xml.js';
import type {Workspace} from '../workspace.js';
/**
@@ -50,6 +52,44 @@ export class CommentDelete extends CommentBase {
override run(forward: boolean) {
CommentBase.CommentCreateDeleteHelper(this, !forward);
}
/**
* Encode the event as JSON.
*
* @returns JSON representation.
*/
override toJson(): CommentDeleteJson {
const json = super.toJson() as CommentDeleteJson;
if (!this.xml) {
throw new Error(
'The comment XML is undefined. Either pass a comment to ' +
'the constructor, or call fromJson');
}
json['xml'] = Xml.domToText(this.xml);
return json;
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of CommentDelete, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: CommentDeleteJson, workspace: Workspace, event?: any):
CommentDelete {
const newEvent =
super.fromJson(json, workspace, event ?? new CommentDelete()) as
CommentDelete;
newEvent.xml = Xml.textToDom(json['xml']);
return newEvent;
}
}
export interface CommentDeleteJson extends CommentBaseJson {
xml: string;
}
registry.register(

View File

@@ -12,12 +12,14 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.CommentMove');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {Coordinate} from '../utils/coordinate.js';
import type {WorkspaceComment} from '../workspace_comment.js';
import {CommentBase, CommentBaseJson} from './events_comment_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -111,6 +113,9 @@ export class CommentMove extends CommentBase {
* @param json JSON representation.
*/
override fromJson(json: CommentMoveJson) {
deprecation.warn(
'Blockly.Events.CommentMove.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
let xy = json['oldCoordinate'].split(',');
this.oldCoordinate_ = new Coordinate(Number(xy[0]), Number(xy[1]));
@@ -118,6 +123,27 @@ export class CommentMove extends CommentBase {
this.newCoordinate_ = new Coordinate(Number(xy[0]), Number(xy[1]));
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of CommentMove, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: CommentMoveJson, workspace: Workspace, event?: any):
CommentMove {
const newEvent =
super.fromJson(json, workspace, event ?? new CommentMove()) as
CommentMove;
let xy = json['oldCoordinate'].split(',');
newEvent.oldCoordinate_ = new Coordinate(Number(xy[0]), Number(xy[1]));
xy = json['newCoordinate'].split(',');
newEvent.newCoordinate_ = new Coordinate(Number(xy[0]), Number(xy[1]));
return newEvent;
}
/**
* Does this event record any change of state?
*

View File

@@ -14,6 +14,7 @@ goog.declareModuleId('Blockly.Events.MarkerMove');
import type {Block} from '../block.js';
import {ASTNode} from '../keyboard_nav/ast_node.js';
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import type {Workspace} from '../workspace.js';
import {AbstractEventJson} from './events_abstract.js';
@@ -96,12 +97,36 @@ export class MarkerMove extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: MarkerMoveJson) {
deprecation.warn(
'Blockly.Events.MarkerMove.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.isCursor = json['isCursor'];
this.blockId = json['blockId'];
this.oldNode = json['oldNode'];
this.newNode = json['newNode'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of MarkerMove, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: MarkerMoveJson, workspace: Workspace, event?: any):
MarkerMove {
const newEvent =
super.fromJson(json, workspace, event ?? new MarkerMove()) as
MarkerMove;
newEvent.isCursor = json['isCursor'];
newEvent.blockId = json['blockId'];
newEvent.oldNode = json['oldNode'];
newEvent.newNode = json['newNode'];
return newEvent;
}
}
export interface MarkerMoveJson extends AbstractEventJson {

View File

@@ -12,11 +12,13 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.Selected');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {AbstractEventJson} from './events_abstract.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -67,10 +69,31 @@ export class Selected extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: SelectedJson) {
deprecation.warn(
'Blockly.Events.Selected.prototype.fromJson', 'version 9', 'version 10',
'Blockly.Events.fromJson');
super.fromJson(json);
this.oldElementId = json['oldElementId'];
this.newElementId = json['newElementId'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of Selected, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: SelectedJson, workspace: Workspace, event?: any):
Selected {
const newEvent =
super.fromJson(json, workspace, event ?? new Selected()) as Selected;
newEvent.oldElementId = json['oldElementId'];
newEvent.newElementId = json['newElementId'];
return newEvent;
}
}
export interface SelectedJson extends AbstractEventJson {

View File

@@ -12,10 +12,12 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.ThemeChange');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {AbstractEventJson} from './events_abstract.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -61,9 +63,30 @@ export class ThemeChange extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: ThemeChangeJson) {
deprecation.warn(
'Blockly.Events.ThemeChange.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.themeName = json['themeName'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of ThemeChange, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: ThemeChangeJson, workspace: Workspace, event?: any):
ThemeChange {
const newEvent =
super.fromJson(json, workspace, event ?? new ThemeChange()) as
ThemeChange;
newEvent.themeName = json['themeName'];
return newEvent;
}
}
export interface ThemeChangeJson extends AbstractEventJson {

View File

@@ -12,10 +12,12 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.ToolboxItemSelect');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {AbstractEventJson} from './events_abstract.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -66,10 +68,33 @@ export class ToolboxItemSelect extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: ToolboxItemSelectJson) {
deprecation.warn(
'Blockly.Events.ToolboxItemSelect.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.oldItem = json['oldItem'];
this.newItem = json['newItem'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of ToolboxItemSelect, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(
json: ToolboxItemSelectJson, workspace: Workspace,
event?: any): ToolboxItemSelect {
const newEvent =
super.fromJson(json, workspace, event ?? new ToolboxItemSelect()) as
ToolboxItemSelect;
newEvent.oldItem = json['oldItem'];
newEvent.newItem = json['newItem'];
return newEvent;
}
}
export interface ToolboxItemSelectJson extends AbstractEventJson {

View File

@@ -12,11 +12,13 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.TrashcanOpen');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {AbstractEventJson} from './events_abstract.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -63,9 +65,30 @@ export class TrashcanOpen extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: TrashcanOpenJson) {
deprecation.warn(
'Blockly.Events.TrashcanOpen.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.isOpen = json['isOpen'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of TrashcanOpen, but we can't specify that due to the fact that
* parameters to static methods in subclasses must be supertypes of
* parameters to static methods in superclasses.
* @internal
*/
static fromJson(json: TrashcanOpenJson, workspace: Workspace, event?: any):
TrashcanOpen {
const newEvent =
super.fromJson(json, workspace, event ?? new TrashcanOpen()) as
TrashcanOpen;
newEvent.isOpen = json['isOpen'];
return newEvent;
}
}
export interface TrashcanOpenJson extends AbstractEventJson {

View File

@@ -12,9 +12,11 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.VarBase');
import * as deprecation from '../utils/deprecation.js';
import type {VariableModel} from '../variable_model.js';
import {Abstract as AbstractEvent, AbstractEventJson} from './events_abstract.js';
import type {Workspace} from '../workspace.js';
/**
@@ -64,9 +66,29 @@ export class VarBase extends AbstractEvent {
* @param json JSON representation.
*/
override fromJson(json: VarBaseJson) {
deprecation.warn(
'Blockly.Events.VarBase.prototype.fromJson', 'version 9', 'version 10',
'Blockly.Events.fromJson');
super.fromJson(json);
this.varId = json['varId'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of VarBase, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: VarBaseJson, workspace: Workspace, event?: any):
VarBase {
const newEvent =
super.fromJson(json, workspace, event ?? new VarBase()) as VarBase;
newEvent.varId = json['varId'];
return newEvent;
}
}
export interface VarBaseJson extends AbstractEventJson {

View File

@@ -12,11 +12,13 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.VarCreate');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import type {VariableModel} from '../variable_model.js';
import {VarBase, VarBaseJson} from './events_var_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -70,11 +72,32 @@ export class VarCreate extends VarBase {
* @param json JSON representation.
*/
override fromJson(json: VarCreateJson) {
deprecation.warn(
'Blockly.Events.VarCreate.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.varType = json['varType'];
this.varName = json['varName'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of VarCreate, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: VarCreateJson, workspace: Workspace, event?: any):
VarCreate {
const newEvent =
super.fromJson(json, workspace, event ?? new VarCreate()) as VarCreate;
newEvent.varType = json['varType'];
newEvent.varName = json['varName'];
return newEvent;
}
/**
* Run a variable creation event.
*

View File

@@ -12,11 +12,13 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.VarDelete');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import type {VariableModel} from '../variable_model.js';
import {VarBase, VarBaseJson} from './events_var_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -70,11 +72,32 @@ export class VarDelete extends VarBase {
* @param json JSON representation.
*/
override fromJson(json: VarDeleteJson) {
deprecation.warn(
'Blockly.Events.VarDelete.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.varType = json['varType'];
this.varName = json['varName'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of VarDelete, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: VarDeleteJson, workspace: Workspace, event?: any):
VarDelete {
const newEvent =
super.fromJson(json, workspace, event ?? new VarDelete()) as VarDelete;
newEvent.varType = json['varType'];
newEvent.varName = json['varName'];
return newEvent;
}
/**
* Run a variable deletion event.
*

View File

@@ -12,11 +12,13 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.VarRename');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import type {VariableModel} from '../variable_model.js';
import {VarBase, VarBaseJson} from './events_var_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -71,11 +73,32 @@ export class VarRename extends VarBase {
* @param json JSON representation.
*/
override fromJson(json: VarRenameJson) {
deprecation.warn(
'Blockly.Events.VarRename.prototype.fromJson', 'version 9',
'version 10', 'Blockly.Events.fromJson');
super.fromJson(json);
this.oldName = json['oldName'];
this.newName = json['newName'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of VarRename, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: VarRenameJson, workspace: Workspace, event?: any):
VarRename {
const newEvent =
super.fromJson(json, workspace, event ?? new VarRename()) as VarRename;
newEvent.oldName = json['oldName'];
newEvent.newName = json['newName'];
return newEvent;
}
/**
* Run a variable rename event.
*

View File

@@ -12,10 +12,12 @@
import * as goog from '../../closure/goog/goog.js';
goog.declareModuleId('Blockly.Events.ViewportChange');
import * as deprecation from '../utils/deprecation.js';
import * as registry from '../registry.js';
import {AbstractEventJson} from './events_abstract.js';
import {UiBase} from './events_ui_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
@@ -105,12 +107,36 @@ export class ViewportChange extends UiBase {
* @param json JSON representation.
*/
override fromJson(json: ViewportChangeJson) {
deprecation.warn(
'Blockly.Events.Viewport.prototype.fromJson', 'version 9', 'version 10',
'Blockly.Events.fromJson');
super.fromJson(json);
this.viewTop = json['viewTop'];
this.viewLeft = json['viewLeft'];
this.scale = json['scale'];
this.oldScale = json['oldScale'];
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of Viewport, but we can't specify that due to the fact that parameters
* to static methods in subclasses must be supertypes of parameters to
* static methods in superclasses.
* @internal
*/
static fromJson(json: ViewportChangeJson, workspace: Workspace, event?: any):
ViewportChange {
const newEvent =
super.fromJson(json, workspace, event ?? new ViewportChange()) as
ViewportChange;
newEvent.viewTop = json['viewTop'];
newEvent.viewLeft = json['viewLeft'];
newEvent.scale = json['scale'];
newEvent.oldScale = json['oldScale'];
return newEvent;
}
}
export interface ViewportChangeJson extends AbstractEventJson {

View File

@@ -518,15 +518,33 @@ export function getDescendantIds(block: Block): string[] {
export function fromJson(
json: AnyDuringMigration, workspace: Workspace): Abstract {
const eventClass = get(json['type']);
if (!eventClass) {
throw Error('Unknown event type.');
if (!eventClass) throw Error('Unknown event type.');
if (eventClassHasStaticFromJson(eventClass)) {
return (eventClass as any).fromJson(json, workspace);
}
// Fallback to the old deserialization method.
const event = new eventClass();
event.fromJson(json);
event.workspaceId = workspace.id;
return event;
}
/**
* Returns true if the given event constructor has /its own/ static fromJson
* method.
*
* Returns false if no static fromJson method exists on the contructor, or if
* the static fromJson method is inheritted.
*/
function eventClassHasStaticFromJson(eventClass: new (...p: any[]) => Abstract):
boolean {
const untypedEventClass = eventClass as any;
return Object.getOwnPropertyDescriptors(untypedEventClass).fromJson &&
typeof untypedEventClass.fromJson === 'function';
}
/**
* Gets the class for a specific event type from the registry.
*

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.blockChangeEvent');
goog.declareModuleId('Blockly.test.eventBlockChange');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
import {defineMutatorBlocks} from './test_helpers/block_definitions.js';
@@ -71,4 +71,28 @@ suite('Block Change Event', function() {
});
});
});
suite('Serialization', function() {
setup(function() {
defineMutatorBlocks();
});
teardown(function() {
Blockly.Extensions.unregister('xml_mutator');
Blockly.Extensions.unregister('jso_mutator');
});
test('events round-trip through JSON', function() {
const block = this.workspace.newBlock('xml_block', 'block_id');
block.domToMutation(
Blockly.Xml.textToDom('<mutation hasInput="true"/>'));
const origEvent = new Blockly.Events.BlockChange(
block, 'mutation', null, '', '<mutation hasInput="true"/>');
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -4,16 +4,18 @@
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.blockCreateEvent');
goog.declareModuleId('Blockly.test.eventBlockCreate');
import {assertEventFired} from './test_helpers/events.js';
import * as eventUtils from '../../build/src/core/events/utils.js';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
import {defineRowBlock} from './test_helpers/block_definitions.js';
suite('Block Create Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineRowBlock();
this.workspace = new Blockly.Workspace();
});
@@ -25,28 +27,22 @@ suite('Block Create Event', function() {
Blockly.Events.disable();
const block = Blockly.serialization.blocks.append(
{
"type": "text_print",
"type": "row_block",
"inputs": {
"TEXT": {
"INPUT": {
"shadow": {
"type": "text",
"type": "row_block",
"id": "shadowId",
"fields": {
"TEXT": "abc",
},
},
"block": {
"type": "text",
"fields": {
"TEXT": "",
},
"type": "row_block",
},
},
},
},
this.workspace);
Blockly.Events.enable();
block.getInput('TEXT').connection.disconnect();
block.getInput('INPUT').connection.disconnect();
assertEventFired(
this.eventsFireStub,
Blockly.Events.BlockCreate,
@@ -57,4 +53,18 @@ suite('Block Create Event', function() {
const event = calls[calls.length - 1].args[0];
chai.assert.equal(event.xml.tagName, 'shadow');
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const block = this.workspace.newBlock('row_block', 'block_id');
const origEvent = new Blockly.Events.BlockCreate(block);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
delete origEvent.xml; // xml fails deep equals for some reason.
delete newEvent.xml; // xml fails deep equals for some reason.
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -4,14 +4,16 @@
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.blockDeleteEvent');
goog.declareModuleId('Blockly.test.eventBlockDelete');
import * as eventUtils from '../../build/src/core/events/utils.js';
import {defineRowBlock} from './test_helpers/block_definitions.js';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Block Delete Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineRowBlock();
this.workspace = new Blockly.Workspace();
});
@@ -36,4 +38,18 @@ suite('Block Delete Event', function() {
chai.assert.isTrue(spy.getCall(0).args[0] instanceof deleteClass);
});
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const block = this.workspace.newBlock('row_block', 'block_id');
const origEvent = new Blockly.Events.BlockDelete(block);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
delete origEvent.oldXml; // xml fails deep equals for some reason.
delete newEvent.oldXml; // xml fails deep equals for some reason.
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventBlockDrag');
import {defineRowBlock} from './test_helpers/block_definitions.js';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Block Drag Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineRowBlock();
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const block = this.workspace.newBlock('row_block', 'block_id');
const origEvent = new Blockly.Events.BlockDrag(block, true, []);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,38 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventBlockMove');
import {defineRowBlock} from './test_helpers/block_definitions.js';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Block Move Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineRowBlock();
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const block1 = this.workspace.newBlock('row_block', 'block_id');
const block2 = this.workspace.newBlock('row_block', 'block_id');
const origEvent = new Blockly.Events.BlockMove(block1);
block2.getInput('INPUT').connection.connect(block2.outputConnection);
origEvent.recordNew();
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,39 @@
/**
* @license
* Copyright 2021 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventBubbleOpen');
import {defineMutatorBlocks} from './test_helpers/block_definitions.js';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Bubble Open Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineMutatorBlocks();
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
Blockly.Extensions.unregister('xml_mutator');
Blockly.Extensions.unregister('jso_mutator');
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const block = this.workspace.newBlock('jso_block', 'block_id');
const origEvent =
new Blockly.Events.BubbleOpen(
block, true, Blockly.Events.BubbleType.MUTATOR);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,37 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventClick');
import {defineRowBlock} from './test_helpers/block_definitions.js';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Click Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineRowBlock();
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const block = this.workspace.newBlock('row_block', 'block_id');
const origEvent =
new Blockly.Events.Click(
block, undefined, Blockly.Events.ClickTarget.BLOCK);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventCommentChange');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Comment Change Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const comment =
new Blockly.WorkspaceComment(this.workspace, 'old text', 10, 10);
const origEvent =
new Blockly.Events.CommentChange(comment, 'old text', 'new text');
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,37 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventCommentCreate');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Comment Create Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const comment =
new Blockly.WorkspaceComment(this.workspace, 'test text', 10, 10);
const origEvent = new Blockly.Events.CommentCreate(comment);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
delete origEvent.xml; // xml fails deep equals for some reason.
delete newEvent.xml; // xml fails deep equals for some reason.
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,37 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventCommentDelete');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Comment Delete Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const comment =
new Blockly.WorkspaceComment(this.workspace, 'test text', 10, 10);
const origEvent = new Blockly.Events.CommentDelete(comment);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
delete origEvent.xml; // xml fails deep equals for some reason.
delete newEvent.xml; // xml fails deep equals for some reason.
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,39 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventCommentMove');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Comment Move Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const comment =
new Blockly.WorkspaceComment(this.workspace, 'test text', 10, 10);
const origEvent = new Blockly.Events.CommentMove(comment);
comment.moveBy(10, 10);
origEvent.recordNew();
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
delete origEvent.comment_; // Ignore private properties.
delete newEvent.comment_; // Ignore private properties.
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,39 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventMarkerMove');
import {defineRowBlock} from './test_helpers/block_definitions.js;';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Marker Move Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineRowBlock();
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite.only('Serialization', function() {
test('events round-trip through JSON', function() {
const block1 = this.workspace.newBlock('row_block', 'test_id1');
const block2 = this.workspace.newBlock('row_block', 'test_id2');
const node1 = new Blockly.ASTNode(Blockly.ASTNode.types.BLOCK, block1);
const node2 = new Blockly.ASTNode(Blockly.ASTNode.types.BLOCK, block2);
const origEvent = new Blockly.Events.MarkerMove(block2, false, node1, node2);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,38 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventSelected');
import {defineRowBlock} from './test_helpers/block_definitions.js;';
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Selected Event', function() {
setup(function() {
sharedTestSetup.call(this);
defineRowBlock();
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite.only('Serialization', function() {
test('events round-trip through JSON', function() {
const block1 = this.workspace.newBlock('row_block', 'test_id1');
const block2 = this.workspace.newBlock('row_block', 'test_id2');
const origEvent =
new Blockly.Events.Selected(block1.id, block2.id, this.workspace.id);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -547,6 +547,7 @@ suite('Events', function() {
type: 'move',
group: '',
blockId: thisObj.block.id,
oldCoordinate: "0, 0",
}),
},
{
@@ -557,6 +558,7 @@ suite('Events', function() {
type: 'move',
group: '',
blockId: thisObj.shadowBlock.id,
oldCoordinate: "0, 0",
recordUndo: false,
}),
},
@@ -581,7 +583,8 @@ suite('Events', function() {
{title: 'Comment delete', class: Blockly.Events.CommentDelete,
getArgs: (thisObj) => [thisObj.comment],
getExpectedJson: (thisObj) => ({type: 'comment_delete', group: '',
commentId: thisObj.comment.id})},
commentId: thisObj.comment.id,
xml: Blockly.Xml.domToText(thisObj.comment.toXmlWithXY())})},
// TODO(#4577) Test serialization of move event coordinate properties.
];
const testSuites = [
@@ -620,9 +623,8 @@ suite('Events', function() {
testSuite.testCases.forEach((testCase) => {
test(testCase.title, function() {
const event = new testCase.class(...testCase.getArgs(this));
const event2 = new testCase.class();
const json = event.toJson();
event2.fromJson(json);
const event2 = Blockly.Events.fromJson(json, this.workspace);
chai.assert.equal(
safeStringify(event2.toJson()), safeStringify(json));

View File

@@ -0,0 +1,34 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventThemeChange');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Theme Change Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const origEvent =
new Blockly.Events.ThemeChange('new theme name', this.workspace.id);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,62 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventToolboxItemSelect');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Toolbox Item Select Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = Blockly.inject('blocklyDiv', {
toolbox: {
"kind": "categoryToolbox",
"contents": [
{
"kind": "category",
"name": "Control",
"contents": [
{
"kind": "block",
"type": "controls_if",
},
],
},
{
"kind": "category",
"name": "Logic",
"contents": [
{
"kind": "block",
"type": "logic_compare",
},
],
},
],
},
});
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const items = this.workspace.getToolbox().getToolboxItems();
const origEvent =
new Blockly.Events.ToolboxItemSelect(
items[0].getName(), items[1].getName(), this.workspace.id);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,34 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventTrashcanOpen');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Trashcan Open Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const origEvent =
new Blockly.Events.TrashcanOpen(true, this.workspace.id);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,35 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventVarCreate');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Var Create Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const varModel =
new Blockly.VariableModel(this.workspace, 'name', 'type', 'id');
const origEvent = new Blockly.Events.VarCreate(varModel);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,34 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventVarDelete');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Var Delete Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const varModel =
new Blockly.VariableModel(this.workspace, 'name', 'type', 'id');
const origEvent = new Blockly.Events.VarDelete(varModel);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,34 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventVarRename');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Var Rename Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const varModel =
new Blockly.VariableModel(this.workspace, 'old name', 'type', 'id');
const origEvent = new Blockly.Events.VarRename(varModel, 'new name');
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -0,0 +1,34 @@
/**
* @license
* Copyright 2022 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
goog.declareModuleId('Blockly.test.eventViewportChange');
import {sharedTestSetup, sharedTestTeardown} from './test_helpers/setup_teardown.js';
suite('Viewport Change Event', function() {
setup(function() {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function() {
sharedTestTeardown.call(this);
});
suite('Serialization', function() {
test('events round-trip through JSON', function() {
const origEvent =
new Blockly.Events.ViewportChange(10, 10, 1, this.workspace.id, .8);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
chai.assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -50,9 +50,6 @@
// Test modules.
'Blockly.test.astNode',
'Blockly.test.blockChangeEvent',
'Blockly.test.blockDeleteEvent',
'Blockly.test.blockCreateEvent',
'Blockly.test.blockJson',
'Blockly.test.blocks',
'Blockly.test.comments',
@@ -64,6 +61,26 @@
'Blockly.test.cursor',
'Blockly.test.dropdown',
'Blockly.test.event',
'Blockly.test.eventBlockChange',
'Blockly.test.eventBlockCreate',
'Blockly.test.eventBlockDelete',
'Blockly.test.eventBlockDrag',
'Blockly.test.eventBlockMove',
'Blockly.test.eventBubbleOpen',
'Blockly.test.eventClick',
'Blockly.test.eventCommentChange',
'Blockly.test.eventCommentCreate',
'Blockly.test.eventCommentDelete',
'Blockly.test.eventCommentMove',
'Blockly.test.eventMarkerMove',
'Blockly.test.eventSelected',
'Blockly.test.eventThemeChange',
'Blockly.test.eventToolboxItemSelect',
'Blockly.test.eventTrashcanOpen',
'Blockly.test.eventVarCreate',
'Blockly.test.eventVarDelete',
'Blockly.test.eventVarRename',
'Blockly.test.eventViewportChange',
'Blockly.test.extensions',
'Blockly.test.fieldAngle',
'Blockly.test.fieldCheckbox',

View File

@@ -67,4 +67,3 @@ suite('Mutator', function() {
});
});
});