feat: Add a VarTypeChange event. (#8402)

* feat: Add a VarTypeChange event.

* chore: Update copyright date.

* refactor: Inline fields in the constructor.
This commit is contained in:
Aaron Dodson
2024-07-29 12:00:52 -07:00
committed by GitHub
parent af0a724b3e
commit 82c7aad4e7
5 changed files with 175 additions and 0 deletions

View File

@@ -43,6 +43,7 @@ import {VarBase, VarBaseJson} from './events_var_base.js';
import {VarCreate, VarCreateJson} from './events_var_create.js';
import {VarDelete, VarDeleteJson} from './events_var_delete.js';
import {VarRename, VarRenameJson} from './events_var_rename.js';
import {VarTypeChange, VarTypeChangeJson} from './events_var_type_change.js';
import {ViewportChange, ViewportChangeJson} from './events_viewport.js';
import * as eventUtils from './utils.js';
import {FinishedLoading} from './workspace_events.js';
@@ -105,6 +106,8 @@ export {VarDelete};
export {VarDeleteJson};
export {VarRename};
export {VarRenameJson};
export {VarTypeChange};
export {VarTypeChangeJson};
export {ViewportChange};
export {ViewportChangeJson};
@@ -140,6 +143,7 @@ export const UI = eventUtils.UI;
export const VAR_CREATE = eventUtils.VAR_CREATE;
export const VAR_DELETE = eventUtils.VAR_DELETE;
export const VAR_RENAME = eventUtils.VAR_RENAME;
export const VAR_TYPE_CHAGE = eventUtils.VAR_TYPE_CHANGE;
export const VIEWPORT_CHANGE = eventUtils.VIEWPORT_CHANGE;
// Event utils.

View File

@@ -0,0 +1,122 @@
/**
* @license
* Copyright 2024 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
/**
* Class for a variable type change event.
*
* @class
*/
import * as registry from '../registry.js';
import type {
IVariableModel,
IVariableState,
} from '../interfaces/i_variable_model.js';
import {VarBase, VarBaseJson} from './events_var_base.js';
import * as eventUtils from './utils.js';
import type {Workspace} from '../workspace.js';
/**
* Notifies listeners that a variable's type has changed.
*/
export class VarTypeChange extends VarBase {
override type = eventUtils.VAR_TYPE_CHANGE;
/**
* @param variable The variable whose type changed. Undefined for a blank event.
* @param oldType The old type of the variable. Undefined for a blank event.
* @param newType The new type of the variable. Undefined for a blank event.
*/
constructor(
variable?: IVariableModel<IVariableState>,
public oldType?: string,
public newType?: string,
) {
super(variable);
}
/**
* Encode the event as JSON.
*
* @returns JSON representation.
*/
override toJson(): VarTypeChangeJson {
const json = super.toJson() as VarTypeChangeJson;
if (!this.oldType || !this.newType) {
throw new Error(
"The variable's types are undefined. Either pass them to " +
'the constructor, or call fromJson',
);
}
json['oldType'] = this.oldType;
json['newType'] = this.newType;
return json;
}
/**
* Deserializes the JSON event.
*
* @param event The event to append new properties to. Should be a subclass
* of VarTypeChange, 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: VarTypeChangeJson,
workspace: Workspace,
event?: any,
): VarTypeChange {
const newEvent = super.fromJson(
json,
workspace,
event ?? new VarTypeChange(),
) as VarTypeChange;
newEvent.oldType = json['oldType'];
newEvent.newType = json['newType'];
return newEvent;
}
/**
* Run a variable type change event.
*
* @param forward True if run forward, false if run backward (undo).
*/
override run(forward: boolean) {
const workspace = this.getEventWorkspace_();
if (!this.varId) {
throw new Error(
'The var ID is undefined. Either pass a variable to ' +
'the constructor, or call fromJson',
);
}
if (!this.oldType || !this.newType) {
throw new Error(
"The variable's types are undefined. Either pass them to " +
'the constructor, or call fromJson',
);
}
const variable = workspace.getVariableMap().getVariableById(this.varId);
if (!variable) return;
if (forward) {
workspace.getVariableMap().changeVariableType(variable, this.newType);
} else {
workspace.getVariableMap().changeVariableType(variable, this.oldType);
}
}
}
export interface VarTypeChangeJson extends VarBaseJson {
oldType: string;
newType: string;
}
registry.register(
registry.Type.EVENT,
eventUtils.VAR_TYPE_CHANGE,
VarTypeChange,
);

View File

@@ -111,6 +111,11 @@ export const VAR_DELETE = 'var_delete';
*/
export const VAR_RENAME = 'var_rename';
/**
* Name of event that changes a variable's type.
*/
export const VAR_TYPE_CHANGE = 'var_type_change';
/**
* Name of generic event that records a UI change.
*/

View File

@@ -0,0 +1,43 @@
/**
* @license
* Copyright 2024 Google LLC
* SPDX-License-Identifier: Apache-2.0
*/
import {assert} from '../../node_modules/chai/chai.js';
import {
sharedTestSetup,
sharedTestTeardown,
} from './test_helpers/setup_teardown.js';
suite('Var Type Change Event', function () {
setup(function () {
sharedTestSetup.call(this);
this.workspace = new Blockly.Workspace();
});
teardown(function () {
sharedTestTeardown.call(this);
});
suite('Serialization', function () {
test('variable type change events round-trip through JSON', function () {
const varModel = new Blockly.VariableModel(
this.workspace,
'name',
'foo',
'id',
);
const origEvent = new Blockly.Events.VarTypeChange(
varModel,
'foo',
'bar',
);
const json = origEvent.toJson();
const newEvent = new Blockly.Events.fromJson(json, this.workspace);
assert.deepEqual(newEvent, origEvent);
});
});
});

View File

@@ -76,6 +76,7 @@
import './event_var_create_test.js';
import './event_var_delete_test.js';
import './event_var_rename_test.js';
import './event_var_type_change_test.js';
import './event_viewport_test.js';
import './extensions_test.js';
import './field_checkbox_test.js';