Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/blockly/core/component_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import type {IAutoHideable} from './interfaces/i_autohideable.js';
import type {IComponent} from './interfaces/i_component.js';
import type {IDeleteArea} from './interfaces/i_delete_area.js';
import type {IDragTarget} from './interfaces/i_drag_target.js';
import type {IFocusableNode} from './interfaces/i_focusable_node.js';
import type {IPositionable} from './interfaces/i_positionable.js';
import * as arrayUtils from './utils/array.js';

Expand All @@ -23,6 +24,7 @@ class Capability<_T> {
static DRAG_TARGET = new Capability<IDragTarget>('drag_target');
static DELETE_AREA = new Capability<IDeleteArea>('delete_area');
static AUTOHIDEABLE = new Capability<IAutoHideable>('autohideable');
static FOCUSABLE = new Capability<IFocusableNode>('focusable');
private readonly name: string;
/** @param name The name of the component capability. */
constructor(name: string) {
Expand Down
14 changes: 3 additions & 11 deletions packages/blockly/core/trashcan.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {EventType} from './events/type.js';
import * as eventUtils from './events/utils.js';
import {getFocusManager} from './focus_manager.js';
import type {IAutoHideable} from './interfaces/i_autohideable.js';
import type {IComponent} from './interfaces/i_component';
import type {IDraggable} from './interfaces/i_draggable.js';
import type {IFlyout} from './interfaces/i_flyout.js';
import type {IFocusableNode} from './interfaces/i_focusable_node.js';
Expand Down Expand Up @@ -49,7 +50,7 @@ import type {WorkspaceSvg} from './workspace_svg.js';
*/
export class Trashcan
extends DeleteArea
implements IAutoHideable, IPositionable, IFocusableNode
implements IAutoHideable, IPositionable, IFocusableNode, IComponent
{
/**
* The id for this component that is used to register with the
Expand Down Expand Up @@ -269,6 +270,7 @@ export class Trashcan
ComponentManager.Capability.DELETE_AREA,
ComponentManager.Capability.DRAG_TARGET,
ComponentManager.Capability.POSITIONABLE,
ComponentManager.Capability.FOCUSABLE,
],
});
this.initialized = true;
Expand Down Expand Up @@ -659,16 +661,6 @@ export class Trashcan
performAction() {
this.click();
}

/**
* Retrieves the globally unique ID of this Trashcan instance. Used for focus
* management.
*
* @internal
*/
getGloballyUniqueId() {
return this.uniqueId;
}
}

/** Width of both the trash can and lid images. */
Expand Down
13 changes: 8 additions & 5 deletions packages/blockly/core/workspace_svg.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import * as hints from './hints.js';
import {MutatorIcon} from './icons/mutator_icon.js';
import {isAutoHideable} from './interfaces/i_autohideable.js';
import type {IBoundedElement} from './interfaces/i_bounded_element.js';
import type {IComponent} from './interfaces/i_component.js';
import {IContextMenu} from './interfaces/i_contextmenu.js';
import type {IDragTarget} from './interfaces/i_drag_target.js';
import type {IFlyout} from './interfaces/i_flyout.js';
Expand Down Expand Up @@ -2961,13 +2962,15 @@ export class WorkspaceSvg
}
}

if (this.trashcan?.getGloballyUniqueId() === id) {
return this.trashcan;
const focusableComponents = this.getComponentManager().getComponents<
IFocusableNode & IComponent
>(ComponentManager.Capability.FOCUSABLE, false);
for (const component of focusableComponents) {
if (component.getFocusableElement().getAttribute('id') === id) {
return component;
}
}

const zoomControl = this.zoomControls_?.getControlWithId(id);
if (zoomControl) return zoomControl;

return null;
}

Expand Down
42 changes: 18 additions & 24 deletions packages/blockly/core/zoom_controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {ComponentManager} from './component_manager.js';
import * as Css from './css.js';
import {EventType} from './events/type.js';
import * as eventUtils from './events/utils.js';
import type {IComponent} from './interfaces/i_component.js';
import {IFocusableNode} from './interfaces/i_focusable_node.js';
import type {IPositionable} from './interfaces/i_positionable.js';
import type {UiMetrics} from './metrics_manager.js';
Expand All @@ -39,9 +40,9 @@ import type {WorkspaceSvg} from './workspace_svg.js';
*
* @internal
*/
abstract class ZoomControl implements IFocusableNode {
abstract class ZoomControl implements IFocusableNode, IComponent {
private pointerDownHandler: browserEvents.Data;
private id: string;
id: string;

constructor(
protected workspace: WorkspaceSvg,
Expand All @@ -60,10 +61,6 @@ abstract class ZoomControl implements IFocusableNode {
this.group.id = this.id;
}

getId() {
return this.id;
}

/**
* Handles a mouse down event on the zoom in or zoom out buttons on the
* workspace.
Expand Down Expand Up @@ -385,6 +382,21 @@ export class ZoomControls implements IPositionable {
this.svgGroup,
);
}

for (const control of [
this.zoomOutControl,
this.zoomInControl,
this.zoomResetControl,
]) {
if (!control) continue;

this.workspace.getComponentManager().addComponent({
component: control,
weight: ComponentManager.ComponentWeight.ZOOM_CONTROLS_WEIGHT,
capabilities: [ComponentManager.Capability.FOCUSABLE],
});
}

return this.svgGroup;
}

Expand Down Expand Up @@ -508,24 +520,6 @@ export class ZoomControls implements IPositionable {
'translate(' + this.left + ',' + this.top + ')',
);
}

/**
* Returns the individual zoom control, if any, with the given ID. Used for
* focus management.
*
* @internal
*/
getControlWithId(id: string) {
for (const control of [
this.zoomInControl,
this.zoomOutControl,
this.zoomResetControl,
]) {
if (control?.getId() === id) {
return control;
}
}
}
}

/** CSS for zoom controls. See css.js for use. */
Expand Down
Loading