Skip to content

Commit 852512f

Browse files
authored
release: v12.0.0
2 parents 4141230 + e5de970 commit 852512f

File tree

264 files changed

+18241
-8609
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

264 files changed

+18241
-8609
lines changed

.github/workflows/assign_reviewers.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ jobs:
1616
requested-reviewer:
1717
runs-on: ubuntu-latest
1818
permissions:
19-
contents: read
20-
issues: write
19+
pull-requests: write
2120
steps:
2221
- name: Assign requested reviewer
2322
uses: actions/github-script@v7

.github/workflows/conventional-label.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ jobs:
88
label:
99
runs-on: ubuntu-latest
1010
permissions:
11-
contents: read
11+
issues: write
1212
pull-requests: write
1313
steps:
1414
- uses: bcoe/conventional-release-labels@v1

api-extractor.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,11 @@
352352
// Needs investigation.
353353
"ae-forgotten-export": {
354354
"logLevel": "none"
355+
},
356+
357+
// We don't prefix our internal APIs with underscores.
358+
"ae-internal-missing-underscore": {
359+
"logLevel": "none"
355360
}
356361
},
357362

blocks/loops.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ const CUSTOM_CONTEXT_MENU_CREATE_VARIABLES_GET_MIXIN = {
269269
}
270270
const varField = this.getField('VAR') as FieldVariable;
271271
const variable = varField.getVariable()!;
272-
const varName = variable.name;
272+
const varName = variable.getName();
273273
if (!this.isCollapsed() && varName !== null) {
274274
const getVarBlockState = {
275275
type: 'variables_get',

blocks/procedures.ts

Lines changed: 76 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import type {Block} from '../core/block.js';
1010
import type {BlockSvg} from '../core/block_svg.js';
1111
import type {BlockDefinition} from '../core/blocks.js';
12-
import * as common from '../core/common.js';
1312
import {defineBlocks} from '../core/common.js';
1413
import {config} from '../core/config.js';
1514
import type {Connection} from '../core/connection.js';
@@ -27,15 +26,19 @@ import {FieldCheckbox} from '../core/field_checkbox.js';
2726
import {FieldLabel} from '../core/field_label.js';
2827
import * as fieldRegistry from '../core/field_registry.js';
2928
import {FieldTextInput} from '../core/field_textinput.js';
29+
import {getFocusManager} from '../core/focus_manager.js';
3030
import '../core/icons/comment_icon.js';
3131
import {MutatorIcon as Mutator} from '../core/icons/mutator_icon.js';
3232
import '../core/icons/warning_icon.js';
3333
import {Align} from '../core/inputs/align.js';
34+
import type {
35+
IVariableModel,
36+
IVariableState,
37+
} from '../core/interfaces/i_variable_model.js';
3438
import {Msg} from '../core/msg.js';
3539
import {Names} from '../core/names.js';
3640
import * as Procedures from '../core/procedures.js';
3741
import * as xmlUtils from '../core/utils/xml.js';
38-
import type {VariableModel} from '../core/variable_model.js';
3942
import * as Variables from '../core/variables.js';
4043
import type {Workspace} from '../core/workspace.js';
4144
import type {WorkspaceSvg} from '../core/workspace_svg.js';
@@ -48,7 +51,7 @@ export const blocks: {[key: string]: BlockDefinition} = {};
4851
type ProcedureBlock = Block & ProcedureMixin;
4952
interface ProcedureMixin extends ProcedureMixinType {
5053
arguments_: string[];
51-
argumentVarModels_: VariableModel[];
54+
argumentVarModels_: IVariableModel<IVariableState>[];
5255
callType_: string;
5356
paramIds_: string[];
5457
hasStatements_: boolean;
@@ -128,7 +131,7 @@ const PROCEDURE_DEF_COMMON = {
128131
for (let i = 0; i < this.argumentVarModels_.length; i++) {
129132
const parameter = xmlUtils.createElement('arg');
130133
const argModel = this.argumentVarModels_[i];
131-
parameter.setAttribute('name', argModel.name);
134+
parameter.setAttribute('name', argModel.getName());
132135
parameter.setAttribute('varid', argModel.getId());
133136
if (opt_paramIds && this.paramIds_) {
134137
parameter.setAttribute('paramId', this.paramIds_[i]);
@@ -196,7 +199,7 @@ const PROCEDURE_DEF_COMMON = {
196199
state['params'].push({
197200
// We don't need to serialize the name, but just in case we decide
198201
// to separate params from variables.
199-
'name': this.argumentVarModels_[i].name,
202+
'name': this.argumentVarModels_[i].getName(),
200203
'id': this.argumentVarModels_[i].getId(),
201204
});
202205
}
@@ -224,7 +227,7 @@ const PROCEDURE_DEF_COMMON = {
224227
param['name'],
225228
'',
226229
);
227-
this.arguments_.push(variable.name);
230+
this.arguments_.push(variable.getName());
228231
this.argumentVarModels_.push(variable);
229232
}
230233
}
@@ -352,7 +355,9 @@ const PROCEDURE_DEF_COMMON = {
352355
*
353356
* @returns List of variable models.
354357
*/
355-
getVarModels: function (this: ProcedureBlock): VariableModel[] {
358+
getVarModels: function (
359+
this: ProcedureBlock,
360+
): IVariableModel<IVariableState>[] {
356361
return this.argumentVarModels_;
357362
},
358363
/**
@@ -370,23 +375,23 @@ const PROCEDURE_DEF_COMMON = {
370375
newId: string,
371376
) {
372377
const oldVariable = this.workspace.getVariableById(oldId)!;
373-
if (oldVariable.type !== '') {
378+
if (oldVariable.getType() !== '') {
374379
// Procedure arguments always have the empty type.
375380
return;
376381
}
377-
const oldName = oldVariable.name;
382+
const oldName = oldVariable.getName();
378383
const newVar = this.workspace.getVariableById(newId)!;
379384

380385
let change = false;
381386
for (let i = 0; i < this.argumentVarModels_.length; i++) {
382387
if (this.argumentVarModels_[i].getId() === oldId) {
383-
this.arguments_[i] = newVar.name;
388+
this.arguments_[i] = newVar.getName();
384389
this.argumentVarModels_[i] = newVar;
385390
change = true;
386391
}
387392
}
388393
if (change) {
389-
this.displayRenamedVar_(oldName, newVar.name);
394+
this.displayRenamedVar_(oldName, newVar.getName());
390395
Procedures.mutateCallers(this);
391396
}
392397
},
@@ -398,9 +403,9 @@ const PROCEDURE_DEF_COMMON = {
398403
*/
399404
updateVarName: function (
400405
this: ProcedureBlock & BlockSvg,
401-
variable: VariableModel,
406+
variable: IVariableModel<IVariableState>,
402407
) {
403-
const newName = variable.name;
408+
const newName = variable.getName();
404409
let change = false;
405410
let oldName;
406411
for (let i = 0; i < this.argumentVarModels_.length; i++) {
@@ -473,12 +478,16 @@ const PROCEDURE_DEF_COMMON = {
473478
const getVarBlockState = {
474479
type: 'variables_get',
475480
fields: {
476-
VAR: {name: argVar.name, id: argVar.getId(), type: argVar.type},
481+
VAR: {
482+
name: argVar.getName(),
483+
id: argVar.getId(),
484+
type: argVar.getType(),
485+
},
477486
},
478487
};
479488
options.push({
480489
enabled: true,
481-
text: Msg['VARIABLES_SET_CREATE_GET'].replace('%1', argVar.name),
490+
text: Msg['VARIABLES_SET_CREATE_GET'].replace('%1', argVar.getName()),
482491
callback: ContextMenu.callbackFactory(this, getVarBlockState),
483492
});
484493
}
@@ -620,30 +629,49 @@ type ArgumentBlock = Block & ArgumentMixin;
620629
interface ArgumentMixin extends ArgumentMixinType {}
621630
type ArgumentMixinType = typeof PROCEDURES_MUTATORARGUMENT;
622631

623-
// TODO(#6920): This is kludgy.
624-
type FieldTextInputForArgument = FieldTextInput & {
625-
oldShowEditorFn_(_e?: Event, quietInput?: boolean): void;
626-
createdVariables_: VariableModel[];
627-
};
632+
/**
633+
* Field responsible for editing procedure argument names.
634+
*/
635+
class ProcedureArgumentField extends FieldTextInput {
636+
/**
637+
* Whether or not this field is currently being edited interactively.
638+
*/
639+
editingInteractively = false;
640+
641+
/**
642+
* The procedure argument variable whose name is being interactively edited.
643+
*/
644+
editingVariable?: IVariableModel<IVariableState>;
645+
646+
/**
647+
* Displays the field editor.
648+
*
649+
* @param e The event that triggered display of the field editor.
650+
*/
651+
protected override showEditor_(e?: Event) {
652+
super.showEditor_(e);
653+
this.editingInteractively = true;
654+
this.editingVariable = undefined;
655+
}
656+
657+
/**
658+
* Handles cleanup when the field editor is dismissed.
659+
*/
660+
override onFinishEditing_(value: string) {
661+
super.onFinishEditing_(value);
662+
this.editingInteractively = false;
663+
}
664+
}
628665

629666
const PROCEDURES_MUTATORARGUMENT = {
630667
/**
631668
* Mutator block for procedure argument.
632669
*/
633670
init: function (this: ArgumentBlock) {
634-
const field = fieldRegistry.fromJson({
635-
type: 'field_input',
636-
text: Procedures.DEFAULT_ARG,
637-
}) as FieldTextInputForArgument;
638-
field.setValidator(this.validator_);
639-
// Hack: override showEditor to do just a little bit more work.
640-
// We don't have a good place to hook into the start of a text edit.
641-
field.oldShowEditorFn_ = (field as AnyDuringMigration).showEditor_;
642-
const newShowEditorFn = function (this: typeof field) {
643-
this.createdVariables_ = [];
644-
this.oldShowEditorFn_();
645-
};
646-
(field as AnyDuringMigration).showEditor_ = newShowEditorFn;
671+
const field = new ProcedureArgumentField(
672+
Procedures.DEFAULT_ARG,
673+
this.validator_,
674+
);
647675

648676
this.appendDummyInput()
649677
.appendField(Msg['PROCEDURES_MUTATORARG_TITLE'])
@@ -653,14 +681,6 @@ const PROCEDURES_MUTATORARGUMENT = {
653681
this.setStyle('procedure_blocks');
654682
this.setTooltip(Msg['PROCEDURES_MUTATORARG_TOOLTIP']);
655683
this.contextMenu = false;
656-
657-
// Create the default variable when we drag the block in from the flyout.
658-
// Have to do this after installing the field on the block.
659-
field.onFinishEditing_ = this.deleteIntermediateVars_;
660-
// Create an empty list so onFinishEditing_ has something to look at, even
661-
// though the editor was never opened.
662-
field.createdVariables_ = [];
663-
field.onFinishEditing_('x');
664684
},
665685

666686
/**
@@ -674,11 +694,11 @@ const PROCEDURES_MUTATORARGUMENT = {
674694
* @returns Valid name, or null if a name was not specified.
675695
*/
676696
validator_: function (
677-
this: FieldTextInputForArgument,
697+
this: ProcedureArgumentField,
678698
varName: string,
679699
): string | null {
680700
const sourceBlock = this.getSourceBlock()!;
681-
const outerWs = sourceBlock!.workspace.getRootWorkspace()!;
701+
const outerWs = sourceBlock.workspace.getRootWorkspace()!;
682702
varName = varName.replace(/[\s\xa0]+/g, ' ').replace(/^ | $/g, '');
683703
if (!varName) {
684704
return null;
@@ -707,50 +727,31 @@ const PROCEDURES_MUTATORARGUMENT = {
707727
return varName;
708728
}
709729

710-
let model = outerWs.getVariable(varName, '');
711-
if (model && model.name !== varName) {
730+
const model = outerWs.getVariable(varName, '');
731+
if (model && model.getName() !== varName) {
712732
// Rename the variable (case change)
713733
outerWs.renameVariableById(model.getId(), varName);
714734
}
715735
if (!model) {
716-
model = outerWs.createVariable(varName, '');
717-
if (model && this.createdVariables_) {
718-
this.createdVariables_.push(model);
736+
if (this.editingInteractively) {
737+
if (!this.editingVariable) {
738+
this.editingVariable = outerWs.createVariable(varName, '');
739+
} else {
740+
outerWs.renameVariableById(this.editingVariable.getId(), varName);
741+
}
742+
} else {
743+
outerWs.createVariable(varName, '');
719744
}
720745
}
721746
return varName;
722747
},
723-
724-
/**
725-
* Called when focusing away from the text field.
726-
* Deletes all variables that were created as the user typed their intended
727-
* variable name.
728-
*
729-
* @internal
730-
* @param newText The new variable name.
731-
*/
732-
deleteIntermediateVars_: function (
733-
this: FieldTextInputForArgument,
734-
newText: string,
735-
) {
736-
const outerWs = this.getSourceBlock()!.workspace.getRootWorkspace();
737-
if (!outerWs) {
738-
return;
739-
}
740-
for (let i = 0; i < this.createdVariables_.length; i++) {
741-
const model = this.createdVariables_[i];
742-
if (model.name !== newText) {
743-
outerWs.deleteVariableById(model.getId());
744-
}
745-
}
746-
},
747748
};
748749
blocks['procedures_mutatorarg'] = PROCEDURES_MUTATORARGUMENT;
749750

750751
/** Type of a block using the PROCEDURE_CALL_COMMON mixin. */
751752
type CallBlock = Block & CallMixin;
752753
interface CallMixin extends CallMixinType {
753-
argumentVarModels_: VariableModel[];
754+
argumentVarModels_: IVariableModel<IVariableState>[];
754755
arguments_: string[];
755756
defType_: string;
756757
quarkIds_: string[] | null;
@@ -1029,7 +1030,7 @@ const PROCEDURE_CALL_COMMON = {
10291030
*
10301031
* @returns List of variable models.
10311032
*/
1032-
getVarModels: function (this: CallBlock): VariableModel[] {
1033+
getVarModels: function (this: CallBlock): IVariableModel<IVariableState>[] {
10331034
return this.argumentVarModels_;
10341035
},
10351036
/**
@@ -1177,7 +1178,7 @@ const PROCEDURE_CALL_COMMON = {
11771178
const def = Procedures.getDefinition(name, workspace);
11781179
if (def) {
11791180
(workspace as WorkspaceSvg).centerOnBlock(def.id);
1180-
common.setSelected(def as BlockSvg);
1181+
getFocusManager().focusNode(def as BlockSvg);
11811182
}
11821183
},
11831184
});

blocks/variables.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import '../core/field_label.js';
2121
import {FieldVariable} from '../core/field_variable.js';
2222
import {Msg} from '../core/msg.js';
2323
import * as Variables from '../core/variables.js';
24-
import type {WorkspaceSvg} from '../core/workspace_svg.js';
2524

2625
/**
2726
* A dictionary of the block definitions provided by this module.
@@ -165,11 +164,11 @@ const deleteOptionCallbackFactory = function (
165164
block: VariableBlock,
166165
): () => void {
167166
return function () {
168-
const workspace = block.workspace;
169167
const variableField = block.getField('VAR') as FieldVariable;
170-
const variable = variableField.getVariable()!;
171-
workspace.deleteVariableById(variable.getId());
172-
(workspace as WorkspaceSvg).refreshToolboxSelection();
168+
const variable = variableField.getVariable();
169+
if (variable) {
170+
Variables.deleteVariable(variable.getWorkspace(), variable, block);
171+
}
173172
};
174173
};
175174

0 commit comments

Comments
 (0)