feat!: Make everything ISelectable focusable (#9004)

* feat!: Make bubbles, comments, and icons focusable

* feat!: Make ISelectable and ICopyable focusable.

* feat: Consolidate selection calls.

Now everything is based on focus with selection only being used as a
proxy.

* feat: Invert responsibility for setSelected().

Now setSelected() is only for quasi-external use.

* feat: Push up shadow check to getters.

Needed new common-level helper.

* chore: Lint fixes.

* feat!: Allow IFocusableNode to disable focus.

* chore: post-merge lint fixes

* fix: Fix tests + text bubble focusing.

This fixed then regressed a circular dependency causing the node and
advanced compilation steps to fail. This investigation is ongoing.

* fix: Clean up & fix imports.

This ensures the node and advanced compilation test steps now pass.

* fix: Lint fixes + revert commented out logic.

* chore: Remove unnecessary cast.

Addresses reviewer comment.

* fix: Some issues and a bunch of clean-ups.

This addresses a bunch of review comments, and fixes selecting workspace
comments.

* chore: Lint fix.

* fix: Remove unnecessary shadow consideration.

* chore: Revert import.

* chore: Some doc updates & added a warn statement.
This commit is contained in:
Ben Henning
2025-05-09 08:16:14 -07:00
committed by GitHub
parent 92cad53cfe
commit 4074cee31b
34 changed files with 380 additions and 209 deletions

View File

@@ -13,7 +13,6 @@
import type {Block} from './block.js';
import type {BlockSvg} from './block_svg.js';
import * as common from './common.js';
import {config} from './config.js';
import {Connection} from './connection.js';
import type {ConnectionDB} from './connection_db.js';
@@ -198,15 +197,12 @@ export class RenderedConnection
? inferiorRootBlock
: superiorRootBlock;
// Raise it to the top for extra visibility.
const selected = common.getSelected() === dynamicRootBlock;
if (!selected) dynamicRootBlock.addSelect();
if (dynamicRootBlock.RTL) {
offsetX = -offsetX;
}
const dx = staticConnection.x + offsetX - dynamicConnection.x;
const dy = staticConnection.y + offsetY - dynamicConnection.y;
dynamicRootBlock.moveBy(dx, dy, ['bump']);
if (!selected) dynamicRootBlock.removeSelect();
}
/**
@@ -559,21 +555,6 @@ export class RenderedConnection
childBlock.updateDisabled();
childBlock.queueRender();
// If either block being connected was selected, visually un- and reselect
// it. This has the effect of moving the selection path to the end of the
// list of child nodes in the DOM. Since SVG z-order is determined by node
// order in the DOM, this works around an issue where the selection outline
// path could be partially obscured by a new block inserted after it in the
// DOM.
const selection = common.getSelected();
const selectedBlock =
(selection === parentBlock && parentBlock) ||
(selection === childBlock && childBlock);
if (selectedBlock) {
selectedBlock.removeSelect();
selectedBlock.addSelect();
}
// The input the child block is connected to (if any).
const parentInput = parentBlock.getInputWithBlock(childBlock);
if (parentInput) {
@@ -671,6 +652,11 @@ export class RenderedConnection
this.unhighlight();
}
/** See IFocusableNode.canBeFocused. */
canBeFocused(): boolean {
return true;
}
private findHighlightSvg(): SVGElement | null {
// This cast is valid as TypeScript's definition is wrong. See:
// https://github.com/microsoft/TypeScript/issues/60996.