mirror of
https://github.com/google/blockly.git
synced 2025-12-16 06:10:12 +01:00
fix: block initialization (#7777)
* fix: reorganize initialization * chore: fix failing tests * fix: tests * chore: format * chore: remove console trace
This commit is contained in:
@@ -921,10 +921,9 @@ const PROCEDURE_CALL_COMMON = {
|
||||
type: 'field_label',
|
||||
text: this.arguments_[i],
|
||||
}) as FieldLabel;
|
||||
const input = this.appendValueInput('ARG' + i)
|
||||
this.appendValueInput('ARG' + i)
|
||||
.setAlign(Align.RIGHT)
|
||||
.appendField(newField, 'ARGNAME' + i);
|
||||
input.init();
|
||||
}
|
||||
}
|
||||
// Remove deleted inputs.
|
||||
@@ -937,7 +936,6 @@ const PROCEDURE_CALL_COMMON = {
|
||||
if (this.arguments_.length) {
|
||||
if (!this.getField('WITH')) {
|
||||
topRow.appendField(Msg['PROCEDURES_CALL_BEFORE_PARAMS'], 'WITH');
|
||||
topRow.init();
|
||||
}
|
||||
} else {
|
||||
if (this.getField('WITH')) {
|
||||
|
||||
@@ -191,6 +191,13 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
*/
|
||||
private disposing = false;
|
||||
|
||||
/**
|
||||
* Has this block been fully initialized? E.g. all fields initailized.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
initialized = false;
|
||||
|
||||
private readonly xy_: Coordinate;
|
||||
isInFlyout: boolean;
|
||||
isInMutator: boolean;
|
||||
@@ -373,13 +380,11 @@ export class Block implements IASTNodeLocation, IDeletable {
|
||||
* change).
|
||||
*/
|
||||
initModel() {
|
||||
if (this.initialized) return;
|
||||
for (const input of this.inputList) {
|
||||
for (const field of input.fieldRow) {
|
||||
if (field.initModel) {
|
||||
field.initModel();
|
||||
}
|
||||
}
|
||||
input.initModel();
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -163,6 +163,9 @@ export class BlockSvg
|
||||
*/
|
||||
constructor(workspace: WorkspaceSvg, prototypeName: string, opt_id?: string) {
|
||||
super(workspace, prototypeName, opt_id);
|
||||
if (!workspace.rendered) {
|
||||
throw TypeError('Cannot create a rendered block in a headless workspace');
|
||||
}
|
||||
this.workspace = workspace;
|
||||
this.svgGroup_ = dom.createSvgElement(Svg.G, {});
|
||||
|
||||
@@ -189,10 +192,8 @@ export class BlockSvg
|
||||
* May be called more than once.
|
||||
*/
|
||||
initSvg() {
|
||||
if (!this.workspace.rendered) {
|
||||
throw TypeError('Workspace is headless.');
|
||||
}
|
||||
for (let i = 0, input; (input = this.inputList[i]); i++) {
|
||||
if (this.initialized) return;
|
||||
for (const input of this.inputList) {
|
||||
input.init();
|
||||
}
|
||||
for (const icon of this.getIcons()) {
|
||||
@@ -202,7 +203,7 @@ export class BlockSvg
|
||||
this.applyColour();
|
||||
this.pathObject.updateMovable(this.isMovable());
|
||||
const svg = this.getSvgRoot();
|
||||
if (!this.workspace.options.readOnly && !this.eventsInit_ && svg) {
|
||||
if (!this.workspace.options.readOnly && svg) {
|
||||
browserEvents.conditionalBind(
|
||||
svg,
|
||||
'pointerdown',
|
||||
@@ -210,11 +211,11 @@ export class BlockSvg
|
||||
this.onMouseDown_,
|
||||
);
|
||||
}
|
||||
this.eventsInit_ = true;
|
||||
|
||||
if (!svg.parentNode) {
|
||||
this.workspace.getCanvas().appendChild(svg);
|
||||
}
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -314,6 +314,7 @@ export abstract class Field<T = any>
|
||||
this.setTooltip(this.tooltip_);
|
||||
this.bindEvents_();
|
||||
this.initModel();
|
||||
this.applyColour();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -103,10 +103,7 @@ export class Input {
|
||||
}
|
||||
|
||||
field.setSourceBlock(this.sourceBlock);
|
||||
if (this.sourceBlock.rendered) {
|
||||
field.init();
|
||||
field.applyColour();
|
||||
}
|
||||
if (this.sourceBlock.initialized) this.initField(field);
|
||||
field.name = opt_name;
|
||||
field.setVisible(this.isVisible());
|
||||
|
||||
@@ -270,11 +267,28 @@ export class Input {
|
||||
|
||||
/** Initialize the fields on this input. */
|
||||
init() {
|
||||
if (!this.sourceBlock.rendered) {
|
||||
return; // Headless blocks don't need fields initialized.
|
||||
for (const field of this.fieldRow) {
|
||||
field.init();
|
||||
}
|
||||
for (let i = 0; i < this.fieldRow.length; i++) {
|
||||
this.fieldRow[i].init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the fields on this input for a headless block.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public initModel() {
|
||||
for (const field of this.fieldRow) {
|
||||
field.initModel();
|
||||
}
|
||||
}
|
||||
|
||||
/** Initializes the given field. */
|
||||
private initField(field: Field) {
|
||||
if (this.sourceBlock.rendered) {
|
||||
field.init();
|
||||
} else {
|
||||
field.initModel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -166,6 +166,7 @@ function shouldRenderRootBlock(block: BlockSvg): boolean {
|
||||
*/
|
||||
function renderBlock(block: BlockSvg) {
|
||||
if (!dirtyBlocks.has(block)) return;
|
||||
if (!block.initialized) return;
|
||||
for (const child of block.getChildren(false)) {
|
||||
renderBlock(child);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ suite('Render Management', function () {
|
||||
getRelativeToSurfaceXY: () => ({x: 0, y: 0}),
|
||||
updateComponentLocations: () => {},
|
||||
bumpNeighbours: () => {},
|
||||
initialized: true,
|
||||
workspace: {
|
||||
resizeContents: () => {},
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user