@@ -30,12 +30,8 @@ import {isFocusableNode} from '../interfaces/i_focusable_node.js';
3030import type { INavigable } from '../interfaces/i_navigable.js' ;
3131import * as registry from '../registry.js' ;
3232import { RenderedConnection } from '../rendered_connection.js' ;
33- import type { MarkerSvg } from '../renderers/common/marker_svg.js' ;
34- import type { PathObject } from '../renderers/zelos/path_object.js' ;
3533import { Renderer } from '../renderers/zelos/renderer.js' ;
36- import * as dom from '../utils/dom.js' ;
3734import { WorkspaceSvg } from '../workspace_svg.js' ;
38- import { ASTNode } from './ast_node.js' ;
3935import { BlockNavigationPolicy } from './block_navigation_policy.js' ;
4036import { ConnectionNavigationPolicy } from './connection_navigation_policy.js' ;
4137import { FieldNavigationPolicy } from './field_navigation_policy.js' ;
@@ -574,40 +570,6 @@ export class LineCursor extends Marker {
574570 return super . getCurNode ( ) ;
575571 }
576572
577- /**
578- * Sets the object in charge of drawing the marker.
579- *
580- * We want to customize drawing, so rather than directly setting the given
581- * object, we instead set a wrapper proxy object that passes through all
582- * method calls and property accesses except for draw(), which it delegates
583- * to the drawMarker() method in this class.
584- *
585- * @param drawer The object ~in charge of drawing the marker.
586- */
587- override setDrawer ( drawer : MarkerSvg ) {
588- const altDraw = function (
589- this : LineCursor ,
590- oldNode : ASTNode | null ,
591- curNode : ASTNode | null ,
592- ) {
593- // Pass the unproxied, raw drawer object so that drawMarker can call its
594- // `draw()` method without triggering infinite recursion.
595- this . drawMarker ( oldNode , curNode , drawer ) ;
596- } . bind ( this ) ;
597-
598- super . setDrawer (
599- new Proxy ( drawer , {
600- get ( target : typeof drawer , prop : keyof typeof drawer ) {
601- if ( prop === 'draw' ) {
602- return altDraw ;
603- }
604-
605- return target [ prop ] ;
606- } ,
607- } ) ,
608- ) ;
609- }
610-
611573 /**
612574 * Set the location of the cursor and draw it.
613575 *
@@ -631,124 +593,6 @@ export class LineCursor extends Marker {
631593 }
632594 }
633595
634- /**
635- * Draw this cursor's marker.
636- *
637- * This is a wrapper around this.drawer.draw (usually implemented by
638- * MarkerSvg.prototype.draw) that will, if newNode is a BLOCK node,
639- * instead call `setSelected` to select it (if it's a regular block)
640- * or `addSelect` (if it's a shadow block, since shadow blocks can't
641- * be selected) instead of using the normal drawer logic.
642- *
643- * TODO(#142): The selection and fake-selection code was originally
644- * a hack added for testing on October 28 2024, because the default
645- * drawer (MarkerSvg) behaviour in Zelos was to draw a box around
646- * the block and all attached child blocks, which was confusing when
647- * navigating stacks.
648- *
649- * Since then we have decided that we probably _do_ in most cases
650- * want navigating to a block to select the block, but more
651- * particularly that we want navigation to move _focus_. Replace
652- * this selection hack with non-hacky changing of focus once that's
653- * possible.
654- *
655- * @param oldNode The previous node.
656- * @param curNode The current node.
657- * @param realDrawer The object ~in charge of drawing the marker.
658- */
659- private drawMarker (
660- oldNode : ASTNode | null ,
661- curNode : ASTNode | null ,
662- realDrawer : MarkerSvg ,
663- ) {
664- // If old node was a block, unselect it or remove fake selection.
665- if ( oldNode ?. getType ( ) === ASTNode . types . BLOCK ) {
666- const block = oldNode . getLocation ( ) as BlockSvg ;
667- if ( ! block . isShadow ( ) ) {
668- // Selection should already be in sync.
669- } else {
670- block . removeSelect ( ) ;
671- }
672- }
673-
674- if ( this . isZelos && oldNode && this . isValueInputConnection ( oldNode ) ) {
675- this . hideAtInput ( oldNode ) ;
676- }
677-
678- const curNodeType = curNode ?. getType ( ) ;
679- const isZelosInputConnection =
680- this . isZelos && curNode && this . isValueInputConnection ( curNode ) ;
681-
682- // If drawing can't be handled locally, just use the drawer.
683- if ( curNodeType !== ASTNode . types . BLOCK && ! isZelosInputConnection ) {
684- realDrawer . draw ( oldNode , curNode ) ;
685- return ;
686- }
687-
688- // Hide any visible marker SVG and instead do some manual rendering.
689- realDrawer . hide ( ) ;
690-
691- if ( isZelosInputConnection ) {
692- this . showAtInput ( curNode ) ;
693- } else if ( curNode && curNodeType === ASTNode . types . BLOCK ) {
694- const block = curNode . getLocation ( ) as BlockSvg ;
695- if ( ! block . isShadow ( ) ) {
696- // Selection should already be in sync.
697- } else {
698- block . addSelect ( ) ;
699- block . getParent ( ) ?. removeSelect ( ) ;
700- }
701- }
702-
703- // Call MarkerSvg.prototype.fireMarkerEvent like
704- // MarkerSvg.prototype.draw would (even though it's private).
705- ( realDrawer as any ) ?. fireMarkerEvent ?.( oldNode , curNode ) ;
706- }
707-
708- /**
709- * Check whether the node represents a value input connection.
710- *
711- * @param node The node to check
712- * @returns True if the node represents a value input connection.
713- */
714- private isValueInputConnection ( node : ASTNode ) {
715- if ( node ?. getType ( ) !== ASTNode . types . INPUT ) return false ;
716- const connection = node . getLocation ( ) as RenderedConnection ;
717- return connection . type === ConnectionType . INPUT_VALUE ;
718- }
719-
720- /**
721- * Hide the cursor rendering at the given input node.
722- *
723- * @param node The input node to hide.
724- */
725- private hideAtInput ( node : ASTNode ) {
726- const inputConnection = node . getLocation ( ) as RenderedConnection ;
727- const sourceBlock = inputConnection . getSourceBlock ( ) as BlockSvg ;
728- const input = inputConnection . getParentInput ( ) ;
729- if ( input ) {
730- const pathObject = sourceBlock . pathObject as PathObject ;
731- const outlinePath = pathObject . getOutlinePath ( input . name ) ;
732- dom . removeClass ( outlinePath , 'inputActiveFocus' ) ;
733- }
734- }
735-
736- /**
737- * Show the cursor rendering at the given input node.
738- *
739- * @param node The input node to show.
740- */
741- private showAtInput ( node : ASTNode ) {
742- const inputConnection = node . getLocation ( ) as RenderedConnection ;
743- const sourceBlock = inputConnection . getSourceBlock ( ) as BlockSvg ;
744- const input = inputConnection . getParentInput ( ) ;
745- if ( input ) {
746- const pathObject = sourceBlock . pathObject as PathObject ;
747- const outlinePath = pathObject . getOutlinePath ( input . name ) ;
748- dom . addClass ( outlinePath , 'inputActiveFocus' ) ;
749- }
750- }
751-
752596 /**
753597 * Updates the current node to match the selection.
754598 *
0 commit comments