refactor: add better types to field configs (#6317)

* fix: add config types in all fields

* fix: add interfaces to fromJson

* chore: cleanup from cherry-pick

* chore: add docs to exported properties

* chore: format

* chore: remove unnecessary test case

* fix: replacing message references in tooltip

* chore: fix format

* chore: rename interfaces to be more explicit

* chore: format

* fix: add proper visibility keywords

* chore: fix label field config name

* chore: formatting

* chore: remove unnecessarily renamed imports
This commit is contained in:
Beka Westberg
2022-08-08 18:16:50 +00:00
committed by GitHub
parent 8f4b49a771
commit f07b06b6d5
13 changed files with 286 additions and 123 deletions

View File

@@ -209,7 +209,7 @@ export abstract class Field implements IASTNodeLocationSvg,
*/
constructor(
value: AnyDuringMigration, opt_validator?: Function|null,
opt_config?: AnyDuringMigration) {
opt_config?: FieldConfig) {
/**
* A generic value possessed by the field.
* Should generally be non-null, only null when the field is created.
@@ -237,17 +237,14 @@ export abstract class Field implements IASTNodeLocationSvg,
* individual field's documentation for a list of properties this
* parameter supports.
*/
protected configure_(config: AnyDuringMigration) {
let tooltip = config['tooltip'];
if (typeof tooltip === 'string') {
tooltip = parsing.replaceMessageReferences(config['tooltip']);
protected configure_(config: FieldConfig) {
// TODO (#2884): Possibly add CSS class config option.
// TODO (#2885): Possibly add cursor config option.
if (config.tooltip) {
this.setTooltip(parsing.replaceMessageReferences(config.tooltip));
}
tooltip && this.setTooltip(tooltip);
}
// TODO (#2884): Possibly add CSS class config option.
// TODO (#2885): Possibly add cursor config option.
/**
* Attach this field to a block.
* @param block The block containing this field.
@@ -1200,3 +1197,10 @@ export abstract class Field implements IASTNodeLocationSvg,
}
}
}
/**
* Extra configuration options for the base field.
*/
export interface FieldConfig {
tooltip?: string;
}

View File

@@ -21,7 +21,7 @@ import * as Css from './css.js';
import * as dropDownDiv from './dropdowndiv.js';
import {Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {FieldTextInput} from './field_textinput.js';
import {FieldTextInputConfig, FieldTextInput} from './field_textinput.js';
import * as dom from './utils/dom.js';
import {KeyCodes} from './utils/keycodes.js';
import * as math from './utils/math.js';
@@ -121,7 +121,7 @@ export class FieldAngle extends FieldTextInput {
*/
constructor(
opt_value?: string|number|Sentinel, opt_validator?: Function,
opt_config?: AnyDuringMigration) {
opt_config?: FieldAngleConfig) {
super(Field.SKIP_SETUP);
/**
@@ -165,15 +165,15 @@ export class FieldAngle extends FieldTextInput {
* Configure the field based on the given map of options.
* @param config A map of options to configure the field based on.
*/
override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldAngleConfig) {
super.configure_(config);
switch (config['mode']) {
case 'compass':
switch (config.mode) {
case Mode.COMPASS:
this.clockwise_ = true;
this.offset_ = 90;
break;
case 'protractor':
case Mode.PROTRACTOR:
// This is the default mode, so we could do nothing. But just to
// future-proof, we'll set it anyway.
this.clockwise_ = false;
@@ -182,33 +182,10 @@ export class FieldAngle extends FieldTextInput {
}
// Allow individual settings to override the mode setting.
const clockwise = config['clockwise'];
if (typeof clockwise === 'boolean') {
this.clockwise_ = clockwise;
}
// If these are passed as null then we should leave them on the default.
let offset = config['offset'];
if (offset !== null) {
offset = Number(offset);
if (!isNaN(offset)) {
this.offset_ = offset;
}
}
let wrap = config['wrap'];
if (wrap !== null) {
wrap = Number(wrap);
if (!isNaN(wrap)) {
this.wrap_ = wrap;
}
}
let round = config['round'];
if (round !== null) {
round = Number(round);
if (!isNaN(round)) {
this.round_ = round;
}
}
if (config.clockwise) this.clockwise_ = config.clockwise;
if (config.offset) this.offset_ = config.offset;
if (config.wrap) this.wrap_ = config.wrap;
if (config.round) this.round_ = config.round;
}
/**
@@ -509,10 +486,10 @@ export class FieldAngle extends FieldTextInput {
* @nocollapse
* @internal
*/
static override fromJson(options: AnyDuringMigration): FieldAngle {
static override fromJson(options: FieldAngleFromJsonConfig): FieldAngle {
// `this` might be a subclass of FieldAngle if that class doesn't override
// the static fromJson method.
return new this(options['angle'], undefined, options);
return new this(options.angle, undefined, options);
}
}
@@ -546,4 +523,41 @@ Css.register(`
fieldRegistry.register('field_angle', FieldAngle);
(FieldAngle.prototype as AnyDuringMigration).DEFAULT_VALUE = 0;
(FieldAngle.prototype as AnyDuringMigration).DEFAULT_VALUE = 0;
/**
* The two main modes of the angle field.
* Compass specifies:
* - clockwise: true
* - offset: 90
* - wrap: 0
* - round: 15
*
* Protractor specifies:
* - clockwise: false
* - offset: 0
* - wrap: 0
* - round: 15
*/
export enum Mode {
COMPASS = 'compass',
PROTRACTOR = 'protractor',
}
/**
* Extra configuration options for the angle field.
*/
export interface FieldAngleConfig extends FieldTextInputConfig {
mode?: Mode;
clockwise?: boolean;
offset?: number;
wrap?: number;
round?: number;
}
/**
* fromJson configuration options for the angle field.
*/
export interface FieldAngleFromJsonConfig extends FieldAngleConfig {
angle?: number;
}

View File

@@ -18,7 +18,7 @@ goog.declareModuleId('Blockly.FieldCheckbox');
// Unused import preserved for side-effects. Remove if unneeded.
import './events/events_block_change.js';
import {Field} from './field.js';
import {FieldConfig, Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import * as dom from './utils/dom.js';
import type {Sentinel} from './utils/sentinel.js';
@@ -61,7 +61,7 @@ export class FieldCheckbox extends Field {
*/
constructor(
opt_value?: string|boolean|Sentinel, opt_validator?: Function,
opt_config?: AnyDuringMigration) {
opt_config?: FieldCheckboxConfig) {
super(Field.SKIP_SETUP);
/**
@@ -86,11 +86,9 @@ export class FieldCheckbox extends Field {
* Configure the field based on the given map of options.
* @param config A map of options to configure the field based on.
*/
protected override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldCheckboxConfig) {
super.configure_(config);
if (config['checkCharacter']) {
this.checkChar_ = config['checkCharacter'];
}
if (config.checkCharacter) this.checkChar_ = config.checkCharacter;
}
/**
@@ -219,13 +217,27 @@ export class FieldCheckbox extends Field {
* @nocollapse
* @internal
*/
static fromJson(options: AnyDuringMigration): FieldCheckbox {
static fromJson(options: FieldCheckboxFromJsonConfig): FieldCheckbox {
// `this` might be a subclass of FieldCheckbox if that class doesn't
// 'override' the static fromJson method.
return new this(options['checked'], undefined, options);
return new this(options.checked, undefined, options);
}
}
fieldRegistry.register('field_checkbox', FieldCheckbox);
(FieldCheckbox.prototype as AnyDuringMigration).DEFAULT_VALUE = false;
(FieldCheckbox.prototype as AnyDuringMigration).DEFAULT_VALUE = false;
/**
* Config options for the checkbox field.
*/
export interface FieldCheckboxConfig extends FieldConfig {
checkCharacter?: string;
}
/**
* fromJson config options for the checkbox field.
*/
export interface FieldCheckboxFromJsonConfig extends FieldCheckboxConfig {
checked?: boolean;
}

View File

@@ -22,7 +22,7 @@ import {BlockSvg} from './block_svg.js';
import * as browserEvents from './browser_events.js';
import * as Css from './css.js';
import * as dropDownDiv from './dropdowndiv.js';
import {Field} from './field.js';
import {FieldConfig, Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import * as aria from './utils/aria.js';
import * as colour from './utils/colour.js';
@@ -155,7 +155,7 @@ export class FieldColour extends Field {
*/
constructor(
opt_value?: string|Sentinel, opt_validator?: Function,
opt_config?: AnyDuringMigration) {
opt_config?: FieldColourConfig) {
super(Field.SKIP_SETUP);
if (opt_value === Field.SKIP_SETUP) {
@@ -174,15 +174,11 @@ export class FieldColour extends Field {
* Configure the field based on the given map of options.
* @param config A map of options to configure the field based on.
*/
protected override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldColourConfig) {
super.configure_(config);
if (config['colourOptions']) {
this.colours_ = config['colourOptions'];
this.titles_ = config['colourTitles'];
}
if (config['columns']) {
this.columns_ = config['columns'];
}
if (config.colourOptions) this.colours_ = config.colourOptions;
if (config.colourTitles) this.titles_ = config.colourTitles;
if (config.columns) this.columns_ = config.columns;
}
/**
@@ -572,7 +568,7 @@ export class FieldColour extends Field {
* @nocollapse
* @internal
*/
static fromJson(options: AnyDuringMigration): FieldColour {
static fromJson(options: FieldColourFromJsonConfig): FieldColour {
// `this` might be a subclass of FieldColour if that class doesn't override
// the static fromJson method.
return new this(options['colour'], undefined, options);
@@ -618,3 +614,19 @@ Css.register(`
`);
fieldRegistry.register('field_colour', FieldColour);
/**
* Config options for the colour field.
*/
export interface FieldColourConfig extends FieldConfig {
colourOptions?: string[];
colourTitles?: string[];
columns?: number;
}
/**
* fromJson config options for the colour field.
*/
export interface FieldColourFromJsonConfig extends FieldColourConfig {
colour?: string;
}

View File

@@ -21,7 +21,7 @@ goog.declareModuleId('Blockly.FieldDropdown');
import type {BlockSvg} from './block_svg.js';
import * as dropDownDiv from './dropdowndiv.js';
import {Field} from './field.js';
import {FieldConfig, Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {Menu} from './menu.js';
import {MenuItem} from './menuitem.js';
@@ -117,7 +117,7 @@ export class FieldDropdown extends Field {
*/
constructor(
menuGenerator: AnyDuringMigration[][]|Function|Sentinel,
opt_validator?: Function, opt_config?: AnyDuringMigration) {
opt_validator?: Function, opt_config?: FieldConfig) {
super(Field.SKIP_SETUP);
// If we pass SKIP_SETUP, don't do *anything* with the menu generator.
@@ -656,10 +656,16 @@ export class FieldDropdown extends Field {
* @nocollapse
* @internal
*/
static fromJson(options: AnyDuringMigration): FieldDropdown {
static fromJson(options: FieldDropdownFromJsonConfig): FieldDropdown {
if (!options.options) {
throw new Error(
'options are required for the dropdown field. The ' +
'options property must be assigned an array of ' +
'[humanReadableValue, languageNeutralValue] tuples.');
}
// `this` might be a subclass of FieldDropdown if that class doesn't
// override the static fromJson method.
return new this(options['options'], undefined, options);
return new this(options.options, undefined, options);
}
/**
@@ -686,14 +692,30 @@ export class FieldDropdown extends Field {
}
}
/** Dropdown image properties. */
interface ImageProperties {
/**
* Definition of a human-readable image dropdown option.
*/
export interface ImageProperties {
src: string;
alt: string;
width: number;
height: number;
}
/**
* An individual option in the dropdown menu. The first element is the human-
* readable value (text or image), and the second element is the language-
* neutral value.
*/
export type MenuOption = [string | ImageProperties, string];
/**
* fromJson config for the dropdown field.
*/
export interface FieldDropdownFromJsonConfig extends FieldConfig {
options?: MenuOption[];
}
/**
* The y offset from the top of the field to the top of the image, if an image
* is selected.

View File

@@ -15,7 +15,7 @@
import * as goog from '../closure/goog/goog.js';
goog.declareModuleId('Blockly.FieldImage');
import {Field} from './field.js';
import {FieldConfig, Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import * as dom from './utils/dom.js';
import * as parsing from './utils/parsing.js';
@@ -84,13 +84,9 @@ export class FieldImage extends Field {
constructor(
src: string|Sentinel, width: string|number, height: string|number,
opt_alt?: string, opt_onClick?: (p1: FieldImage) => AnyDuringMigration,
opt_flipRtl?: boolean, opt_config?: AnyDuringMigration) {
opt_flipRtl?: boolean, opt_config?: FieldImageConfig) {
super(Field.SKIP_SETUP);
// Return early.
if (!src) {
throw Error('Src value of an image field is required');
}
const imageHeight = Number(parsing.replaceMessageReferences(height));
const imageWidth = Number(parsing.replaceMessageReferences(width));
if (isNaN(imageHeight) || isNaN(imageWidth)) {
@@ -133,10 +129,12 @@ export class FieldImage extends Field {
* Configure the field based on the given map of options.
* @param config A map of options to configure the field based on.
*/
protected override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldImageConfig) {
super.configure_(config);
this.flipRtl_ = !!config['flipRtl'];
this.altText_ = parsing.replaceMessageReferences(config['alt']) || '';
if (config.flipRtl) this.flipRtl_ = config.flipRtl;
if (config.alt) {
this.altText_ = parsing.replaceMessageReferences(config.alt);
}
}
/**
@@ -248,15 +246,37 @@ export class FieldImage extends Field {
* @nocollapse
* @internal
*/
static fromJson(options: AnyDuringMigration): FieldImage {
static fromJson(options: FieldImageFromJsonConfig): FieldImage {
if (!options.src || !options.width || !options.height) {
throw new Error(
'src, width, and height values for an image field are' +
'required. The width and height must be non-zero.');
}
// `this` might be a subclass of FieldImage if that class doesn't override
// the static fromJson method.
return new this(
options['src'], options['width'], options['height'], undefined,
undefined, undefined, options);
options.src, options.width, options.height, undefined, undefined,
undefined, options);
}
}
fieldRegistry.register('field_image', FieldImage);
(FieldImage.prototype as AnyDuringMigration).DEFAULT_VALUE = '';
(FieldImage.prototype as AnyDuringMigration).DEFAULT_VALUE = '';
/**
* Config options for the image field.
*/
export interface FieldImageConfig extends FieldConfig {
flipRtl?: boolean;
alt?: string;
}
/**
* fromJson config options for the colour field.
*/
export interface FieldImageFromJsonConfig extends FieldImageConfig {
src?: string;
width?: number;
height?: number;
}

View File

@@ -17,7 +17,7 @@
import * as goog from '../closure/goog/goog.js';
goog.declareModuleId('Blockly.FieldLabel');
import {Field} from './field.js';
import {FieldConfig, Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import * as dom from './utils/dom.js';
import * as parsing from './utils/parsing.js';
@@ -52,7 +52,7 @@ export class FieldLabel extends Field {
*/
constructor(
opt_value?: string|Sentinel, opt_class?: string,
opt_config?: AnyDuringMigration) {
opt_config?: FieldLabelConfig) {
super(Field.SKIP_SETUP);
if (opt_value === Field.SKIP_SETUP) {
@@ -66,9 +66,9 @@ export class FieldLabel extends Field {
this.setValue(opt_value);
}
override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldLabelConfig) {
super.configure_(config);
this.class_ = config['class'];
if (config.class) this.class_ = config.class;
}
/**
@@ -121,8 +121,8 @@ export class FieldLabel extends Field {
* @nocollapse
* @internal
*/
static fromJson(options: AnyDuringMigration): FieldLabel {
const text = parsing.replaceMessageReferences(options['text']);
static fromJson(options: FieldLabelFromJsonConfig): FieldLabel {
const text = parsing.replaceMessageReferences(options.text);
// `this` might be a subclass of FieldLabel if that class doesn't override
// the static fromJson method.
return new this(text, undefined, options);
@@ -131,4 +131,22 @@ export class FieldLabel extends Field {
fieldRegistry.register('field_label', FieldLabel);
(FieldLabel.prototype as AnyDuringMigration).DEFAULT_VALUE = '';
(FieldLabel.prototype as AnyDuringMigration).DEFAULT_VALUE = '';
// clang-format off
// Clang does not like the 'class' keyword being used as a property.
/**
* Config options for the label field.
*/
export interface FieldLabelConfig extends FieldConfig {
class?: string;
}
// clang-format on
/**
* fromJson config options for the label field.
*/
export interface FieldLabelFromJsonConfig extends FieldLabelConfig {
text?: string;
}

View File

@@ -19,7 +19,7 @@
import * as goog from '../closure/goog/goog.js';
goog.declareModuleId('Blockly.FieldLabelSerializable');
import {FieldLabel} from './field_label.js';
import {FieldLabelConfig, FieldLabelFromJsonConfig, FieldLabel} from './field_label.js';
import * as fieldRegistry from './field_registry.js';
import * as parsing from './utils/parsing.js';
@@ -52,7 +52,7 @@ export class FieldLabelSerializable extends FieldLabel {
* for a list of properties this parameter supports.
*/
constructor(
opt_value?: string, opt_class?: string, opt_config?: AnyDuringMigration) {
opt_value?: string, opt_class?: string, opt_config?: FieldLabelConfig) {
super(String(opt_value ?? ''), opt_class, opt_config);
}
@@ -64,9 +64,9 @@ export class FieldLabelSerializable extends FieldLabel {
* @nocollapse
* @internal
*/
static override fromJson(options: AnyDuringMigration):
static override fromJson(options: FieldLabelFromJsonConfig):
FieldLabelSerializable {
const text = parsing.replaceMessageReferences(options['text']);
const text = parsing.replaceMessageReferences(options.text);
// `this` might be a subclass of FieldLabelSerializable if that class
// doesn't override the static fromJson method.
return new this(text, undefined, options);

View File

@@ -18,7 +18,7 @@ goog.declareModuleId('Blockly.FieldMultilineInput');
import * as Css from './css.js';
import {Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {FieldTextInput} from './field_textinput.js';
import {FieldTextInputConfig, FieldTextInput} from './field_textinput.js';
import * as aria from './utils/aria.js';
import * as dom from './utils/dom.js';
import {KeyCodes} from './utils/keycodes.js';
@@ -68,7 +68,7 @@ export class FieldMultilineInput extends FieldTextInput {
*/
constructor(
opt_value?: string|Sentinel, opt_validator?: Function,
opt_config?: AnyDuringMigration) {
opt_config?: FieldMultilineInputConfig) {
super(Field.SKIP_SETUP);
if (opt_value === Field.SKIP_SETUP) {
@@ -83,9 +83,9 @@ export class FieldMultilineInput extends FieldTextInput {
}
}
override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldMultilineInputConfig) {
super.configure_(config);
config['maxLines'] && this.setMaxLines(config['maxLines']);
if (config.maxLines) this.setMaxLines(config.maxLines);
}
/**
@@ -424,8 +424,9 @@ export class FieldMultilineInput extends FieldTextInput {
* @nocollapse
* @internal
*/
static override fromJson(options: AnyDuringMigration): FieldMultilineInput {
const text = parsing.replaceMessageReferences(options['text']);
static override fromJson(options: FieldMultilineInputFromJsonConfig):
FieldMultilineInput {
const text = parsing.replaceMessageReferences(options.text);
// `this` might be a subclass of FieldMultilineInput if that class doesn't
// override the static fromJson method.
return new this(text, undefined, options);
@@ -448,3 +449,18 @@ Css.register(`
`);
fieldRegistry.register('field_multilinetext', FieldMultilineInput);
/**
* Config options for the multiline input field.
*/
export interface FieldMultilineInputConfig extends FieldTextInputConfig {
maxLines?: number;
}
/**
* fromJson config options for the multiline input field.
*/
export interface FieldMultilineInputFromJsonConfig extends
FieldMultilineInputConfig {
text?: string;
}

View File

@@ -17,7 +17,7 @@ goog.declareModuleId('Blockly.FieldNumber');
import {Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {FieldTextInput} from './field_textinput.js';
import {FieldTextInputConfig, FieldTextInput} from './field_textinput.js';
import * as aria from './utils/aria.js';
import type {Sentinel} from './utils/sentinel.js';
@@ -70,7 +70,7 @@ export class FieldNumber extends FieldTextInput {
constructor(
opt_value?: string|number|Sentinel, opt_min?: string|number|null,
opt_max?: string|number|null, opt_precision?: string|number|null,
opt_validator?: Function|null, opt_config?: AnyDuringMigration) {
opt_validator?: Function|null, opt_config?: FieldNumberConfig) {
// Pass SENTINEL so that we can define properties before value validation.
super(Field.SKIP_SETUP);
@@ -92,11 +92,11 @@ export class FieldNumber extends FieldTextInput {
* Configure the field based on the given map of options.
* @param config A map of options to configure the field based on.
*/
override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldNumberConfig) {
super.configure_(config);
this.setMinInternal_(config['min']);
this.setMaxInternal_(config['max']);
this.setPrecisionInternal_(config['precision']);
this.setMinInternal_(config.min);
this.setMaxInternal_(config.max);
this.setPrecisionInternal_(config.precision);
}
/**
@@ -298,14 +298,30 @@ export class FieldNumber extends FieldTextInput {
* @nocollapse
* @internal
*/
static override fromJson(options: AnyDuringMigration): FieldNumber {
static override fromJson(options: FieldNumberFromJsonConfig): FieldNumber {
// `this` might be a subclass of FieldNumber if that class doesn't override
// the static fromJson method.
return new this(
options['value'], undefined, undefined, undefined, undefined, options);
options.value, undefined, undefined, undefined, undefined, options);
}
}
fieldRegistry.register('field_number', FieldNumber);
(FieldNumber.prototype as AnyDuringMigration).DEFAULT_VALUE = 0;
/**
* Config options for the number field.
*/
export interface FieldNumberConfig extends FieldTextInputConfig {
min?: number;
max?: number;
precision?: number;
}
/**
* fromJson config options for the number field.
*/
export interface FieldNumberFromJsonConfig extends FieldNumberConfig {
value?: number;
}

View File

@@ -23,7 +23,7 @@ import * as browserEvents from './browser_events.js';
import * as dialog from './dialog.js';
import * as dropDownDiv from './dropdowndiv.js';
import * as eventUtils from './events/utils.js';
import {Field} from './field.js';
import {FieldConfig, Field} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {Msg} from './msg.js';
import * as aria from './utils/aria.js';
@@ -105,7 +105,7 @@ export class FieldTextInput extends Field {
*/
constructor(
opt_value?: string|Sentinel, opt_validator?: Function|null,
opt_config?: AnyDuringMigration) {
opt_config?: FieldTextInputConfig) {
super(Field.SKIP_SETUP);
if (opt_value === Field.SKIP_SETUP) {
@@ -120,10 +120,10 @@ export class FieldTextInput extends Field {
}
}
override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldTextInputConfig) {
super.configure_(config);
if (typeof config['spellcheck'] === 'boolean') {
this.spellcheck_ = config['spellcheck'];
if (config.spellcheck !== undefined) {
this.spellcheck_ = config.spellcheck;
}
}
@@ -564,8 +564,8 @@ export class FieldTextInput extends Field {
* @nocollapse
* @internal
*/
static fromJson(options: AnyDuringMigration): FieldTextInput {
const text = parsing.replaceMessageReferences(options['text']);
static fromJson(options: FieldTextInputFromJsonConfig): FieldTextInput {
const text = parsing.replaceMessageReferences(options.text);
// `this` might be a subclass of FieldTextInput if that class doesn't
// override the static fromJson method.
return new this(text, undefined, options);
@@ -575,3 +575,17 @@ export class FieldTextInput extends Field {
fieldRegistry.register('field_input', FieldTextInput);
(FieldTextInput.prototype as AnyDuringMigration).DEFAULT_VALUE = '';
/**
* Config options for the text input field.
*/
export interface FieldTextInputConfig extends FieldConfig {
spellcheck?: boolean;
}
/**
* fromJson config options for the text input field.
*/
export interface FieldTextInputFromJsonConfig extends FieldTextInputConfig {
text?: string;
}

View File

@@ -19,7 +19,7 @@ goog.declareModuleId('Blockly.FieldVariable');
import './events/events_block_change.js';
import type {Block} from './block.js';
import {Field} from './field.js';
import {Field, FieldConfig} from './field.js';
import {FieldDropdown} from './field_dropdown.js';
import * as fieldRegistry from './field_registry.js';
import * as internalConstants from './internal_constants.js';
@@ -84,7 +84,7 @@ export class FieldVariable extends FieldDropdown {
constructor(
varName: string|null|Sentinel, opt_validator?: Function,
opt_variableTypes?: string[], opt_defaultType?: string,
opt_config?: AnyDuringMigration) {
opt_config?: FieldVariableConfig) {
super(Field.SKIP_SETUP);
/**
@@ -123,9 +123,9 @@ export class FieldVariable extends FieldDropdown {
* Configure the field based on the given map of options.
* @param config A map of options to configure the field based on.
*/
protected override configure_(config: AnyDuringMigration) {
protected override configure_(config: FieldVariableConfig) {
super.configure_(config);
this.setTypes_(config['variableTypes'], config['defaultType']);
this.setTypes_(config.variableTypes, config.defaultType);
}
/**
@@ -475,8 +475,9 @@ export class FieldVariable extends FieldDropdown {
* @nocollapse
* @internal
*/
static override fromJson(options: AnyDuringMigration): FieldVariable {
const varName = parsing.replaceMessageReferences(options['variable']);
static override fromJson(options: FieldVariableFromJsonConfig):
FieldVariable {
const varName = parsing.replaceMessageReferences(options.variable);
// `this` might be a subclass of FieldVariable if that class doesn't
// override the static fromJson method.
return new this(varName, undefined, undefined, undefined, options);
@@ -527,3 +528,18 @@ export class FieldVariable extends FieldDropdown {
}
fieldRegistry.register('field_variable', FieldVariable);
/**
* Config options for the variable field.
*/
export interface FieldVariableConfig extends FieldConfig {
variableTypes?: string[];
defaultType?: string;
}
/**
* fromJson config options for the variable field.
*/
export interface FieldVariableFromJsonConfig extends FieldVariableConfig {
variable?: string;
}