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