8000 Investigate why calling field.getFocusableElement().focus() doesn't update the cursor correctly · Issue #499 · google/blockly-keyboard-experimentation · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Investigate why calling field.getFocusableElement().focus() doesn't update the cursor correctly #499

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
1 task
RoboErikG opened this issue May 7, 2025 · 5 comments
Assignees

Comments

@RoboErikG
Copy link
Contributor

Check for duplicates

  • I have searched for similar issues before opening a new one.

Description

This is causing tests that depend on programmatically focusing on a field to fail.

Reproduction steps

  1. Open up the console and set up a field variable that points at some field in the workspace.
  2. In console use setTimeout(() => {field.getFocusableElement().focus()}, 5000);
  3. Click on a different block than the one that will get focused
  4. After focus moves to the field from the timeout, press up on the keyboard
  5. See the focus jump back to where it was after clicking (moved up one)

Stack trace

Screenshots

No response

Browsers

No response

@BenHenning
Copy link
Contributor

So I looked into this, and I'm fairly certain what's happening is that focus state is definitely updating correctly, but the cursor doesn't represent this because it filters out all non-block focusables. That's obviously wrong and is from previous selection-syncing logic. We don't really see this manifest as a real problem normally because the cursor itself (or navigation logic now) will explicit set the exact next thing to go to, but this means that DOM-driven cursor changes like the one mentioned in this issue won't work.

This is a problem for all non-blocks that can be navigated to. I would say this is a non-priority to fix as it realistically should only ever effect code or tests, and code calling focus() directly probably should use FocusManager's focusNode, anyway.

For tests, it would be preferable to navigate to the field using keyboard navigation in the same way as a human (which would actually test the full flows rather than skip them like this).

That being said, it would be more correct to ensure the cursor state properly reflects the FocusManager. Doing that would require this update to LineCursor (as of google/blockly#9004):

  private updateCurNodeFromFocus() {
    const focused = getFocusManager().getFocusedNode();

    if (isNavigable(focused)) {
      // TODO: Is this needed? Is it needed for non-blocks?
      if (focused instanceof BlockSvg && focused.workspace !== this.workspace) {
        return;
      }
      this.setCurNode(focused);
    }
  }

(Note that this requires adding an isNavigable function to i_navigable.ts).

I'm unsure if the existing workspace check is really necessary. I think it logically is for the multiple workspaces situation, but it's tricky because there's no top-level way to extract a workspace from either an IFocusableNode or an INavigable.

@maribethb
Copy link
Contributor

Hopefully also a non-issue also if we get rid of the cursor keeping track of its current node anyway, since it can just ask the focus manager what's focused

@maribethb
Copy link
Contributor

The failing tests can be fixed in a different way, Ben has some suggestions above related to using focusNode instaed of focus

@BenHenning
Copy link
Contributor
BenHenning commented 8000 May 12, 2025

Sorry that's not an exact fix, that was actually just a separate thought since using DOM focus directly is a bit messier (but roughly the same behavior).

The issue is we'll need to change cursor behavior in order to sync to more than just blocks to properly fix focusing non-block nodes, otherwise we can only use keyboard navigation for navigating between things in tests.

@BenHenning BenHenning self-assigned this May 12, 2025
BenHenning added a commit to google/blockly that referenced this issue May 14, 2025
## The basics

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

## The details
### Resolves

Fixes google/blockly-keyboard-experimentation#499

### Proposed Changes

This ensures that non-blocks which hold active focus correctly update `LineCursor`'s internal state.

### Reason for Changes

This is outright a correction in how `LineCursor` has worked up until now, and is now possible after several recent changes (most notably #9004). #9004 updated selection to be more explicitly generic (and based on `IFocusableNode`) which means `LineCursor` should also properly support more than just blocks when synchronizing with focus (in place of selection), particularly since lots of non-block things can be focusable.

What's interesting is that this change isn't strictly necessary, even if it is a reasonable correction and improvement in the robustness of `LineCursor`. Essentially everywhere navigation is handled results in a call to `setCurNode` which correctly sets the cursor's internal state (with no specific correction from focus since only blocks were checked and we already ensure that selecting a block correctly focuses it).

### Test Coverage

It would be nice to add test coverage specifically for the cursor cases, but it seems largely unnecessary since:
1. The main failure cases are test-specific (as mentioned above).
2. These flows are better left tested as part of broader accessibility testing (per #8915).

This has been tested with a cursory playthrough of some basic scenarios (block movement, insertion, deletion, copy & paste, context menus, and interacting with fields).

### Documentation

No new documentation should be needed here.

### Additional Information

This is expected to only affect keyboard navigation plugin behaviors, particularly plugin tests.

It may be worth updating `LineCursor` to completely reflect current focus state rather than holding an internal variable. This, in turn, may end up simplifying solving issues like #8793 (but not necessarily).
@BenHenning
Copy link
Contributor

Fixed in google/blockly#9032. It should now be possible to use .focus() or focusNode() to correctly focus a field for continued cursor navigation.

@github-project-automation github-project-automation bot moved this from Todo to Done in Blockly Accessibility May 14, 2025
BenHenning added a commit to google/blockly that referenced this issue May 19, 2025
## The basics

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

## The details
### Resolves

Fixes google/blockly-keyboard-experimentation#526

### Proposed Changes

This limits synchronizing in `LineCursor` from `FocusManager` to just nodes that have a corresponding block.

### Reason for Changes

Limiting the synchronizing in this way ensures that navigation can't enter a bad state. The reason for why this is needed is explained in google/blockly-keyboard-experimentation#526 (comment).

Longer term it would maybe be ideal to do one or both of the following:
- Figure out ways of making navigation a bit more robust (perhaps on the keyboard navigation side) such that if cursor _is_ in a bad state there's some way to recover (rather than ending up permanently broken).
- Remove `Marker`'s internal state in favor of always relying on `FocusManager`'s state to cover the cases where there can be automatic focus shifting.

### Test Coverage

This was manually tested with the keyboard navigation plugin and verified to ensure that both google/blockly-keyboard-experimentation#526 and google/blockly-keyboard-experimentation#499 are (still) working as expected. Some basic testing was done with the core simple playground with the developer console open to ensure there weren't any expected failures.

Automated testing cases would be better addressed as part of resolving #8915.

### Documentation

No new documentation is needed here.

### Additional Information

This behavior is expected to only affect the keyboard navigation plugin.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

No branches or pull requests

3 participants
0