@@ -26,8 +26,10 @@ import type {IComponent} from './interfaces/i_component';
2626import type { IDraggable } from './interfaces/i_draggable.js' ;
2727import type { IFlyout } from './interfaces/i_flyout.js' ;
2828import type { IFocusableNode } from './interfaces/i_focusable_node.js' ;
29+ import type { IFocusableTree } from './interfaces/i_focusable_tree.js' ;
2930import type { IPositionable } from './interfaces/i_positionable.js' ;
3031import { KeyboardMover } from './keyboard_nav/keyboard_mover.js' ;
32+ import { WorkspaceControlNavigator } from './keyboard_nav/navigators/workspace_control_navigator.js' ;
3133import { keyboardNavigationController } from './keyboard_navigation_controller.js' ;
3234import type { UiMetrics } from './metrics_manager.js' ;
3335import { Msg } from './msg.js' ;
@@ -50,8 +52,14 @@ import type {WorkspaceSvg} from './workspace_svg.js';
5052 */
5153export class Trashcan
5254 extends DeleteArea
53- implements IAutoHideable , IPositionable , IFocusableNode , IComponent
55+ implements
56+ IAutoHideable ,
57+ IPositionable ,
58+ IFocusableNode ,
59+ IFocusableTree ,
60+ IComponent
5461{
62+ private readonly navigator = new WorkspaceControlNavigator ( ) ;
5563 /**
5664 * The id for this component that is used to register with the
5765 * ComponentManager.
@@ -137,17 +145,25 @@ export class Trashcan
137145 */
138146 createDom ( ) : SVGElement {
139147 /* Here's the markup that will be generated:
140- <g class="blocklyTrash">
141- <clippath id="blocklyTrashBodyClipPath837493">
142- <rect width="47" height="45" y="15"></rect>
143- </clippath>
144- <image width="64" height="92" y="-32" xlink:href="media/sprites.png"
145- clip-path="url(#blocklyTrashBodyClipPath837493)"></image>
146- <clippath id="blocklyTrashLidClipPath837493">
147- <rect width="47" height="15"></rect>
148- </clippath>
149- <image width="84" height="92" y="-32" xlink:href="media/sprites.png"
150- clip-path="url(#blocklyTrashLidClipPath837493)"></image>
148+ <g role="button" class="blocklyTrash" tabindex="0" id="blockly-0"
149+ aria-label="Trash, currently empty" aria-disabled="true">
150+ <rect width="55" height="68" x="-4" y="-4" rx="2" ry="2"
151+ fill="none" class="blocklyFocusRing"></rect>
152+ <clipPath id="blocklyTrashBodyClipPath837493">
153+ <rect width="47" height="44" y="16"></rect>
154+ </clipPath>
155+ <image width="96" x="0" height="124" y="-32"
156+ clip-path="url(#blocklyTrashBodyClipPath837493)"
157+ xlink:href="../media/sprites.svg"></image>
158+ <clipPath id="blocklyTrashLidClipPath837493">
159+ <rect width="47" height="16"></rect>
160+ </clipPath>
161+ <g role="none" class="blocklyTrashLid">
162+ <svg role="none" viewBox="0 32 47 16" width="47" height="16">
163+ <image width="96" height="124"
164+ href="../media/sprites.svg"></image>
165+ </svg>
166+ </g>
151167 </g>
152168 */
153169 this . svgGroup = dom . createSvgElement ( Svg . G , {
@@ -256,6 +272,7 @@ export class Trashcan
256272 this . blockMouseDownWhenOpenable ,
257273 ) ;
258274 browserEvents . bind ( this . svgGroup , 'pointerup' , this , this . click ) ;
275+ getFocusManager ( ) . registerTree ( this , false ) ;
259276 return this . svgGroup ;
260277 }
261278
@@ -275,7 +292,6 @@ export class Trashcan
275292 ComponentManager . Capability . DELETE_AREA ,
276293 ComponentManager . Capability . DRAG_TARGET ,
277294 ComponentManager . Capability . POSITIONABLE ,
278- ComponentManager . Capability . FOCUSABLE ,
279295 ] ,
280296 } ) ;
281297 this . initialized = true ;
@@ -287,6 +303,9 @@ export class Trashcan
287303 * Unlink from all DOM elements to prevent memory leaks.
288304 */
289305 dispose ( ) {
306+ if ( getFocusManager ( ) . isRegistered ( this ) ) {
307+ getFocusManager ( ) . unregisterTree ( this ) ;
308+ }
290309 this . workspace . getComponentManager ( ) . removeComponent ( 'trashcan' ) ;
291310 if ( this . svgGroup ) {
292311 dom . removeNode ( this . svgGroup ) ;
@@ -662,7 +681,7 @@ export class Trashcan
662681 }
663682
664683 getFocusableTree ( ) {
665- return this . workspace ;
684+ return this ;
666685 }
667686
668687 onNodeFocus ( ) { }
@@ -672,6 +691,37 @@ export class Trashcan
672691 return ! ! this . svgGroup ;
673692 }
674693
694+ /** See IFocusableTree.getRootFocusableNode. */
695+ getRootFocusableNode ( ) : IFocusableNode {
696+ return this ;
697+ }
698+
699+ /** See IFocusableTree.getRestoredFocusableNode. */
700+ getRestoredFocusableNode ( ) : IFocusableNode | null {
701+ return this ;
702+ }
703+
704+ /** See IFocusableTree.getNestedTrees. */
705+ getNestedTrees ( ) : IFocusableTree [ ] {
706+ return [ ] ;
707+ }
708+
709+ /** See IFocusableTree.lookUpFocusableNode. */
710+ lookUpFocusableNode ( ) : IFocusableNode | null {
711+ return null ;
712+ }
713+
714+ /** See IFocusableTree.onTreeFocus. */
715+ onTreeFocus ( ) : void { }
716+
717+ /** See IFocusableTree.onTreeBlur. */
718+ onTreeBlur ( ) : void { }
719+
720+ /** See IFocusableTree.getNavigator. */
721+ getNavigator ( ) : WorkspaceControlNavigator {
722+ return this . navigator ;
723+ }
724+
675725 performAction ( ) {
676726 this . click ( ) ;
677727 }
0 commit comments