## The basics
- [x] I [validated my changes](https://developers.google.com/blockly/guides/contribute/core#making_and_verifying_a_change)
## The details
### Resolves
Fixes#8930
Fixes part of #8771
### Proposed Changes
This PR introduces support for connections to be focusable (and thus navigable with keyboard navigation when paired with downstream changes to `LineCursor` and the keyboard navigation plugin). This is a largely isolated change in how it fundamentally works:
- `RenderedConnection` has been updated to be an `IFocusableNode` using a new unique ID maintained by `Connection` and automatically enabling/disabling the connection highlight based on whether it's focused (per keyboard navigation).
- The way that rendering works here has changed: rather than recreating the connection's highlight SVG each time, it's only created once and updated thereafter to ensure that it correctly fits block resizes or movements. Visibility of the highlight is controlled entirely through display visibility and can now be done synchronously (which was a requirement for focusability as only displayed elements can be focused).
- This employs the same type of ID schema strategy as fields in #8923.
### 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.
_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#8913Fixes#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.
* Revert "feat: Make toolbox and flyout focusable (#8920)"
This reverts commit 5bc83808bf.
* Revert "feat: Make WorkspaceSvg and BlockSvg focusable (#8916)"
This reverts commit d7680cf32e.
## The basics
- [x] I [validated my changes](https://developers.google.com/blockly/guides/contribute/core#making_and_verifying_a_change)
## The details
### Resolves
Fixes#8913Fixes#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.
* refactor(events): Use "export ... from" where applicable
* refactor(events): Introduce EventType enum
Introduce an enum for the event .type values. We can't actually
use it as the type of the .type property on Abstract events,
because we want to allow developers to add their own custom
event types inheriting from this type, but at least this way we
can be reasonably sure that all of our own event subclasses have
distinct .type values—plus consistent use of enum syntax
(EventType.TYPE_NAME) is probably good for readability overall.
Put it in a separate module from the rest of events/utils.ts
because it would be helpful if event utils could use
event instanceof SomeEventType
for type narrowing but but at the moment most events are in
modules that depend on events/utils.ts for their .type
constant, and although circular ESM dependencies should work
in principle there are various restrictions and this
particular circularity causes issues at the moment.
A few of the event classes also depend on utils.ts for fire()
or other functions, which will be harder to deal with, but at
least this commit is win in terms of reducing the complexity
of our dependencies, making most of the Abstract event subclass
module dependent on type.ts, which has no imports, rather than
on utils.ts which has multiple imports.
* chore(deps): Add pretter-plugin-organize-imports
* chore: Remove insignificant blank lines in import sections
Since prettier-plugin-organize-imports sorts imports within
sections separated by blank lines, but preserves the section
divisions, remove any blank lines that are not dividing imports
into meaningful sections.
Do not remove blank lines separating side-effect-only imports
from main imports.
* chore: Remove unneded eslint-disable directives
* chore: Organise imports
* feat: allow fetching block bounds not including children.
* chore: run formatter.
* chore: run the other formatter.
* fix: don't include subsequent blocks in the childless bounding rect.
* chore: remove logging.
* Setting style property to make CSP less grumpy.
"Content-Security-Policy: The page’s settings blocked the loading of a resource at inline (“style-src”)."
The 'style' property should be set as an object, not as a string, according to CSP rules.
Back-ported from Blockly Games.
* fix(build): Restore erroneously-deleted filter function
This was deleted in PR #7406 as it was mainly being used to
filter core/ vs. test/mocha/ deps into separate deps files -
but it turns out also to be used for filtering error
messages too. Oops.
* refactor(tests): Migrate advanced compilation test to ES Modules
* refactor(build): Migrate main.js to TypeScript
This turns out to be pretty straight forward, even if it would
cause crashing if one actually tried to import this module
instead of just feeding it to Closure Compiler.
* chore(build): Remove goog.declareModuleId calls
Replace goog.declareModuleId calls with a comment recording the
former module ID for posterity (or at least until we decide
how to reformat the renamings file.
* chore(tests): Delete closure/goog/*
For the moment we still need something to serve as base.js for
the benefit of closure-make-deps, so we keep a vestigial
base.js around, containing only the @provideGoog declaration.
* refactor(build): Remove vestigial base.js
By changing slightly the command line arguments to
closure-make-deps and closure-calculate-chunks the need to have
any base.js is eliminated.
* chore: Typo fix for PR #7415
* feat: Parse message newlines as endOfRow dummies.
* Fix the multilineinput field test.
* Addressing PR feedback.
* Addressing PR feedback.
* Newline parsing now uses a new custom input.
* npm run format
* Added input_end_row to block factory.
* Addres feedback, fix endrow after external value.
* fix: input exports
* chore: fix build
* chore: attempt to fix build
* chore: attempt to fix build
* chore: create new align enum to replace old one
* chore: format
* fix: Tweak renamings entries
It appears that the goal is to map:
Blockly.Input.Align -> Blockly.inputs.Align
Blockly.Align -> Blockly.inputs.Align
Blockly.ALIGN_* -> Blockly.inputs.Align.*
I believe this commit achieves that in a more minimal (and correct)
way—but if I have misunderstood the intention then this will not
be a useful correction.
---------
Co-authored-by: Christopher Allen <cpcallen+git@google.com>