diff --git a/package.json b/package.json index 85b3363cf9f2..862f548d4968 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,7 @@ "@zip.js/zip.js": "2.4.20", "adm-zip": "^0.5.12", "axios": "^1.12.2", - "blockly": "13.0.0-beta.8", + "blockly": "13.0.0-beta.9", "browserify": "17.0.0", "chai": "^3.5.0", "chalk": "^4.1.2", @@ -151,10 +151,10 @@ }, "overrides": { "@blockly/field-grid-dropdown": { - "blockly": "13.0.0-beta.8" + "blockly": "13.0.0-beta.9" }, "@blockly/plugin-workspace-search": { - "blockly": "13.0.0-beta.8" + "blockly": "13.0.0-beta.9" }, "combine-source-map": { "source-map": "0.4.4" diff --git a/pxtblocks/builtins/functions.ts b/pxtblocks/builtins/functions.ts index 3a24c63a10ea..a24b54bf6d9c 100644 --- a/pxtblocks/builtins/functions.ts +++ b/pxtblocks/builtins/functions.ts @@ -7,7 +7,7 @@ import { FieldProcedure } from "../fields"; import { cachedBlockInfo, setOutputCheck } from "../loader"; import { domToWorkspaceNoEvents } from "../importer"; import { FieldImageNoText } from "../fields/field_imagenotext"; -import { maybeFocusMutatorButton } from "../utils"; +import { maybeMoveFocusFromButton } from "../utils"; export function initFunctions() { const msg = Blockly.Msg; @@ -356,7 +356,7 @@ function initReturnStatement(b: Blockly.Block) { b.setInputsInline(true); if (userTriggered) { - maybeFocusMutatorButton(buttonToFocus?.fieldRow[0]); + maybeMoveFocusFromButton(buttonToFocus?.fieldRow[0]); } } diff --git a/pxtblocks/composableMutations.ts b/pxtblocks/composableMutations.ts index 5706ad690765..43176773ad21 100644 --- a/pxtblocks/composableMutations.ts +++ b/pxtblocks/composableMutations.ts @@ -9,7 +9,7 @@ import { DRAGGABLE_PARAM_INPUT_PREFIX, getBlocklyCheckForType, setVarFieldValue import { UpdateBeforeRenderMixin } from "./plugins/renderer"; import { FieldImageNoText } from "./fields/field_imagenotext"; import { setDuplicateOnDrag } from "./plugins/duplicateOnDrag"; -import { maybeFocusMutatorButton } from "./utils"; +import { maybeMoveFocusFromButton } from "./utils"; export interface ComposableMutation { // Set to save mutations. Should return an XML element @@ -69,7 +69,7 @@ export function initVariableArgsBlock(b: Blockly.Block, handlerArgs: pxt.blocks. if (currentlyVisible >= handlerArgs.length) { i.removeField("_HANDLER_ADD"); if (userTriggered) { - maybeFocusMutatorButton(fieldToFocus); + maybeMoveFocusFromButton(fieldToFocus); } } else if (actuallyVisible >= handlerArgs.length) { @@ -269,7 +269,7 @@ export function initExpandableBlock(info: pxtc.BlocksInfo, b: Blockly.Block, def if (buttonToFocus.fieldRow.length > 1) { field = delta < 0 ? field : buttonToFocus.fieldRow[1]; } - maybeFocusMutatorButton(field); + maybeMoveFocusFromButton(field); buttonToFocus = null; } }); @@ -503,7 +503,7 @@ export function initVariableReporterArgs(b: Blockly.Block, handlerArgs: pxt.bloc setTimeout(() => { populateArguments(); if (userTriggered && handlerArgs.length === state.getNumber(numVisibleAttr)) { - maybeFocusMutatorButton(inputToFocus.connection?.targetBlock() as Blockly.BlockSvg) + maybeMoveFocusFromButton(inputToFocus.connection?.targetBlock() as Blockly.BlockSvg) } }, 0); } diff --git a/pxtblocks/monkeyPatches/blockSvg.ts b/pxtblocks/monkeyPatches/blockSvg.ts index ef6815928288..76aacacd2c3d 100644 --- a/pxtblocks/monkeyPatches/blockSvg.ts +++ b/pxtblocks/monkeyPatches/blockSvg.ts @@ -1,7 +1,7 @@ import * as Blockly from "blockly"; import { FieldImageNoText } from "../fields/field_imagenotext"; import { ConstantProvider } from "../plugins/renderer/constants"; -import { maybeFocusMutatorButton } from "../utils"; +import { maybeMoveFocusFromButton } from "../utils"; export function monkeyPatchBlockSvg() { const oldSetCollapsed = Blockly.BlockSvg.prototype.setCollapsed; @@ -17,8 +17,10 @@ export function monkeyPatchBlockSvg() { if (image) { input.appendField(new FieldImageNoText(image, 24, 24, lf("Expand block"), () => { this.setCollapsed(false); + // Functions keep focus on their collapse button; other blocks + // have no such button so focus the block itself instead. const collapseBtn = this.inputList.find(i => i.name === "function_collapse")?.fieldRow[0]; - maybeFocusMutatorButton(collapseBtn); + maybeMoveFocusFromButton(collapseBtn ?? this); }, false)); } } diff --git a/pxtblocks/plugins/arrays/createList.ts b/pxtblocks/plugins/arrays/createList.ts index 92c15b51b711..bee9fbb7d823 100644 --- a/pxtblocks/plugins/arrays/createList.ts +++ b/pxtblocks/plugins/arrays/createList.ts @@ -3,7 +3,7 @@ import { FUNCTION_CALL_OUTPUT_BLOCK_TYPE } from "../functions/constants"; import { CommonFunctionBlock } from "../functions/commonFunctionMixin"; import { InlineSvgsExtensionBlock } from "../functions"; import { FieldImageNoText } from "../../fields/field_imagenotext"; -import { maybeFocusMutatorButton } from "../../utils"; +import { maybeMoveFocusFromButton } from "../../utils"; type ListCreateMixinType = typeof LIST_CREATE_MIXIN; @@ -188,7 +188,7 @@ const LIST_CREATE_MIXIN = { if (this.buttons.fieldRow.length > 1) { field = this.delta < 0 ? field : this.buttons.fieldRow[1]; } - maybeFocusMutatorButton(field); + maybeMoveFocusFromButton(field); this.buttons = null; this.delta = 0; } diff --git a/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts b/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts index 9d567ac333ae..5f1d2ddb8192 100644 --- a/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts +++ b/pxtblocks/plugins/functions/blocks/functionDefinitionBlock.ts @@ -23,7 +23,7 @@ import { COLLAPSE_IMAGE_DATAURI } from "../svgs"; import { ArgumentReporterBlock } from "./argumentReporterBlocks"; import { setDuplicateOnDrag } from "../../duplicateOnDrag"; import { FieldImageNoText } from "../../../fields/field_imagenotext"; -import { maybeFocusMutatorButton } from "../../../utils"; +import { maybeMoveFocusFromButton } from "../../../utils"; interface FunctionDefinitionMixin extends CommonFunctionMixin { createArgumentReporter_(arg: FunctionArgument): ArgumentReporterBlock; @@ -203,7 +203,7 @@ Blockly.Blocks[FUNCTION_DEFINITION_BLOCK_TYPE] = { () => { this.setCollapsed(true); const expandBtn = this.inputList.find(i => i.name === Blockly.constants.COLLAPSED_INPUT_NAME)?.fieldRow[1]; - maybeFocusMutatorButton(expandBtn); + maybeMoveFocusFromButton(expandBtn); }, false ) diff --git a/pxtblocks/plugins/logic/ifElse.ts b/pxtblocks/plugins/logic/ifElse.ts index a2cb8420fa4c..fad58b3fd6ff 100644 --- a/pxtblocks/plugins/logic/ifElse.ts +++ b/pxtblocks/plugins/logic/ifElse.ts @@ -1,7 +1,7 @@ import * as Blockly from "blockly"; import { InlineSvgsExtensionBlock } from "../functions"; import { FieldImageNoText } from "../../fields/field_imagenotext"; -import { maybeFocusMutatorButton } from "../../utils"; +import { maybeMoveFocusFromButton } from "../../utils"; type IfElseMixinType = typeof IF_ELSE_MIXIN; @@ -88,7 +88,7 @@ const IF_ELSE_MIXIN = { // Focus the condition of the last elseif branch, fallback to the condition of the if. const focusIndex = this.elseifCount_; const inputName = 'IF' + focusIndex; - maybeFocusMutatorButton(this.getInput(inputName)?.connection?.targetBlock() as Blockly.BlockSvg); + maybeMoveFocusFromButton(this.getInput(inputName)?.connection?.targetBlock() as Blockly.BlockSvg); }, addElseIf_: function (this: IfElseBlock) { Blockly.utils.aria.announceDynamicAriaState(pxt.Util.lf("Else if branch added.")); @@ -106,7 +106,7 @@ const IF_ELSE_MIXIN = { // Focus the condition of the branch before the one just removed. const prevIndex = arg - 1; const inputName = 'IF' + prevIndex; - maybeFocusMutatorButton(this.getInput(inputName)?.connection?.targetBlock() as Blockly.BlockSvg); + maybeMoveFocusFromButton(this.getInput(inputName)?.connection?.targetBlock() as Blockly.BlockSvg); }, update_: function (this: IfElseBlock, update: () => void, arg?: number) { Blockly.Events.setGroup(true); @@ -196,7 +196,7 @@ const IF_ELSE_MIXIN = { if (that.elseCount_ == 0) { that.addElse_(); // Focus the else 'remove branch' button (keyboard users only). - maybeFocusMutatorButton(that.getInput('ELSEBUTTONS')?.fieldRow[0]); + maybeMoveFocusFromButton(that.getInput('ELSEBUTTONS')?.fieldRow[0]); } else { if (!that.elseifCount_) that.elseifCount_ = 0; that.addElseIf_(); diff --git a/pxtblocks/plugins/text/join.ts b/pxtblocks/plugins/text/join.ts index 061657bf020b..d1b4e8ade1db 100644 --- a/pxtblocks/plugins/text/join.ts +++ b/pxtblocks/plugins/text/join.ts @@ -1,7 +1,7 @@ import * as Blockly from "blockly"; import { InlineSvgsExtensionBlock } from "../functions"; import { FieldImageNoText } from "../../fields/field_imagenotext"; -import { maybeFocusMutatorButton } from "../../utils"; +import { maybeMoveFocusFromButton } from "../../utils"; type TextJoinMixinType = typeof TEXT_JOIN_MUTATOR_MIXIN; @@ -108,7 +108,7 @@ const TEXT_JOIN_MUTATOR_MIXIN = { if (this.buttons.fieldRow.length > 1) { field = this.delta < 0 ? field : this.buttons.fieldRow[1]; } - maybeFocusMutatorButton(field); + maybeMoveFocusFromButton(field); this.buttons = null; this.delta = 0; } diff --git a/pxtblocks/utils.ts b/pxtblocks/utils.ts index 328b69909601..dc99c3f786c0 100644 --- a/pxtblocks/utils.ts +++ b/pxtblocks/utils.ts @@ -1,7 +1,11 @@ import * as Blockly from "blockly"; import { FieldImageNoText } from "./fields/field_imagenotext"; -export const maybeFocusMutatorButton = (node: Blockly.IFocusableNode | undefined): void => { +// Moves focus to the given node, but only when focus currently sits on one of +// our FieldImageNoText buttons (the +/-/expand/collapse icons) or nowhere. This +// keeps focus sensible after such a button re-renders away the element that had +// focus, without stealing focus if it has moved elsewhere. +export const maybeMoveFocusFromButton = (node: Blockly.IFocusableNode | undefined): void => { const focusManager = Blockly.getFocusManager(); const currentlyFocusedNode = focusManager.getFocusedNode(); if ( @@ -10,4 +14,4 @@ export const maybeFocusMutatorButton = (node: Blockly.IFocusableNode | undefined ) { focusManager.focusNode(node); } -} \ No newline at end of file +} diff --git a/webapp/src/blocks.tsx b/webapp/src/blocks.tsx index a66955cfde8f..e464b5d1bf6f 100644 --- a/webapp/src/blocks.tsx +++ b/webapp/src/blocks.tsx @@ -705,11 +705,6 @@ export class Editor extends toolboxeditor.ToolboxEditor { if (focused instanceof Blockly.BlockSvg && shouldDuplicateOnDrag(focused)) { return !workspace.isReadOnly() && !workspace.isDragging(); } - // Workaround: https://github.com/RaspberryPiFoundation/blockly/issues/9963 - if (focused instanceof Blockly.BlockSvg && focused.isShadow()) { - workspace.getAudioManager().playErrorBeep(); - return false; - } return disconnectShortcut.preconditionFn!(workspace, scope); }, callback: (workspace, e, shortcut, scope) => {