Skip to content

Commit

Permalink
release: v9.0.1
Browse files Browse the repository at this point in the history
Merge pull request #6573 from cpcallen/blockly-9.0.1
  • Loading branch information
cpcallen authored Oct 19, 2022
2 parents a7bff66 + c5bd54e commit 34634ea
Show file tree
Hide file tree
Showing 17 changed files with 390 additions and 179 deletions.
225 changes: 114 additions & 111 deletions blockly_compressed.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion blockly_compressed.js.map

Large diffs are not rendered by default.

10 changes: 8 additions & 2 deletions core/block_animations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ function disconnectUiStep(group: SVGElement, magnitude: number, start: Date) {
skew = `skewX(${val})`;
disconnectPid = setTimeout(disconnectUiStep, 10, group, magnitude, start);
}
group.setAttribute('transform', skew);
(group as AnyDuringMigration).skew_ = skew;
group.setAttribute(
'transform',
(group as AnyDuringMigration).translate_ +
(group as AnyDuringMigration).skew_);
}

/**
Expand All @@ -202,7 +206,9 @@ export function disconnectUiStop() {
if (disconnectPid) {
clearTimeout(disconnectPid);
}
disconnectGroup.setAttribute('transform', '');
const group = disconnectGroup;
(group as AnyDuringMigration).skew_ = '';
group.setAttribute('transform', (group as AnyDuringMigration).translate_);
disconnectGroup = null;
}
}
42 changes: 33 additions & 9 deletions core/field.ts
Original file line number Diff line number Diff line change
Expand Up @@ -255,10 +255,7 @@ export abstract class Field implements IASTNodeLocationSvg,
* @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_}.`);
}
getSourceBlock(): Block|null {
return this.sourceBlock_;
}

Expand Down Expand Up @@ -476,10 +473,11 @@ export abstract class Field implements IASTNodeLocationSvg,
/** Add or remove the UI indicating if this field is editable or not. */
updateEditable() {
const group = this.fieldGroup_;
if (!this.EDITABLE || !group) {
const block = this.getSourceBlock();
if (!this.EDITABLE || !group || !block) {
return;
}
if (this.enabled_ && this.getSourceBlock().isEditable()) {
if (this.enabled_ && block.isEditable()) {
dom.addClass(group, 'blocklyEditableText');
dom.removeClass(group, 'blocklyNonEditableText');
group.style.cursor = this.CURSOR;
Expand Down Expand Up @@ -756,7 +754,7 @@ export abstract class Field implements IASTNodeLocationSvg,
this.textElement_.setAttribute(
'x',
`${
this.getSourceBlock().RTL ?
this.getSourceBlock()?.RTL ?
this.size_.width - contentWidth - xOffset :
xOffset}`);
this.textElement_.setAttribute(
Expand Down Expand Up @@ -819,12 +817,17 @@ export abstract class Field implements IASTNodeLocationSvg,
let scaledWidth;
let scaledHeight;
let xy;
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}

if (!this.borderRect_) {
// Browsers are inconsistent in what they return for a bounding box.
// - Webkit / Blink: fill-box / object bounding box
// - Gecko: stroke-box
const bBox = (this.sourceBlock_ as BlockSvg).getHeightWidth();
const scale = (this.getSourceBlock().workspace as WorkspaceSvg).scale;
const scale = (block.workspace as WorkspaceSvg).scale;
xy = this.getAbsoluteXY_();
scaledWidth = (bBox.width + 1) * scale;
scaledHeight = (bBox.height + 1) * scale;
Expand Down Expand Up @@ -1158,6 +1161,9 @@ export abstract class Field implements IASTNodeLocationSvg,
getParentInput(): Input {
let parentInput = null;
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
const inputs = block.inputList;

for (let idx = 0; idx < block.inputList.length; idx++) {
Expand Down Expand Up @@ -1241,7 +1247,11 @@ export abstract class Field implements IASTNodeLocationSvg,

/** Redraw any attached marker or cursor svgs if needed. */
protected updateMarkers_() {
const workspace = this.getSourceBlock().workspace as WorkspaceSvg;
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
const workspace = block.workspace as WorkspaceSvg;
if (workspace.keyboardAccessibilityMode && this.cursorSvg_) {
workspace.getCursor()!.draw();
}
Expand All @@ -1264,3 +1274,17 @@ export interface FieldConfig {
* in descendants, though they should contain all of Field's prototype methods.
*/
export type FieldProto = Pick<typeof Field, 'prototype'>;

/**
* Represents an error where the field is trying to access its block or
* information about its block before it has actually been attached to said
* block.
*/
export class UnattachedFieldError extends Error {
/** @internal */
constructor() {
super(
'The field has not yet been attached to its input. ' +
'Call appendField to attach it.');
}
}
10 changes: 7 additions & 3 deletions core/field_angle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,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 {Field, UnattachedFieldError} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {FieldTextInputConfig, FieldTextInput} from './field_textinput.js';
import * as dom from './utils/dom.js';
Expand Down Expand Up @@ -430,18 +430,22 @@ export class FieldAngle extends FieldTextInput {
*/
protected override onHtmlInputKeyDown_(e: Event) {
super.onHtmlInputKeyDown_(e);
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}

let multiplier;
// AnyDuringMigration because: Property 'keyCode' does not exist on type
// 'Event'.
if ((e as AnyDuringMigration).keyCode === KeyCodes.LEFT) {
// decrement (increment in RTL)
multiplier = this.getSourceBlock().RTL ? 1 : -1;
multiplier = block.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.getSourceBlock().RTL ? -1 : 1;
multiplier = block.RTL ? -1 : 1;
// AnyDuringMigration because: Property 'keyCode' does not exist on type
// 'Event'.
} else if ((e as AnyDuringMigration).keyCode === KeyCodes.DOWN) {
Expand Down
41 changes: 28 additions & 13 deletions core/field_dropdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ goog.declareModuleId('Blockly.FieldDropdown');

import type {BlockSvg} from './block_svg.js';
import * as dropDownDiv from './dropdowndiv.js';
import {FieldConfig, Field} from './field.js';
import {FieldConfig, Field, UnattachedFieldError} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {Menu} from './menu.js';
import {MenuItem} from './menuitem.js';
Expand Down Expand Up @@ -217,16 +217,16 @@ 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.getSourceBlock().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.getSourceBlock().RTL ? FieldDropdown.ARROW_CHAR + ' ' :
' ' + FieldDropdown.ARROW_CHAR));
if (this.getSourceBlock().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.getTextElement().insertBefore(
Expand Down Expand Up @@ -258,6 +258,10 @@ export class FieldDropdown extends Field {
* undefined if triggered programmatically.
*/
protected override showEditor_(opt_e?: Event) {
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
this.dropdownCreate_();
// AnyDuringMigration because: Property 'clientX' does not exist on type
// 'Event'.
Expand All @@ -279,11 +283,10 @@ export class FieldDropdown extends Field {
dom.addClass(menuElement, 'blocklyDropdownMenu');

if (this.getConstants()!.FIELD_DROPDOWN_COLOURED_DIV) {
const primaryColour = this.getSourceBlock().isShadow() ?
this.getSourceBlock().getParent()!.getColour() :
this.getSourceBlock().getColour();
const borderColour = this.getSourceBlock().isShadow() ?
(this.getSourceBlock().getParent() as BlockSvg).style.colourTertiary :
const primaryColour =
block.isShadow() ? block.getParent()!.getColour() : block.getColour();
const borderColour = block.isShadow() ?
(block.getParent() as BlockSvg).style.colourTertiary :
(this.sourceBlock_ as BlockSvg).style.colourTertiary;
if (!borderColour) {
throw new Error(
Expand All @@ -308,6 +311,10 @@ export class FieldDropdown extends Field {

/** Create the dropdown editor. */
private dropdownCreate_() {
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
const menu = new Menu();
menu.setRole(aria.Role.LISTBOX);
this.menu_ = menu;
Expand All @@ -326,7 +333,7 @@ export class FieldDropdown extends Field {
}
const menuItem = new MenuItem(content, value);
menuItem.setRole(aria.Role.OPTION);
menuItem.setRightToLeft(this.getSourceBlock().RTL);
menuItem.setRightToLeft(block.RTL);
menuItem.setCheckable(true);
menu.addChild(menuItem);
menuItem.setChecked(value === this.value_);
Expand Down Expand Up @@ -552,6 +559,10 @@ export class FieldDropdown extends Field {
* @param imageJson Selected option that must be an image.
*/
private renderSelectedImage_(imageJson: ImageProperties) {
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
this.imageElement_!.style.display = '';
this.imageElement_!.setAttributeNS(
dom.XLINK_NS, 'xlink:href', imageJson.src);
Expand Down Expand Up @@ -590,7 +601,7 @@ export class FieldDropdown extends Field {
this.size_.height = height;

let arrowX = 0;
if (this.getSourceBlock().RTL) {
if (block.RTL) {
const imageX = xPadding + arrowWidth;
this.imageElement_!.setAttribute('x', imageX.toString());
} else {
Expand Down Expand Up @@ -646,12 +657,16 @@ export class FieldDropdown extends Field {
if (!this.svgArrow_) {
return 0;
}
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
const hasBorder = !!this.borderRect_;
const xPadding =
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.getSourceBlock().RTL ? xPadding : x + textPadding;
const arrowX = block.RTL ? xPadding : x + textPadding;
this.svgArrow_.setAttribute(
'transform', 'translate(' + arrowX + ',' + y + ')');
return svgArrowSize + textPadding;
Expand Down
14 changes: 11 additions & 3 deletions core/field_multilineinput.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import * as goog from '../closure/goog/goog.js';
goog.declareModuleId('Blockly.FieldMultilineInput');

import * as Css from './css.js';
import {Field} from './field.js';
import {Field, UnattachedFieldError} from './field.js';
import * as fieldRegistry from './field_registry.js';
import {FieldTextInputConfig, FieldTextInput} from './field_textinput.js';
import * as aria from './utils/aria.js';
Expand Down Expand Up @@ -163,6 +163,10 @@ export class FieldMultilineInput extends FieldTextInput {
* @returns Currently displayed text.
*/
protected override getDisplayText_(): string {
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
let textLines = this.getText();
if (!textLines) {
// Prevent the field from disappearing if empty.
Expand All @@ -189,7 +193,7 @@ export class FieldMultilineInput extends FieldTextInput {
textLines += '\n';
}
}
if (this.getSourceBlock().RTL) {
if (block.RTL) {
// The SVG is LTR, force value to be RTL.
textLines += '\u200F';
}
Expand All @@ -212,6 +216,10 @@ export class FieldMultilineInput extends FieldTextInput {

/** Updates the text of the textElement. */
protected override render_() {
const block = this.getSourceBlock();
if (!block) {
throw new UnattachedFieldError();
}
// Remove all text group children.
let currentChild;
while (currentChild = this.textGroup_.firstChild) {
Expand Down Expand Up @@ -248,7 +256,7 @@ export class FieldMultilineInput extends FieldTextInput {
this.updateSize_();

if (this.isBeingEdited_) {
if (this.getSourceBlock().RTL) {
if (block.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.
Expand Down
Loading

0 comments on commit 34634ea

Please sign in to comment.