@@ -17,6 +17,7 @@ import {
1717 registrationType as cursorRegistrationType ,
1818 FlyoutCursor ,
1919} from './flyout_cursor' ;
20+ import { PassiveFocus } from './passive_focus' ;
2021
2122/**
2223 * Class that holds all methods necessary for keyboard navigation to work.
@@ -33,11 +34,6 @@ export class Navigation {
3334 */
3435 WS_MOVE_DISTANCE = 40 ;
3536
36- /**
37- * The name of the marker to use for keyboard navigation.
38- */
39- MARKER_NAME = 'local_marker_1' ;
40-
4137 /**
4238 * The default coordinate to use when focusing on the workspace and no
4339 * blocks are present. In pixel coordinates, but will be converted to
@@ -72,6 +68,17 @@ export class Navigation {
7268 */
7369 protected workspaces : Blockly . WorkspaceSvg [ ] = [ ] ;
7470
71+ /**
72+ * An object that renders a passive focus indicator at a specified location.
73+ */
74+ protected passiveFocusIndicator : PassiveFocus = new PassiveFocus ( ) ;
75+
76+ /**
77+ * The node that has passive focus when the cursor has moved to the flyout
78+ * or toolbox; null if the cursor is moving around the main workspace.
79+ */
80+ protected markedNode : Blockly . ASTNode | null = null ;
81+
7582 /**
7683 * Constructor for keyboard navigation.
7784 */
@@ -90,9 +97,6 @@ export class Navigation {
9097 addWorkspace ( workspace : Blockly . WorkspaceSvg ) {
9198 this . workspaces . push ( workspace ) ;
9299 const flyout = workspace . getFlyout ( ) ;
93- workspace
94- . getMarkerManager ( )
95- . registerMarker ( this . MARKER_NAME , new Blockly . Marker ( ) ) ;
96100 workspace . addChangeListener ( this . wsChangeWrapper ) ;
97101
98102 if ( flyout ) {
@@ -116,9 +120,7 @@ export class Navigation {
116120 if ( workspaceIdx > - 1 ) {
117121 this . workspaces . splice ( workspaceIdx , 1 ) ;
118122 }
119- if ( workspace . getMarkerManager ( ) ) {
120- workspace . getMarkerManager ( ) . unregisterMarker ( this . MARKER_NAME ) ;
121- }
123+ this . passiveFocusIndicator . dispose ( ) ;
122124 workspace . removeChangeListener ( this . wsChangeWrapper ) ;
123125
124126 if ( flyout ) {
@@ -146,16 +148,6 @@ export class Navigation {
146148 return this . workspaceStates [ workspace . id ] ;
147149 }
148150
149- /**
150- * Gets the marker created for keyboard navigation.
151- *
152- * @param workspace The workspace to get the marker from.
153- * @returns The marker created for keyboard navigation.
154- */
155- getMarker ( workspace : Blockly . WorkspaceSvg ) : Blockly . Marker | null {
156- return workspace . getMarker ( this . MARKER_NAME ) ;
157- }
158-
159151 /**
160152 * Adds all event listeners and cursors to the flyout that are needed for
161153 * keyboard navigation to work.
@@ -480,13 +472,11 @@ export class Navigation {
480472 return ;
481473 }
482474
475+ this . markAtCursor ( workspace ) ;
476+ workspace . getCursor ( ) ?. hide ( ) ;
483477 this . setState ( workspace , Constants . STATE . TOOLBOX ) ;
484478 this . resetFlyout ( workspace , false /* shouldHide */ ) ;
485479
486- if ( ! this . getMarker ( workspace ) ! . getCurNode ( ) ) {
487- this . markAtCursor ( workspace ) ;
488- }
489-
490480 if ( ! toolbox . getSelectedItem ( ) ) {
491481 // Find the first item that is selectable.
492482 const toolboxItems = ( toolbox as any ) . getToolboxItems ( ) ;
@@ -506,14 +496,12 @@ export class Navigation {
506496 * @param workspace The workspace the flyout is on.
507497 */
508498 focusFlyout ( workspace : Blockly . WorkspaceSvg ) {
509- const flyout = workspace . getFlyout ( ) ;
499+ workspace . getCursor ( ) ?. hide ( ) ;
500+ this . markAtCursor ( workspace ) ;
510501
502+ const flyout = workspace . getFlyout ( ) ;
511503 this . setState ( workspace , Constants . STATE . FLYOUT ) ;
512504
513- if ( ! this . getMarker ( workspace ) ! . getCurNode ( ) ) {
514- this . markAtCursor ( workspace ) ;
515- }
516-
517505 if ( flyout && flyout . getWorkspace ( ) ) {
518506 const flyoutContents = flyout . getContents ( ) ;
519507 const firstFlyoutItem = flyoutContents [ 0 ] ;
@@ -612,11 +600,14 @@ export class Navigation {
612600 if ( ! newBlock ) {
613601 return ;
614602 }
615- const markerNode = this . getMarker ( workspace ) ! . getCurNode ( ) ;
603+ if ( ! this . markedNode ) {
604+ this . warn ( 'No marked node when inserting from flyout.' ) ;
605+ return ;
606+ }
616607 if (
617608 ! this . tryToConnectNodes (
618609 workspace ,
619- markerNode ,
610+ this . markedNode ,
620611 Blockly . ASTNode . createBlockNode ( newBlock ) ! ,
621612 )
622613 ) {
@@ -681,19 +672,21 @@ export class Navigation {
681672 }
682673
683674 /**
684- * Connects the location of the marker and the location of the cursor.
685- * No-op if the marker or cursor node are null.
675+ * Connects the location of the marked node and the location of the cursor.
676+ * No-op if the marked node or cursor node are null.
686677 *
687678 * @param workspace The main workspace.
688679 * @returns True if the cursor and marker locations were connected,
689680 * false otherwise.
690681 */
691682 connectMarkerAndCursor ( workspace : Blockly . WorkspaceSvg ) : boolean {
692- const markerNode = this . getMarker ( workspace ) ! . getCurNode ( ) ;
693683 const cursorNode = workspace . getCursor ( ) ! . getCurNode ( ) ;
694684
695- if ( markerNode && cursorNode ) {
696- return this . tryToConnectNodes ( workspace , markerNode , cursorNode ) ;
685+ if ( this . markedNode && cursorNode ) {
686+ if ( this . tryToConnectNodes ( workspace , this . markedNode , cursorNode ) ) {
687+ this . removeMark ( workspace ) ;
688+ return true ;
689+ }
697690 }
698691 return false ;
699692 }
@@ -1109,22 +1102,24 @@ export class Navigation {
11091102 }
11101103
11111104 /**
1112- * Moves the marker to the cursor's current location.
1105+ * Moves the passive focus indicator to the cursor's current location.
11131106 *
11141107 * @param workspace The workspace.
11151108 */
11161109 markAtCursor ( workspace : Blockly . WorkspaceSvg ) {
1117- this . getMarker ( workspace ) ! . setCurNode ( workspace . getCursor ( ) ! . getCurNode ( ) ) ;
1110+ const cursor = workspace . getCursor ( ) ! ;
1111+ this . markedNode = cursor . getCurNode ( ) ;
1112+ this . passiveFocusIndicator . show ( this . markedNode ) ;
11181113 }
11191114
11201115 /**
1121- * Removes the marker from its current location and hide it.
1116+ * Removes the passive focus indicator from its current location and hides it.
11221117 *
11231118 * @param workspace The workspace.
11241119 */
11251120 removeMark ( workspace : Blockly . WorkspaceSvg ) {
1126- const marker = this . getMarker ( workspace ) ;
1127- marker ?. hide ( ) ;
1121+ this . passiveFocusIndicator . hide ( ) ;
1122+ this . markedNode = null ;
11281123 }
11291124
11301125 /**
@@ -1154,8 +1149,8 @@ export class Navigation {
11541149 workspace . keyboardAccessibilityMode
11551150 ) {
11561151 workspace . keyboardAccessibilityMode = false ;
1152+ this . markAtCursor ( workspace ) ;
11571153 workspace . getCursor ( ) ! . hide ( ) ;
1158- this . getMarker ( workspace ) ! . hide ( ) ;
11591154 if ( this . getFlyoutCursor ( workspace ) ) {
11601155 this . getFlyoutCursor ( workspace ) ! . hide ( ) ;
11611156 }
@@ -1247,7 +1242,6 @@ export class Navigation {
12471242 curNode . isConnection ( ) ||
12481243 nodeType == Blockly . ASTNode . types . WORKSPACE
12491244 ) {
1250- this . markAtCursor ( workspace ) ;
12511245 if ( workspace . getToolbox ( ) ) {
12521246 this . focusToolbox ( workspace ) ;
12531247 } else {
@@ -1327,6 +1321,7 @@ export class Navigation {
13271321 ) as Blockly . BlockSvg ;
13281322 if ( block ) {
13291323 isHandled = this . insertPastedBlock ( workspace , block ) ;
1324+ this . removeMark ( workspace ) ;
13301325 }
13311326 Blockly . Events . setGroup ( false ) ;
13321327 return isHandled ;
0 commit comments