mirror of
https://github.com/google/blockly.git
synced 2026-01-06 16:40:07 +01:00
chore: cleaned up several type cases in core/field.ts and impacted files (#6363)
* chore: cleaned up several type cases in core/field.ts and impacted files * chore: updated instances of `sourceBlock_!` to `getSourceBlock()` * chore: updated instances of `fieldGroup_!` to `getSvgRoot()` * chore: updated nullable variables in `field.ts` to use internal functions * chore: updated getSourceBlock and getSvgRoot to handle nullability * chore: updated comments to reference throwing an error * fix: reverted `getSvgRoot` to `fieldGroup_` in null-accepting areas * fix: updated `getSvgRoot` to allow null and added null handling methods * fix: moved click target error handling to their specific cases * fix: updated drawer.ts to handle cast svg group to defined
This commit is contained in:
committed by
GitHub
parent
dd0d0f6bcf
commit
fa925e8c35
172
core/field.ts
172
core/field.ts
@@ -72,9 +72,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
protected value_: AnyDuringMigration;
|
||||
|
||||
/** Validation function called when user edits an editable field. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'Function'.
|
||||
protected validator_: Function = null as AnyDuringMigration;
|
||||
protected validator_: Function|null = null;
|
||||
|
||||
/**
|
||||
* Used to cache the field's tooltip value if setTooltip is called when the
|
||||
@@ -87,44 +85,31 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
* Holds the cursors svg element when the cursor is attached to the field.
|
||||
* This is null if there is no cursor on the field.
|
||||
*/
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'SVGElement'.
|
||||
private cursorSvg_: SVGElement = null as AnyDuringMigration;
|
||||
private cursorSvg_: SVGElement|null = null;
|
||||
|
||||
/**
|
||||
* Holds the markers svg element when the marker is attached to the field.
|
||||
* This is null if there is no marker on the field.
|
||||
*/
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'SVGElement'.
|
||||
private markerSvg_: SVGElement = null as AnyDuringMigration;
|
||||
private markerSvg_: SVGElement|null = null;
|
||||
|
||||
/** The rendered field's SVG group element. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'SVGGElement'.
|
||||
protected fieldGroup_: SVGGElement = null as AnyDuringMigration;
|
||||
protected fieldGroup_: SVGGElement|null = null;
|
||||
|
||||
/** The rendered field's SVG border element. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'SVGRectElement'.
|
||||
protected borderRect_: SVGRectElement = null as AnyDuringMigration;
|
||||
protected borderRect_: SVGRectElement|null = null;
|
||||
|
||||
/** The rendered field's SVG text element. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'SVGTextElement'.
|
||||
protected textElement_: SVGTextElement = null as AnyDuringMigration;
|
||||
protected textElement_: SVGTextElement|null = null;
|
||||
|
||||
/** The rendered field's text content element. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type 'Text'.
|
||||
protected textContent_: Text = null as AnyDuringMigration;
|
||||
protected textContent_: Text|null = null;
|
||||
|
||||
/** Mouse down event listener data. */
|
||||
private mouseDownWrapper_: browserEvents.Data|null = null;
|
||||
|
||||
/** Constants associated with the source block's renderer. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'ConstantProvider'.
|
||||
protected constants_: ConstantProvider = null as AnyDuringMigration;
|
||||
protected constants_: ConstantProvider|null = null;
|
||||
|
||||
/**
|
||||
* Has this field been disposed of?
|
||||
@@ -137,8 +122,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
maxDisplayLength = 50;
|
||||
|
||||
/** Block this field is attached to. Starts as null, then set in init. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type 'Block'.
|
||||
protected sourceBlock_: Block = null as AnyDuringMigration;
|
||||
protected sourceBlock_: Block|null = null;
|
||||
|
||||
/** Does this block need to be re-rendered? */
|
||||
protected isDirty_ = true;
|
||||
@@ -152,9 +136,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
protected enabled_ = true;
|
||||
|
||||
/** The element the click handler is bound to. */
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'Element'.
|
||||
protected clickTarget_: Element = null as AnyDuringMigration;
|
||||
protected clickTarget_: Element|null = null;
|
||||
|
||||
/**
|
||||
* The prefix field.
|
||||
@@ -271,8 +253,12 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
* Get the block this field is attached to.
|
||||
*
|
||||
* @returns The block containing this field.
|
||||
* @throws An error if the source block is not defined.
|
||||
*/
|
||||
getSourceBlock(): Block {
|
||||
if (!this.sourceBlock_) {
|
||||
throw new Error(`The source block is ${this.sourceBlock_}.`);
|
||||
}
|
||||
return this.sourceBlock_;
|
||||
}
|
||||
|
||||
@@ -361,9 +347,11 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
* do custom input handling.
|
||||
*/
|
||||
protected bindEvents_() {
|
||||
Tooltip.bindMouseEvents(this.getClickTarget_());
|
||||
const clickTarget = this.getClickTarget_();
|
||||
if (!clickTarget) throw new Error('A click target has not been set.');
|
||||
Tooltip.bindMouseEvents(clickTarget);
|
||||
this.mouseDownWrapper_ = browserEvents.conditionalBind(
|
||||
this.getClickTarget_(), 'mousedown', this, this.onMouseDown_);
|
||||
clickTarget, 'mousedown', this, this.onMouseDown_);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -431,7 +419,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
* Used to see if `this` has overridden any relevant hooks.
|
||||
* @returns The stringified version of the XML state, or null.
|
||||
*/
|
||||
protected saveLegacyState(callingClass: AnyDuringMigration): string|null {
|
||||
protected saveLegacyState(callingClass: FieldProto): string|null {
|
||||
if (callingClass.prototype.saveState === this.saveState &&
|
||||
callingClass.prototype.toXml !== this.toXml) {
|
||||
const elem = utilsXml.createElement('field');
|
||||
@@ -454,7 +442,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
* @param state The state to apply to the field.
|
||||
* @returns Whether the state was applied or not.
|
||||
*/
|
||||
loadLegacyState(callingClass: AnyDuringMigration, state: AnyDuringMigration):
|
||||
loadLegacyState(callingClass: FieldProto, state: AnyDuringMigration):
|
||||
boolean {
|
||||
if (callingClass.prototype.loadState === this.loadState &&
|
||||
callingClass.prototype.fromXml !== this.fromXml) {
|
||||
@@ -491,7 +479,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
if (!this.EDITABLE || !group) {
|
||||
return;
|
||||
}
|
||||
if (this.enabled_ && this.sourceBlock_.isEditable()) {
|
||||
if (this.enabled_ && this.getSourceBlock().isEditable()) {
|
||||
dom.addClass(group, 'blocklyEditableText');
|
||||
dom.removeClass(group, 'blocklyNonEditableText');
|
||||
group.style.cursor = this.CURSOR;
|
||||
@@ -590,7 +578,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
return;
|
||||
}
|
||||
this.visible_ = visible;
|
||||
const root = this.getSvgRoot();
|
||||
const root = this.fieldGroup_;
|
||||
if (root) {
|
||||
root.style.display = visible ? 'block' : 'none';
|
||||
}
|
||||
@@ -630,10 +618,49 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
*
|
||||
* @returns The group element.
|
||||
*/
|
||||
getSvgRoot(): SVGGElement {
|
||||
getSvgRoot(): SVGGElement|null {
|
||||
return this.fieldGroup_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the border rectangle element.
|
||||
*
|
||||
* @returns The border rectangle element.
|
||||
* @throws An error if the border rectangle element is not defined.
|
||||
*/
|
||||
protected getBorderRect(): SVGRectElement {
|
||||
if (!this.borderRect_) {
|
||||
throw new Error(`The border rectangle is ${this.borderRect_}.`);
|
||||
}
|
||||
return this.borderRect_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text element.
|
||||
*
|
||||
* @returns The text element.
|
||||
* @throws An error if the text element is not defined.
|
||||
*/
|
||||
protected getTextElement(): SVGTextElement {
|
||||
if (!this.textElement_) {
|
||||
throw new Error(`The text element is ${this.textElement_}.`);
|
||||
}
|
||||
return this.textElement_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the text content.
|
||||
*
|
||||
* @returns The text content.
|
||||
* @throws An error if the text content is not defined.
|
||||
*/
|
||||
protected getTextContent(): Text {
|
||||
if (!this.textContent_) {
|
||||
throw new Error(`The text content is ${this.textContent_}.`);
|
||||
}
|
||||
return this.textContent_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the field to match the colour/style of the block. Should only be
|
||||
* called by BlockSvg.applyColour().
|
||||
@@ -726,20 +753,19 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
const constants = this.getConstants();
|
||||
const halfHeight = this.size_.height / 2;
|
||||
|
||||
// AnyDuringMigration because: Argument of type 'number' is not assignable
|
||||
// to parameter of type 'string'.
|
||||
this.textElement_.setAttribute(
|
||||
'x',
|
||||
(this.sourceBlock_.RTL ? this.size_.width - contentWidth - xOffset :
|
||||
xOffset) as AnyDuringMigration);
|
||||
// AnyDuringMigration because: Argument of type 'number' is not assignable
|
||||
// to parameter of type 'string'.
|
||||
`${
|
||||
this.getSourceBlock().RTL ?
|
||||
this.size_.width - contentWidth - xOffset :
|
||||
xOffset}`);
|
||||
this.textElement_.setAttribute(
|
||||
'y',
|
||||
(constants!.FIELD_TEXT_BASELINE_CENTER ?
|
||||
halfHeight :
|
||||
halfHeight - constants!.FIELD_TEXT_HEIGHT / 2 +
|
||||
constants!.FIELD_TEXT_BASELINE) as AnyDuringMigration);
|
||||
`${
|
||||
constants!.FIELD_TEXT_BASELINE_CENTER ?
|
||||
halfHeight :
|
||||
halfHeight - constants!.FIELD_TEXT_HEIGHT / 2 +
|
||||
constants!.FIELD_TEXT_BASELINE}`);
|
||||
}
|
||||
|
||||
/** Position a field's border rect after a size change. */
|
||||
@@ -747,24 +773,12 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
if (!this.borderRect_) {
|
||||
return;
|
||||
}
|
||||
// AnyDuringMigration because: Argument of type 'number' is not assignable
|
||||
// to parameter of type 'string'.
|
||||
this.borderRect_.setAttribute('width', `${this.size_.width}`);
|
||||
this.borderRect_.setAttribute('height', `${this.size_.height}`);
|
||||
this.borderRect_.setAttribute(
|
||||
'width', this.size_.width as AnyDuringMigration);
|
||||
// AnyDuringMigration because: Argument of type 'number' is not assignable
|
||||
// to parameter of type 'string'.
|
||||
'rx', `${this.getConstants()!.FIELD_BORDER_RECT_RADIUS}`);
|
||||
this.borderRect_.setAttribute(
|
||||
'height', this.size_.height as AnyDuringMigration);
|
||||
// AnyDuringMigration because: Argument of type 'number' is not assignable
|
||||
// to parameter of type 'string'.
|
||||
this.borderRect_.setAttribute(
|
||||
'rx',
|
||||
this.getConstants()!.FIELD_BORDER_RECT_RADIUS as AnyDuringMigration);
|
||||
// AnyDuringMigration because: Argument of type 'number' is not assignable
|
||||
// to parameter of type 'string'.
|
||||
this.borderRect_.setAttribute(
|
||||
'ry',
|
||||
this.getConstants()!.FIELD_BORDER_RECT_RADIUS as AnyDuringMigration);
|
||||
'ry', `${this.getConstants()!.FIELD_BORDER_RECT_RADIUS}`);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -810,7 +824,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
// - Webkit / Blink: fill-box / object bounding box
|
||||
// - Gecko: stroke-box
|
||||
const bBox = (this.sourceBlock_ as BlockSvg).getHeightWidth();
|
||||
const scale = (this.sourceBlock_.workspace as WorkspaceSvg).scale;
|
||||
const scale = (this.getSourceBlock().workspace as WorkspaceSvg).scale;
|
||||
xy = this.getAbsoluteXY_();
|
||||
scaledWidth = (bBox.width + 1) * scale;
|
||||
scaledHeight = (bBox.height + 1) * scale;
|
||||
@@ -896,9 +910,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
*/
|
||||
markDirty() {
|
||||
this.isDirty_ = true;
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'ConstantProvider'.
|
||||
this.constants_ = null as AnyDuringMigration;
|
||||
this.constants_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1101,7 +1113,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
*
|
||||
* @returns Element to bind click handler to.
|
||||
*/
|
||||
protected getClickTarget_(): Element {
|
||||
protected getClickTarget_(): Element|null {
|
||||
return this.clickTarget_ || this.getSvgRoot();
|
||||
}
|
||||
|
||||
@@ -1145,7 +1157,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
*/
|
||||
getParentInput(): Input {
|
||||
let parentInput = null;
|
||||
const block = this.sourceBlock_;
|
||||
const block = this.getSourceBlock();
|
||||
const inputs = block.inputList;
|
||||
|
||||
for (let idx = 0; idx < block.inputList.length; idx++) {
|
||||
@@ -1158,9 +1170,7 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
}
|
||||
}
|
||||
}
|
||||
// AnyDuringMigration because: Type 'Input | null' is not assignable to
|
||||
// type 'Input'.
|
||||
return parentInput as AnyDuringMigration;
|
||||
return parentInput!;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1199,12 +1209,13 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
*/
|
||||
setCursorSvg(cursorSvg: SVGElement) {
|
||||
if (!cursorSvg) {
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'SVGElement'.
|
||||
this.cursorSvg_ = null as AnyDuringMigration;
|
||||
this.cursorSvg_ = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.fieldGroup_) {
|
||||
throw new Error(`The field group is ${this.fieldGroup_}.`);
|
||||
}
|
||||
this.fieldGroup_.appendChild(cursorSvg);
|
||||
this.cursorSvg_ = cursorSvg;
|
||||
}
|
||||
@@ -1217,19 +1228,20 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
*/
|
||||
setMarkerSvg(markerSvg: SVGElement) {
|
||||
if (!markerSvg) {
|
||||
// AnyDuringMigration because: Type 'null' is not assignable to type
|
||||
// 'SVGElement'.
|
||||
this.markerSvg_ = null as AnyDuringMigration;
|
||||
this.markerSvg_ = null;
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this.fieldGroup_) {
|
||||
throw new Error(`The field group is ${this.fieldGroup_}.`);
|
||||
}
|
||||
this.fieldGroup_.appendChild(markerSvg);
|
||||
this.markerSvg_ = markerSvg;
|
||||
}
|
||||
|
||||
/** Redraw any attached marker or cursor svgs if needed. */
|
||||
protected updateMarkers_() {
|
||||
const workspace = this.sourceBlock_.workspace as WorkspaceSvg;
|
||||
const workspace = this.getSourceBlock().workspace as WorkspaceSvg;
|
||||
if (workspace.keyboardAccessibilityMode && this.cursorSvg_) {
|
||||
workspace.getCursor()!.draw();
|
||||
}
|
||||
@@ -1246,3 +1258,9 @@ export abstract class Field implements IASTNodeLocationSvg,
|
||||
export interface FieldConfig {
|
||||
tooltip?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* For use by Field and descendants of Field. Constructors can change
|
||||
* in descendants, though they should contain all of Field's prototype methods.
|
||||
*/
|
||||
export type FieldProto = Pick<typeof Field, 'prototype'>;
|
||||
|
||||
@@ -202,7 +202,7 @@ export class FieldAngle extends FieldTextInput {
|
||||
// #2380)
|
||||
this.symbol_ = dom.createSvgElement(Svg.TSPAN, {});
|
||||
this.symbol_.appendChild(document.createTextNode('°'));
|
||||
this.textElement_.appendChild(this.symbol_);
|
||||
this.getTextElement().appendChild(this.symbol_);
|
||||
}
|
||||
|
||||
/** Updates the graph when the field rerenders. */
|
||||
@@ -436,12 +436,12 @@ export class FieldAngle extends FieldTextInput {
|
||||
// 'Event'.
|
||||
if ((e as AnyDuringMigration).keyCode === KeyCodes.LEFT) {
|
||||
// decrement (increment in RTL)
|
||||
multiplier = this.sourceBlock_.RTL ? 1 : -1;
|
||||
multiplier = this.getSourceBlock().RTL ? 1 : -1;
|
||||
// AnyDuringMigration because: Property 'keyCode' does not exist on type
|
||||
// 'Event'.
|
||||
} else if ((e as AnyDuringMigration).keyCode === KeyCodes.RIGHT) {
|
||||
// increment (decrement in RTL)
|
||||
multiplier = this.sourceBlock_.RTL ? -1 : 1;
|
||||
multiplier = this.getSourceBlock().RTL ? -1 : 1;
|
||||
// AnyDuringMigration because: Property 'keyCode' does not exist on type
|
||||
// 'Event'.
|
||||
} else if ((e as AnyDuringMigration).keyCode === KeyCodes.DOWN) {
|
||||
|
||||
@@ -112,8 +112,9 @@ export class FieldCheckbox extends Field {
|
||||
override initView() {
|
||||
super.initView();
|
||||
|
||||
dom.addClass(this.textElement_, 'blocklyCheckbox');
|
||||
this.textElement_.style.display = this.value_ ? 'block' : 'none';
|
||||
const textElement = this.getTextElement();
|
||||
dom.addClass(textElement, 'blocklyCheckbox');
|
||||
textElement.style.display = this.value_ ? 'block' : 'none';
|
||||
}
|
||||
|
||||
override render_() {
|
||||
|
||||
@@ -191,7 +191,7 @@ export class FieldColour extends Field {
|
||||
this.getConstants()!.FIELD_COLOUR_DEFAULT_HEIGHT);
|
||||
if (!this.getConstants()!.FIELD_COLOUR_FULL_BLOCK) {
|
||||
this.createBorderRect_();
|
||||
this.borderRect_.style['fillOpacity'] = '1';
|
||||
this.getBorderRect().style['fillOpacity'] = '1';
|
||||
} else if (this.sourceBlock_ instanceof BlockSvg) {
|
||||
this.clickTarget_ = this.sourceBlock_.getSvgRoot();
|
||||
}
|
||||
|
||||
@@ -217,24 +217,24 @@ export class FieldDropdown extends Field {
|
||||
protected shouldAddBorderRect_(): boolean {
|
||||
return !this.getConstants()!.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW ||
|
||||
this.getConstants()!.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW &&
|
||||
!this.sourceBlock_.isShadow();
|
||||
!this.getSourceBlock().isShadow();
|
||||
}
|
||||
|
||||
/** Create a tspan based arrow. */
|
||||
protected createTextArrow_() {
|
||||
this.arrow_ = dom.createSvgElement(Svg.TSPAN, {}, this.textElement_);
|
||||
this.arrow_!.appendChild(document.createTextNode(
|
||||
this.sourceBlock_.RTL ? FieldDropdown.ARROW_CHAR + ' ' :
|
||||
' ' + FieldDropdown.ARROW_CHAR));
|
||||
if (this.sourceBlock_.RTL) {
|
||||
this.getSourceBlock().RTL ? FieldDropdown.ARROW_CHAR + ' ' :
|
||||
' ' + FieldDropdown.ARROW_CHAR));
|
||||
if (this.getSourceBlock().RTL) {
|
||||
// AnyDuringMigration because: Argument of type 'SVGTSpanElement | null'
|
||||
// is not assignable to parameter of type 'Node'.
|
||||
this.textElement_.insertBefore(
|
||||
this.getTextElement().insertBefore(
|
||||
this.arrow_ as AnyDuringMigration, this.textContent_);
|
||||
} else {
|
||||
// AnyDuringMigration because: Argument of type 'SVGTSpanElement | null'
|
||||
// is not assignable to parameter of type 'Node'.
|
||||
this.textElement_.appendChild(this.arrow_ as AnyDuringMigration);
|
||||
this.getTextElement().appendChild(this.arrow_ as AnyDuringMigration);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,11 +279,11 @@ export class FieldDropdown extends Field {
|
||||
dom.addClass(menuElement, 'blocklyDropdownMenu');
|
||||
|
||||
if (this.getConstants()!.FIELD_DROPDOWN_COLOURED_DIV) {
|
||||
const primaryColour = this.sourceBlock_.isShadow() ?
|
||||
this.sourceBlock_.getParent()!.getColour() :
|
||||
this.sourceBlock_.getColour();
|
||||
const borderColour = this.sourceBlock_.isShadow() ?
|
||||
(this.sourceBlock_.getParent() as BlockSvg).style.colourTertiary :
|
||||
const primaryColour = this.getSourceBlock().isShadow() ?
|
||||
this.getSourceBlock().getParent()!.getColour() :
|
||||
this.getSourceBlock().getColour();
|
||||
const borderColour = this.getSourceBlock().isShadow() ?
|
||||
(this.getSourceBlock().getParent() as BlockSvg).style.colourTertiary :
|
||||
(this.sourceBlock_ as BlockSvg).style.colourTertiary;
|
||||
if (!borderColour) {
|
||||
throw new Error(
|
||||
@@ -326,7 +326,7 @@ export class FieldDropdown extends Field {
|
||||
}
|
||||
const menuItem = new MenuItem(content, value);
|
||||
menuItem.setRole(aria.Role.OPTION);
|
||||
menuItem.setRightToLeft(this.sourceBlock_.RTL);
|
||||
menuItem.setRightToLeft(this.getSourceBlock().RTL);
|
||||
menuItem.setCheckable(true);
|
||||
menu.addChild(menuItem);
|
||||
menuItem.setChecked(value === this.value_);
|
||||
@@ -532,7 +532,7 @@ export class FieldDropdown extends Field {
|
||||
/** Draws the border with the correct width. */
|
||||
protected override render_() {
|
||||
// Hide both elements.
|
||||
this.textContent_.nodeValue = '';
|
||||
this.getTextContent().nodeValue = '';
|
||||
this.imageElement_!.style.display = 'none';
|
||||
|
||||
// Show correct element.
|
||||
@@ -590,12 +590,12 @@ export class FieldDropdown extends Field {
|
||||
this.size_.height = height;
|
||||
|
||||
let arrowX = 0;
|
||||
if (this.sourceBlock_.RTL) {
|
||||
if (this.getSourceBlock().RTL) {
|
||||
const imageX = xPadding + arrowWidth;
|
||||
this.imageElement_!.setAttribute('x', imageX.toString());
|
||||
} else {
|
||||
arrowX = imageWidth + arrowWidth;
|
||||
this.textElement_.setAttribute('text-anchor', 'end');
|
||||
this.getTextElement().setAttribute('text-anchor', 'end');
|
||||
this.imageElement_!.setAttribute('x', xPadding.toString());
|
||||
}
|
||||
this.imageElement_!.setAttribute(
|
||||
@@ -607,9 +607,10 @@ export class FieldDropdown extends Field {
|
||||
/** Renders the selected option, which must be text. */
|
||||
private renderSelectedText_() {
|
||||
// Retrieves the selected option to display through getText_.
|
||||
this.textContent_.nodeValue = this.getDisplayText_();
|
||||
dom.addClass(this.textElement_, 'blocklyDropdownText');
|
||||
this.textElement_.setAttribute('text-anchor', 'start');
|
||||
this.getTextContent().nodeValue = this.getDisplayText_();
|
||||
const textElement = this.getTextElement();
|
||||
dom.addClass(textElement, 'blocklyDropdownText');
|
||||
textElement.setAttribute('text-anchor', 'start');
|
||||
|
||||
// Height and width include the border rect.
|
||||
const hasBorder = !!this.borderRect_;
|
||||
@@ -617,7 +618,7 @@ export class FieldDropdown extends Field {
|
||||
hasBorder ? this.getConstants()!.FIELD_DROPDOWN_BORDER_RECT_HEIGHT : 0,
|
||||
this.getConstants()!.FIELD_TEXT_HEIGHT);
|
||||
const textWidth = dom.getFastTextWidth(
|
||||
this.textElement_, this.getConstants()!.FIELD_TEXT_FONTSIZE,
|
||||
this.getTextElement(), this.getConstants()!.FIELD_TEXT_FONTSIZE,
|
||||
this.getConstants()!.FIELD_TEXT_FONTWEIGHT,
|
||||
this.getConstants()!.FIELD_TEXT_FONTFAMILY);
|
||||
const xPadding =
|
||||
@@ -650,7 +651,7 @@ export class FieldDropdown extends Field {
|
||||
hasBorder ? this.getConstants()!.FIELD_BORDER_RECT_X_PADDING : 0;
|
||||
const textPadding = this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_PADDING;
|
||||
const svgArrowSize = this.getConstants()!.FIELD_DROPDOWN_SVG_ARROW_SIZE;
|
||||
const arrowX = this.sourceBlock_.RTL ? xPadding : x + textPadding;
|
||||
const arrowX = this.getSourceBlock().RTL ? xPadding : x + textPadding;
|
||||
this.svgArrow_.setAttribute(
|
||||
'transform', 'translate(' + arrowX + ',' + y + ')');
|
||||
return svgArrowSize + textPadding;
|
||||
|
||||
@@ -76,7 +76,7 @@ export class FieldLabel extends Field {
|
||||
override initView() {
|
||||
this.createTextElement_();
|
||||
if (this.class_) {
|
||||
dom.addClass(this.textElement_, this.class_);
|
||||
dom.addClass(this.getTextElement(), this.class_);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -189,8 +189,8 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
textLines += '\n';
|
||||
}
|
||||
}
|
||||
if (this.sourceBlock_.RTL) {
|
||||
// The SVG is LTR, force value to be RTL by adding an RLM.
|
||||
if (this.getSourceBlock().RTL) {
|
||||
// The SVG is LTR, force value to be RTL.
|
||||
textLines += '\u200F';
|
||||
}
|
||||
return textLines;
|
||||
@@ -248,7 +248,7 @@ export class FieldMultilineInput extends FieldTextInput {
|
||||
this.updateSize_();
|
||||
|
||||
if (this.isBeingEdited_) {
|
||||
if (this.sourceBlock_.RTL) {
|
||||
if (this.getSourceBlock().RTL) {
|
||||
// in RTL, we need to let the browser reflow before resizing
|
||||
// in order to get the correct bounding box of the borderRect
|
||||
// avoiding issue #2777.
|
||||
|
||||
@@ -133,7 +133,7 @@ export class FieldTextInput extends Field {
|
||||
let nFields = 0;
|
||||
let nConnections = 0;
|
||||
// Count the number of fields, excluding text fields
|
||||
for (let i = 0, input; input = this.sourceBlock_.inputList[i]; i++) {
|
||||
for (let i = 0, input; input = this.getSourceBlock().inputList[i]; i++) {
|
||||
for (let j = 0; input.fieldRow[j]; j++) {
|
||||
nFields++;
|
||||
}
|
||||
@@ -143,8 +143,8 @@ export class FieldTextInput extends Field {
|
||||
}
|
||||
// The special case is when this is the only non-label field on the block
|
||||
// and it has an output but no inputs.
|
||||
this.fullBlockClickTarget_ =
|
||||
nFields <= 1 && this.sourceBlock_.outputConnection && !nConnections;
|
||||
this.fullBlockClickTarget_ = nFields <= 1 &&
|
||||
this.getSourceBlock().outputConnection && !nConnections;
|
||||
} else {
|
||||
this.fullBlockClickTarget_ = false;
|
||||
}
|
||||
@@ -311,7 +311,8 @@ export class FieldTextInput extends Field {
|
||||
* @param quietInput True if editor should be created without focus.
|
||||
*/
|
||||
private showInlineEditor_(quietInput: boolean) {
|
||||
WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_.bind(this));
|
||||
WidgetDiv.show(
|
||||
this, this.getSourceBlock().RTL, this.widgetDispose_.bind(this));
|
||||
this.htmlInput_ = this.widgetCreate_() as HTMLInputElement;
|
||||
this.isBeingEdited_ = true;
|
||||
|
||||
@@ -332,7 +333,9 @@ export class FieldTextInput extends Field {
|
||||
eventUtils.setGroup(true);
|
||||
const div = WidgetDiv.getDiv();
|
||||
|
||||
dom.addClass(this.getClickTarget_(), 'editing');
|
||||
const clickTarget = this.getClickTarget_();
|
||||
if (!clickTarget) throw new Error('A click target has not been set.');
|
||||
dom.addClass(clickTarget, 'editing');
|
||||
|
||||
const htmlInput = (document.createElement('input'));
|
||||
htmlInput.className = 'blocklyHtmlInput';
|
||||
@@ -352,8 +355,8 @@ export class FieldTextInput extends Field {
|
||||
// Override border radius.
|
||||
borderRadius = (bBox.bottom - bBox.top) / 2 + 'px';
|
||||
// Pull stroke colour from the existing shadow block
|
||||
const strokeColour = this.sourceBlock_.getParent() ?
|
||||
(this.sourceBlock_.getParent() as BlockSvg).style.colourTertiary :
|
||||
const strokeColour = this.getSourceBlock().getParent() ?
|
||||
(this.getSourceBlock().getParent() as BlockSvg).style.colourTertiary :
|
||||
(this.sourceBlock_ as BlockSvg).style.colourTertiary;
|
||||
htmlInput.style.border = 1 * scale + 'px solid ' + strokeColour;
|
||||
div!.style.borderRadius = borderRadius;
|
||||
@@ -401,7 +404,9 @@ export class FieldTextInput extends Field {
|
||||
style.boxShadow = '';
|
||||
this.htmlInput_ = null;
|
||||
|
||||
dom.removeClass(this.getClickTarget_(), 'editing');
|
||||
const clickTarget = this.getClickTarget_();
|
||||
if (!clickTarget) throw new Error('A click target has not been set.');
|
||||
dom.removeClass(clickTarget, 'editing');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -516,7 +521,8 @@ export class FieldTextInput extends Field {
|
||||
|
||||
// In RTL mode block fields and LTR input fields the left edge moves,
|
||||
// whereas the right edge is fixed. Reposition the editor.
|
||||
const x = this.sourceBlock_.RTL ? bBox.right - div!.offsetWidth : bBox.left;
|
||||
const x =
|
||||
this.getSourceBlock().RTL ? bBox.right - div!.offsetWidth : bBox.left;
|
||||
const xy = new Coordinate(x, bBox.top);
|
||||
|
||||
div!.style.left = xy.x + 'px';
|
||||
|
||||
@@ -139,7 +139,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
return; // Initialization already happened.
|
||||
}
|
||||
const variable = Variables.getOrCreateVariablePackage(
|
||||
this.sourceBlock_.workspace, null, this.defaultVariableName,
|
||||
this.getSourceBlock().workspace, null, this.defaultVariableName,
|
||||
this.defaultType_);
|
||||
// Don't call setValue because we don't want to cause a rerender.
|
||||
this.doValueUpdate_(variable.getId());
|
||||
@@ -148,7 +148,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
override shouldAddBorderRect_() {
|
||||
return super.shouldAddBorderRect_() &&
|
||||
(!this.getConstants()!.FIELD_DROPDOWN_NO_BORDER_RECT_SHADOW ||
|
||||
this.sourceBlock_.type !== 'variables_get');
|
||||
this.getSourceBlock().type !== 'variables_get');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -168,7 +168,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
// AnyDuringMigration because: Argument of type 'string | null' is not
|
||||
// assignable to parameter of type 'string | undefined'.
|
||||
const variable = Variables.getOrCreateVariablePackage(
|
||||
this.sourceBlock_.workspace, id, variableName as AnyDuringMigration,
|
||||
this.getSourceBlock().workspace, id, variableName as AnyDuringMigration,
|
||||
variableType);
|
||||
|
||||
// This should never happen :)
|
||||
@@ -238,7 +238,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
}
|
||||
// This is necessary so that blocks in the flyout can have custom var names.
|
||||
const variable = Variables.getOrCreateVariablePackage(
|
||||
this.sourceBlock_.workspace, state['id'] || null, state['name'],
|
||||
this.getSourceBlock().workspace, state['id'] || null, state['name'],
|
||||
state['type'] || '');
|
||||
this.setValue(variable.getId());
|
||||
}
|
||||
@@ -316,7 +316,8 @@ export class FieldVariable extends FieldDropdown {
|
||||
return null;
|
||||
}
|
||||
const newId = opt_newValue as string;
|
||||
const variable = Variables.getVariable(this.sourceBlock_.workspace, newId);
|
||||
const variable =
|
||||
Variables.getVariable(this.getSourceBlock().workspace, newId);
|
||||
if (!variable) {
|
||||
console.warn(
|
||||
'Variable id doesn\'t point to a real variable! ' +
|
||||
@@ -343,7 +344,7 @@ export class FieldVariable extends FieldDropdown {
|
||||
*/
|
||||
protected override doValueUpdate_(newId: AnyDuringMigration) {
|
||||
this.variable_ =
|
||||
Variables.getVariable(this.sourceBlock_.workspace, newId as string);
|
||||
Variables.getVariable(this.getSourceBlock().workspace, newId as string);
|
||||
super.doValueUpdate_(newId);
|
||||
}
|
||||
|
||||
|
||||
@@ -295,7 +295,7 @@ export class Drawer {
|
||||
*/
|
||||
protected layoutField_(fieldInfo: Icon|Field) {
|
||||
const svgGroup = Types.isField(fieldInfo) ?
|
||||
(fieldInfo as Field).field.getSvgRoot() :
|
||||
(fieldInfo as Field).field.getSvgRoot()! :
|
||||
(fieldInfo as Icon).icon.iconGroup_!; // Never null in rendered case.
|
||||
|
||||
const yPos = fieldInfo.centerline - fieldInfo.height / 2;
|
||||
|
||||
@@ -247,7 +247,7 @@ export function bindMouseEvents(element: Element) {
|
||||
* @param element SVG element onto which tooltip is bound.
|
||||
* @alias Blockly.Tooltip.unbindMouseEvents
|
||||
*/
|
||||
export function unbindMouseEvents(element: Element) {
|
||||
export function unbindMouseEvents(element: Element|null) {
|
||||
if (!element) {
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user