Commit Graph

8941 Commits

Author SHA1 Message Date
Ben Henning
d82983f2c6 feat: Make WorkspaceSvg and BlockSvg focusable (roll forward) (#8938)
_Note: This is a roll forward of #8916 that was reverted in #8933. See Additional Information below._

## The basics

- [x] I [validated my changes](https://developers.google.com/blockly/guides/contribute/core#making_and_verifying_a_change)

## The details
### Resolves

Fixes #8913
Fixes #8914
Fixes part of #8771

### Proposed Changes

This updates `WorkspaceSvg` and `BlockSvg` to be focusable, that is, it makes the workspace a `IFocusableTree` and blocks `IFocusableNode`s.

Some important details:
- While this introduces focusable tree support for `Workspace` it doesn't include two other components that are obviously needed by the keyboard navigation plugin's playground: fields and connections. These will be introduced in subsequent PRs.
- Blocks are set up to automatically synchronize their selection state with their focus state. This will eventually help to replace `LineCursor`'s responsibility for managing selection state itself.
- The tabindex property for the workspace and its ARIA label have been moved down to the `.blocklyWorkspace` element itself rather than its wrapper. This helps address some tab stop issues that are already addressed in the plugin (via monkey patches), but also to ensure that the workspace's main SVG group interacts correctly with `FocusManager`.
- `WorkspaceSvg` is being initially set up to default to its first top block when being focused for the first time. This is to match parity with the keyboard navigation plugin, however the latter also has functionality for defaulting to a position when no blocks are present. It's not clear how to actually support this under the new focus-based system (without adding an ephemeral element on which to focus), or if it's even necessary (since the workspace root can hold focus).
- `css.ts` was updated to remove `blocklyActiveFocus` and `blocklyPassiveFocus` since these have unintended highlighting consequences that aren't actually desirable yet. Instead, the exact styling for active/passive focus will be iterated in the keyboard navigation plugin project and moved to Core once finalized.

### Reason for Changes

This is part of an ongoing effort to ensure key components of Blockly are focusable so that they can be keyboard-navigable (with other needed changes yet both in Core Blockly and the keyboard navigation plugin).

### Test Coverage

No new tests have been added. It's certainly possible to add unit tests for the focusable configurations being introduced in this PR, but it may not be highly beneficial. It's largely assumed that the individual implementations should work due to a highly tested FocusManager, and it may be the case that the interactions of the components working together is far more important to verify (that is, the end user flows). The latter is planned to be tackled as part of #8915.

### Documentation

No documentation changes should be needed here.

### Additional Information

This includes changes that have been pulled from #8875.

This was originally merged in #8916 but was reverted in #8933 due to https://github.com/google/blockly-keyboard-experimentation/issues/481. This actually contains no differences from the original PR except for `css.ts` which are documented above. It does employ a new merge strategy: all of the necessary PRs to move both Core and the plugin over to using `FocusManager` will be staged and merged in quick succession as ensuring the plugin works for each constituent change (vs. the final one) is quite complex. Thus, this PR *does* break the plugin, and won't be merged until its subsequent PRs are approved and also ready for merging.

Edit: See https://github.com/google/blockly/pull/8938#issuecomment-2843589525 for why this actually is being merged a bit sooner than originally planned. Keeping the original reasoning above for context.
2025-04-30 15:43:41 -07:00
Ben Henning
b8c2b731b7 chore: update assignment workflow permissions for v12 (#8947)
_This is a cherry-pick of #8811 into the v12 release branch._

## The basics

- [x] I [validated my changes](https://developers.google.com/blockly/guides/contribute/core#making_and_verifying_a_change)

(ish--largely relying on the original testing for this PR since it's actions-related)

## The details
### Resolves

This fixes the same issue as #8811 but on the v12 branch.

### Proposed Changes

See #8811.

### Reason for Changes

The failing assignee workflow will continue on v12 so the cherry-pick makes the next couple of PRs for this branch a bit nicer, but it's not a strong must-have since we'll eventually merge `develop` into `v12` which would then include #8811.

### Test Coverage

N/A -- There's no strong benefit from automated tests for this workflow, and it was manually tested as part of #8811 (see https://github.com/google/blockly/pull/8811#issuecomment-2822741434).

### Documentation

N/A -- No documentation changes are needed for this.

### Additional Information

None.
2025-04-30 10:51:49 -07:00
Christopher Allen
b9b40f48ab fix: Fix bug in BlockSvg.prototype.setParent (#8934)
* test(BlockSvg): Add tests for setParent(null) when dragging

  Add tests for scenarios where block(s) unrelated to the block
  being disconnected has/have been marked as as being dragged.
  Due to a bug in BlockSvg.prototype.setParent, one of these
  fails in the case that the dragging block is not a top
  block.

  Also add a check to assertNonParentAndOrphan to check that the
  orphan block's SVG root's parent is the workspace's canvass
  (i.e., that orphan is a top-level block in the DOM too).

* fix(BlockSvg): Fix bug in setParent re: dragging block

  Fix an incorrect assumption in setParent: the topmost block
  whose root SVG element has the blocklyDragging class may not
  actually be a top-level block.

* refactor(BlockDragStrategy): Hide connection preview earlier

* chore(BlockDragStrategy): prefer ?. to !.

  Per nit on PR #8934.

* fix(BlockSvg): Spelling: "canvass" -> "canvas"
2025-04-29 15:15:42 +00:00
RoboErikG
dee27b905d fix: Support RTL in WorkspaceSvg.scrollIntoBounds (#8936)
* feat: add support for RTL to scrollBoundsIntoView

* Add additional comment
2025-04-28 15:24:57 -07:00
RoboErikG
c644fe36ef Fix: Revert focus prs (#8933)
* Revert "feat: Make toolbox and flyout focusable (#8920)"

This reverts commit 5bc83808bf.

* Revert "feat: Make WorkspaceSvg and BlockSvg focusable (#8916)"

This reverts commit d7680cf32e.
2025-04-25 15:03:32 -07:00
Grace
8f59649956 fix: LineCursor can loop forward, but not back (#8926)
* fix: loop cursor when moving to prev node

* chore: add loop tests for LineCursor prev and out

* chore: fix out loop test for line cursor
2025-04-25 08:26:58 -07:00
Ben Henning
5bc83808bf feat: Make toolbox and flyout focusable (#8920)
## The basics

- [x] I [validated my changes](https://developers.google.com/blockly/guides/contribute/core#making_and_verifying_a_change)

## The details
### Resolves

Fixes #8918
Fixes #8919
Fixes part of #8771

### Proposed Changes

This updates several classes in order to make toolboxes and flyouts focusable:
- `IFlyout` is now an `IFocusableTree` with corresponding implementations in `FlyoutBase`.
- `IToolbox` is now an `IFocusableTree` with corresponding implementations in `Toolbox`.
- `IToolboxItem` is now an `IFocusableNode` with corresponding implementations in `ToolboxItem`.
- As the primary toolbox items, `ToolboxCategory` and `ToolboxSeparator` were updated to have -1 tab indexes and defined IDs to help `ToolboxItem` fulfill its contracted for `IFocusableNode.getFocusableElement`.

Each of these two new focusable trees have specific noteworthy behaviors behaviors:
- `Toolbox` will automatically indicate that its first item should be focused (if one is present), even overriding the ability to focus the toolbox's root (however there are some cases where that can still happen).
- `Toolbox` will automatically synchronize its selection state with its item nodes being focused.
- `FlyoutBase`, now being a focusable tree, has had a tab index of 0 added. Normally a tab index of -1 is all that's needed, but the keyboard navigation plugin specifically uses 0 for flyout so that the flyout is tabbable. This is a **new** tab stop being introduced.
- `FlyoutBase` holds a workspace (for rendering blocks) and, since `WorkspaceSvg` is already set up to be a focusable tree, it's represented as a subtree to `FlyoutBase`. This does introduce some wonky behaviors: the flyout's root will have passive focus while its contents have active focus. This could be manually disabled with some CSS if it ends up being a confusing user experience.
- Both `FlyoutBase` and `WorkspaceSvg` have built-in behaviors for detecting when a user tries navigating away from an open flyout to ensure that the flyout is closed when it's supposed to be. That is, the flyout is auto-hideable and a non-flyout, non-toolbox node has then been focused. This matches parity with the `T`/`Esc` flows supported in the keyboard navigation plugin playground.

One other thing to note: `Toolbox` had a few tests to update that were trying to reinit a toolbox without first disposing of it (which was caught by one of `FocusManager`'s state guardrails).

### Reason for Changes

This is part of an ongoing effort to ensure key components of Blockly are focusable so that they can be keyboard-navigable (with other needed changes yet both in Core Blockly and the keyboard navigation plugin).

### Test Coverage

No new tests have been added. It's certainly possible to add unit tests for the focusable configurations being introduced in this PR, but it may not be highly beneficial. It's largely assumed that the individual implementations should work due to a highly tested FocusManager, and it may be the case that the interactions of the components working together is far more important to verify (that is, the end user flows). The latter is planned to be tackled as part of #8915.

### Documentation

No documentation changes should be needed here.

### Additional Information

This includes changes that have been pulled from #8875.
2025-04-24 15:08:18 -07:00
Ben Henning
d7680cf32e feat: Make WorkspaceSvg and BlockSvg focusable (#8916)
## The basics

- [x] I [validated my changes](https://developers.google.com/blockly/guides/contribute/core#making_and_verifying_a_change)

## The details
### Resolves

Fixes #8913
Fixes #8914
Fixes part of #8771

### Proposed Changes

This updates `WorkspaceSvg` and `BlockSvg` to be focusable, that is, it makes the workspace a `IFocusableTree` and blocks `IFocusableNode`s.

Some important details:
- While this introduces focusable tree support for `Workspace` it doesn't include two other components that are obviously needed by the keyboard navigation plugin's playground: fields and connections. These will be introduced in subsequent PRs.
- Blocks are set up to automatically synchronize their selection state with their focus state. This will eventually help to replace `LineCursor`'s responsibility for managing selection state itself.
- The tabindex property for the workspace and its ARIA label have been moved down to the `.blocklyWorkspace` element itself rather than its wrapper. This helps address some tab stop issues that are already addressed in the plugin (via monkey patches), but also to ensure that the workspace's main SVG group interacts correctly with `FocusManager`.
- `WorkspaceSvg` is being initially set up to default to its first top block when being focused for the first time. This is to match parity with the keyboard navigation plugin, however the latter also has functionality for defaulting to a position when no blocks are present. It's not clear how to actually support this under the new focus-based system (without adding an ephemeral element on which to focus), or if it's even necessary (since the workspace root can hold focus).

### Reason for Changes

This is part of an ongoing effort to ensure key components of Blockly are focusable so that they can be keyboard-navigable (with other needed changes yet both in Core Blockly and the keyboard navigation plugin).

### Test Coverage

No new tests have been added. It's certainly possible to add unit tests for the focusable configurations being introduced in this PR, but it may not be highly beneficial. It's largely assumed that the individual implementations should work due to a highly tested FocusManager, and it may be the case that the interactions of the components working together is far more important to verify (that is, the end user flows). The latter is planned to be tackled as part of #8915.

### Documentation

No documentation changes should be needed here.

### Additional Information

This includes changes that have been pulled from #8875.
2025-04-24 14:48:16 -07:00
Ben Henning
ac7fea11cf Merge pull request #8909 from BenHenning/add-focus-manager-callbacks-and-improvements
feat!: Introduce new focus tree/node functions.
2025-04-23 14:26:57 -07:00
Ben Henning
096e7711cb chore: clean-up documentation comment. 2025-04-23 21:24:05 +00:00
Ben Henning
2564239d23 chore: Add private method documentation.
Addresses a review comment.
2025-04-23 21:22:37 +00:00
Ben Henning
e9ea69d2bd Merge branch 'rc/v12.0.0' into add-focus-manager-callbacks-and-improvements 2025-04-23 21:15:03 +00:00
Ben Henning
7c0c8536e6 fix: Fix broken FocusManager tree unregistration. 2025-04-22 00:49:52 +00:00
Aaron Dodson
c6e58c4f92 feat: Add support for displaying toast-style notifications. (#8896)
* feat: Allow resetting alert/prompt/confirm to defaults.

* chore: Add unit tests for Blockly.dialog.

* fix: Removed TEST_ONLY hack from Blockly.dialog.

* feat: Add a default toast notification implementation.

* feat: Add support for toasts to Blockly.dialog.

* chore: Add tests for default toast implementation.

* chore: Fix docstring.

* refactor: Use default arguments for dialog functions.

* refactor: Add 'close' to the list of messages.

* chore: Add new message in several other places.

* chore: clarify docstrings.

* feat: Make toast assertiveness configurable.
2025-04-21 15:32:45 -07:00
Ben Henning
4e8bb9850f Revert "chore: Remove unused isFocusable*() functions."
This reverts commit 404c20eeaf.
2025-04-21 21:09:26 +00:00
Ben Henning
c91fed3fdb chore: equality + doc cleanups 2025-04-21 21:00:27 +00:00
Ben Henning
404c20eeaf chore: Remove unused isFocusable*() functions.
These were needed in previous versions of plugin changes, but aren't
anymore.
2025-04-21 20:55:02 +00:00
Ben Henning
0772a29824 feat!: Introduce new focus tree/node functions.
This introduces new callback methods for IFocusableTree and
IFocusableNode for providing a basis of synchronizing domain state with
focus changes. It also introduces support for implementations of
IFocusableTree to better manage initial state cases, especially when a
tree is focused using tab navigation.

FocusManager has also been updated to ensure functional parity between
tab-navigating to a tree and using focusTree() on that tree. This means
that tab navigating to a tree will actually restore focus back to that
tree's previous focused node rather than the root (unless the root is
navigated to from within the tree itself). This is meant to provide
better consistency between tab and non-tab keyboard navigation.

Note that these changes originally came from #8875 and are required for
later PRs that will introduce IFocusableNode and IFocusableTree
implementations.
2025-04-21 20:42:28 +00:00
Aaron Dodson
9d127698d6 fix: Add some missing message strings. (#8908)
* fix: Add some missing message strings.

* fix: Prefix messages with SHORTCUTS
2025-04-21 10:44:57 -07:00
Aaron Dodson
cece3f6296 chore: Add messages from the keyboard experiment. (#8904)
* chore: Add messages from the keyboard experiment.

* fix: Resolve duplicate message ID.

* fix: Use placeholders for keyboard shortcuts.
2025-04-21 08:54:39 -07:00
Aaron Dodson
4fb054c484 fix: Recreate the dropdowndiv when clearing it. (#8903) 2025-04-18 12:21:52 -07:00
Aaron Dodson
5b103e1d79 fix: Fix bug that caused flyout items under the mouse to be selected without movement. (#8900) 2025-04-17 15:39:04 -07:00
Aaron Dodson
296ad33c21 fix: Fix bug that allowed some invisible fields/inputs to be navigated to. (#8899) 2025-04-17 09:48:17 -07:00
Maribeth Moffatt
d63a8882c5 feat: show context menu for connections (#8895)
* feat: show context menu for connections

* fix: update after rebase
2025-04-16 10:48:18 -07:00
Aaron Dodson
fd9263ac51 feat: Allow for HTML elements in dropdown field menus. (#8889)
* feat: Allow for HTML elements in dropdown field menus.

* refactor: Use dot access.
2025-04-15 14:34:38 -07:00
Maribeth Moffatt
acca9ea83f feat!: deprecate scopeType and include focusedNode in context menu options (#8882)
* feat!: deprecate scopeType and include focusedNode in context menu options

* chore: add issue to todo
2025-04-15 11:24:01 -07:00
Aaron Dodson
b1d7670a6e release: Update version number to 12.0.0-beta.4 blockly-v12.0.0-beta.4 2025-04-14 15:09:07 -07:00
Aaron Dodson
e45471d6f4 fix: Fix menu scrolling. (#8881) 2025-04-14 13:56:46 -07:00
Aaron Dodson
98cf5cb8ee feat: Add support for retrieving blocks' drag strategies. (#8893) 2025-04-14 13:54:15 -07:00
Aaron Dodson
7a3eb62142 fix: Don't visit invisible inputs with the cursor. (#8892) 2025-04-14 13:20:33 -07:00
Maribeth Moffatt
547fed4c6b feat: menuOpenEvent, menuSelectEvent, and location for context menu items
feat: menuOpenEvent, menuSelectEvent, and location for context menu items
2025-04-14 12:37:49 -07:00
Maribeth Moffatt
e0009e257c fix: update dependencies so adv compilation works (#8890) 2025-04-14 12:16:40 -07:00
Rachel Fenichel
fac75043dd feat: add loopback in cursor navigation, and add tests (#8883)
* chore: tests for cursor getNextNode

* chore: add tests for getPreviousNode

* feat: add looping to getPreviousNode and getNextNode

* chore: inline returns

* chore: fix test that results in a stack node

* chore: fix annotations
2025-04-14 09:58:58 -07:00
Maribeth Moffatt
d1dc38f582 feat: support menuOpenEvent, menuSelectEvent, location for context menu items (#8877)
* feat: support menuOpenEvent, menuSelectEvent, location for context menu items

* feat: show context menu based on location

* fix: rtl
2025-04-11 15:10:05 -07:00
Rachel Fenichel
3160e3d321 feat: add getFirstNode and getLastNode to cursor with tests (#8878)
* feat: add getFirstNode and getlastNode to line_cursor.ts

* chore: add simple tests for getFirstNode and getLastNode

* chore: broken tests for debugging

* chore: additional cursor tests

* chore: lint, format, reenable tasks
2025-04-11 10:13:10 -07:00
Maribeth Moffatt
c5736bba65 feat: make block and workspace implement IContextMenu (#8876) 2025-04-10 10:34:35 -07:00
Maribeth Moffatt
7aff866944 release: update version to 12.0.0-beta.3 blockly-v12.0.0-beta.3 2025-04-08 12:17:58 -07:00
Maribeth Moffatt
2c05119ef2 fix: change css class for disabled block pattern (#8864) 2025-04-08 12:06:05 -07:00
Maribeth Moffatt
89194b2ead fix: check potential variables for flyout variable fields (#8873)
* fix: check potential variables for flyout variable fields

* fix: format

* chore: move comment
2025-04-07 17:29:00 -07:00
Rachel Fenichel
76b02de654 feat: add getSearchRadius to BlockDragStrategy (#8871) 2025-04-07 13:52:15 -07:00
Rachel Fenichel
49387ec788 feat: add shouldHealStack method (#8872)
* feat: add shouldHealStack method

* chore: format
2025-04-07 12:44:40 -07:00
Ben Henning
17171abf1c Merge pull request #8814 from BenHenning/introduce-focus-system-implementation
feat: Introduce FocusManager implementation
2025-04-03 16:20:49 -07:00
Ben Henning
c5404af82e chore: lint fixes. 2025-04-03 23:04:06 +00:00
Rachel Fenichel
58cd954fc0 feat: make getNextNode and getPreviousNode public (#8859) 2025-04-03 22:59:34 +00:00
Ben Henning
720e8dab2b chore: part 2 of addressing reviewer comments. 2025-04-03 22:55:35 +00:00
Ben Henning
902b26b1a1 chore: part 1 of addressing reviewer comments. 2025-04-03 22:25:50 +00:00
Aaron Dodson
ca362725ee refactor!: Backport LineCursor to core. (#8834)
* refactor: Backport LineCursor to core.

* fix: Fix instantiation of LineCursor.

* fix: Fix tests.

* chore: Assauge the linter.

* chore: Fix some typos.

* feat: Make padding configurable for scrollBoundsIntoView.

* chore: Merge in the latest changes from keyboard-experimentation.

* refactor: Clarify name and docs for findSiblingOrParentSibling().

* fix: Improve scrollBoundsIntoView() behavior.

* fix: Export CursorOptions.

* refactor: Further clarify second parameter of setCurNode().

* fix: Revert change that could prevent scrolling bounds into view.
2025-04-03 12:15:17 -07:00
Aaron Dodson
7171350992 fix!: Tighten and correct typings on ASTNode (#8835)
* fix!: Tighten typings on ASTNode.create*Node() methods.

* fix: Restore missing condition.

* fix: Fix unsafe casts, non-null assertions and incorrect types.

* refactor: Simplify parent input checks.
2025-04-01 14:59:40 -07:00
Aaron Dodson
7a07b4b2ba refactor!: Remove old cursor and tab support. (#8803) 2025-03-28 13:54:33 -07:00
Ben Henning
3dc4d17b30 Update tests/mocha/index.html 2025-03-27 16:54:19 -07:00