@@ -4,8 +4,8 @@ import * as Sarif from 'sarif';
44import * as Keys from '../result-keys' ;
55import { LocationStyle , ResolvableLocationValue } from 'semmle-bqrs' ;
66import * as octicons from './octicons' ;
7- import { className , renderLocation , ResultTableProps , zebraStripe , selectableZebraStripe } from './result-table-utils' ;
8- import { PathTableResultSet } from './results' ;
7+ import { className , renderLocation , ResultTableProps , zebraStripe , selectableZebraStripe , jumpToLocation } from './result-table-utils' ;
8+ import { PathTableResultSet , onNavigation , NavigationEvent } from './results' ;
99
1010export type PathTableProps = ResultTableProps & { resultSet : PathTableResultSet } ;
1111export interface PathTableState {
@@ -75,6 +75,7 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
7575 constructor ( props : PathTableProps ) {
7676 super ( props ) ;
7777 this . state = { expanded : { } , selectedPathNode : undefined } ;
78+ this . handleNavigationEvent = this . handleNavigationEvent . bind ( this ) ;
7879 }
7980
8081 /**
@@ -290,6 +291,37 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
290291 < tbody > { rows } </ tbody >
291292 </ table > ;
292293 }
294+
295+ private handleNavigationEvent ( event : NavigationEvent ) {
296+ this . setState ( prevState => {
297+ let { selectedPathNode } = prevState ;
298+ if ( selectedPathNode === undefined ) return prevState ;
299+
300+ let path = Keys . getPath ( this . props . resultSet . sarif , selectedPathNode ) ;
301+ if ( path === undefined ) return prevState ;
302+
303+ let nextIndex = selectedPathNode . pathNodeIndex + event . direction ;
304+ if ( nextIndex < 0 || nextIndex >= path . locations . length ) return prevState ;
305+
306+ let sarifLoc = path . locations [ nextIndex ] . location ;
307+ if ( sarifLoc === undefined ) return prevState ;
308+
309+ let loc = parseSarifLocation ( sarifLoc , this . props . resultSet . sourceLocationPrefix ) ;
310+ if ( loc . t === 'NoLocation' ) return prevState ;
311+
312+ jumpToLocation ( loc , this . props . databaseUri ) ;
313+ let newSelection = { ...selectedPathNode , pathNodeIndex : nextIndex } ;
314+ return { ...prevState , selectedPathNode : newSelection } ;
315+ } ) ;
316+ }
317+
318+ componentDidMount ( ) {
319+ onNavigation . addListener ( this . handleNavigationEvent ) ;
320+ }
321+
322+ componentWillUnmount ( ) {
323+ onNavigation . removeListener ( this . handleNavigationEvent ) ;
324+ }
293325}
294326
295327function parseSarifLocation ( loc : Sarif . Location , sourceLocationPrefix : string ) : ParsedSarifLocation {
0 commit comments