diff --git a/core/block.ts b/core/block.ts index 425e42774..a37de7dab 100644 --- a/core/block.ts +++ b/core/block.ts @@ -1568,13 +1568,7 @@ export class Block implements IASTNodeLocation, IDeletable { * @returns The input object created. */ appendValueInput(name: string): Input { - return this.appendInput( - new ValueInput( - name, - this, - this.makeConnection_(ConnectionType.INPUT_VALUE) - ) - ); + return this.appendInput(new ValueInput(name, this)); } /** @@ -1586,13 +1580,7 @@ export class Block implements IASTNodeLocation, IDeletable { */ appendStatementInput(name: string): Input { this.statementInputCount++; - return this.appendInput( - new StatementInput( - name, - this, - this.makeConnection_(ConnectionType.NEXT_STATEMENT) - ) - ); + return this.appendInput(new StatementInput(name, this)); } /** @@ -1632,7 +1620,7 @@ export class Block implements IASTNodeLocation, IDeletable { false ); if (!inputConstructor) return null; - return this.appendInput(new inputConstructor(name, this, null)); + return this.appendInput(new inputConstructor(name, this)); } /** @@ -2309,8 +2297,9 @@ export class Block implements IASTNodeLocation, IDeletable { * * @param type The type of the connection to create. * @returns A new connection of the specified type. + * @internal */ - protected makeConnection_(type: number): Connection { + makeConnection_(type: ConnectionType): Connection { return new Connection(this, type); } diff --git a/core/block_svg.ts b/core/block_svg.ts index 1dbcec637..e8172c51a 100644 --- a/core/block_svg.ts +++ b/core/block_svg.ts @@ -1474,8 +1474,9 @@ export class BlockSvg * * @param type The type of the connection to create. * @returns A new connection of the specified type. + * @internal */ - protected override makeConnection_(type: number): RenderedConnection { + override makeConnection_(type: ConnectionType): RenderedConnection { return new RenderedConnection(this, type); } diff --git a/core/inputs/dummy_input.ts b/core/inputs/dummy_input.ts index 7abfbea93..3521b9df0 100644 --- a/core/inputs/dummy_input.ts +++ b/core/inputs/dummy_input.ts @@ -18,6 +18,6 @@ export class DummyInput extends Input { * @param block The block containing this input. */ constructor(public name: string, block: Block) { - super(name, block, null); + super(name, block); } } diff --git a/core/inputs/input.ts b/core/inputs/input.ts index fd43da4ad..abfa274c4 100644 --- a/core/inputs/input.ts +++ b/core/inputs/input.ts @@ -18,6 +18,7 @@ import '../field_label.js'; import type {Block} from '../block.js'; import type {BlockSvg} from '../block_svg.js'; import type {Connection} from '../connection.js'; +import type {ConnectionType} from '../connection_type.js'; import type {Field} from '../field.js'; import * as fieldRegistry from '../field_registry.js'; import type {RenderedConnection} from '../rendered_connection.js'; @@ -36,19 +37,14 @@ export class Input { public readonly type: inputTypes = inputTypes.CUSTOM; + public connection: Connection | null = null; + /** * @param name Language-neutral identifier which may used to find this input * again. * @param sourceBlock The block containing this input. - * @param connection Optional connection for this input. If this is a custom - * input, `null` will always be passed, and then the subclass can - * optionally construct a connection. */ - constructor( - public name: string, - private sourceBlock: Block, - public connection: Connection | null - ) {} + constructor(public name: string, private sourceBlock: Block) {} /** * Get the source block for this input. @@ -296,6 +292,18 @@ export class Input { this.connection.dispose(); } } + + /** + * Constructs a connection based on the type of this input's source block. + * Properly handles constructing headless connections for headless blocks + * and rendered connections for rendered blocks. + * + * @returns a connection of the given type, which is either a headless + * or rendered connection, based on the type of this input's source block. + */ + protected makeConnection(type: ConnectionType): Connection { + return this.sourceBlock.makeConnection_(type); + } } export namespace Input { diff --git a/core/inputs/statement_input.ts b/core/inputs/statement_input.ts index bd7ea1714..ee0663459 100644 --- a/core/inputs/statement_input.ts +++ b/core/inputs/statement_input.ts @@ -6,6 +6,7 @@ import type {Block} from '../block.js'; import type {Connection} from '../connection.js'; +import {ConnectionType} from '../connection_type.js'; import {Input} from './input.js'; import {inputTypes} from './input_types.js'; @@ -13,20 +14,18 @@ import {inputTypes} from './input_types.js'; export class StatementInput extends Input { readonly type = inputTypes.STATEMENT; + public connection: Connection; + /** * @param name Language-neutral identifier which may used to find this input * again. * @param block The block containing this input. - * @param connection The statement connection for this input. */ - constructor( - public name: string, - block: Block, - public connection: Connection - ) { + constructor(public name: string, block: Block) { // Errors are maintained for people not using typescript. if (!name) throw new Error('Statement inputs must have a non-empty name'); - if (!connection) throw new Error('Value inputs must have a connection'); - super(name, block, connection); + + super(name, block); + this.connection = this.makeConnection(ConnectionType.NEXT_STATEMENT); } } diff --git a/core/inputs/value_input.ts b/core/inputs/value_input.ts index 1abe4d303..ef88ac58e 100644 --- a/core/inputs/value_input.ts +++ b/core/inputs/value_input.ts @@ -5,7 +5,7 @@ */ import type {Block} from '../block.js'; -import type {Connection} from '../connection.js'; +import {ConnectionType} from '../connection_type.js'; import {Input} from './input.js'; import {inputTypes} from './input_types.js'; @@ -17,16 +17,11 @@ export class ValueInput extends Input { * @param name Language-neutral identifier which may used to find this input * again. * @param block The block containing this input. - * @param connection The value connection for this input. */ - constructor( - public name: string, - block: Block, - public connection: Connection - ) { + constructor(public name: string, block: Block) { // Errors are maintained for people not using typescript. if (!name) throw new Error('Value inputs must have a non-empty name'); - if (!connection) throw new Error('Value inputs must have a connection'); - super(name, block, connection); + super(name, block); + this.connection = this.makeConnection(ConnectionType.INPUT_VALUE); } }