@@ -62,8 +62,6 @@ interface HoverifierOptions {
6262
6363 hoverOverlayElements : Observable < HTMLElement | null >
6464
65- dom : DOMFunctions
66-
6765 /**
6866 * Called for programmatic navigation (like `history.push()`)
6967 */
@@ -102,28 +100,37 @@ export interface Hoverifier {
102100 unsubscribe ( ) : void
103101}
104102
105- export interface HoverifyOptions {
103+ export interface PositionJump {
104+ /**
105+ * The position within the code view to jump to
106+ */
107+ position : LineOrPositionOrRange
108+ /**
109+ * The code view
110+ */
111+ codeView : HTMLElement
112+ /**
113+ * The element to scroll if the position is out of view
114+ */
115+ scrollElement : HTMLElement
116+ }
117+
118+ /**
119+ * HoverifyOptions that need to be included internally with every event
120+ */
121+ interface EventOptions {
122+ resolveContext : ContextResolver
123+ dom : DOMFunctions
124+ }
125+
126+ export interface HoverifyOptions extends EventOptions {
106127 positionEvents : Observable < PositionEvent >
107128
108129 /**
109130 * Emit on this Observable to trigger the overlay on a position in this code view.
110131 * This Observable is intended to be used to trigger a Hover after a URL change with a position.
111132 */
112- positionJumps : Observable < {
113- /**
114- * The position within the code view to jump to
115- */
116- position : LineOrPositionOrRange
117- /**
118- * The code view
119- */
120- codeView : HTMLElement
121- /**
122- * The element to scroll if the position is out of view
123- */
124- scrollElement : HTMLElement
125- } >
126- resolveContext : ContextResolver
133+ positionJumps : Observable < PositionJump >
127134}
128135
129136/**
@@ -217,7 +224,6 @@ export const createHoverifier = ({
217224 fetchHover,
218225 fetchJumpURL,
219226 logTelemetryEvent,
220- dom,
221227} : HoverifierOptions ) : Hoverifier => {
222228 // Internal state that is not exposed to the caller
223229 // Shared between all hoverified code views
@@ -232,9 +238,7 @@ export const createHoverifier = ({
232238 selectedPosition : undefined ,
233239 } )
234240
235- interface MouseEventTrigger extends PositionEvent {
236- resolveContext : ContextResolver
237- }
241+ interface MouseEventTrigger extends PositionEvent , EventOptions { }
238242
239243 // These Subjects aggregate all events from all hoverified code views
240244 const allPositionsFromEvents = new Subject < MouseEventTrigger > ( )
@@ -246,12 +250,7 @@ export const createHoverifier = ({
246250 const allCodeMouseOvers = allPositionsFromEvents . pipe ( filter ( isEventType ( 'mouseover' ) ) )
247251 const allCodeClicks = allPositionsFromEvents . pipe ( filter ( isEventType ( 'click' ) ) )
248252
249- const allPositionJumps = new Subject < {
250- position : LineOrPositionOrRange
251- codeView : HTMLElement
252- scrollElement : HTMLElement
253- resolveContext : ContextResolver
254- } > ( )
253+ const allPositionJumps = new Subject < PositionJump & EventOptions > ( )
255254
256255 const subscription = new Subscription ( )
257256
@@ -314,7 +313,7 @@ export const createHoverifier = ({
314313 distinctUntilChanged ( ( a , b ) => isEqual ( a , b ) ) ,
315314 // Ignore undefined or partial positions (e.g. line only)
316315 filter ( ( jump ) : jump is typeof jump & { position : Position } => Position . is ( jump . position ) ) ,
317- map ( ( { position, codeView, ...rest } ) => {
316+ map ( ( { position, codeView, dom , ...rest } ) => {
318317 const cell = dom . getCodeElementFromLineNumber ( codeView , position . line )
319318 if ( ! cell ) {
320319 return undefined
@@ -325,7 +324,7 @@ export const createHoverifier = ({
325324 return undefined
326325 }
327326 const part = dom . getDiffCodePart && dom . getDiffCodePart ( target )
328- return { ...rest , eventType : 'jump' as 'jump' , target, position : { ...position , part } , codeView }
327+ return { ...rest , eventType : 'jump' as 'jump' , target, position : { ...position , part } , codeView, dom }
329328 } ) ,
330329 filter ( isDefined )
331330 )
@@ -364,9 +363,9 @@ export const createHoverifier = ({
364363 * This is a higher-order Observable (Observable that emits Observables).
365364 */
366365 const hoverObservables = resolvedPositions . pipe (
367- map ( ( { position, codeView } ) => {
366+ map ( ( { position, ... rest } ) => {
368367 if ( ! position ) {
369- return of ( { codeView , hoverOrError : undefined } )
368+ return of ( { ... rest , hoverOrError : undefined } )
370369 }
371370 // Fetch the hover for that position
372371 const hoverFetch = fetchHover ( position ) . pipe (
@@ -388,33 +387,35 @@ export const createHoverifier = ({
388387 takeUntil ( hoverFetch )
389388 ) ,
390389 hoverFetch
391- ) . pipe ( map ( hoverOrError => ( { hoverOrError , codeView } ) ) )
390+ ) . pipe ( map ( hoverOrError => ( { ... rest , hoverOrError } ) ) )
392391 } ) ,
393392 share ( )
394393 )
395394 // Highlight the hover range returned by the language server
396395 subscription . add (
397- hoverObservables . pipe ( switchMap ( hoverObservable => hoverObservable ) ) . subscribe ( ( { hoverOrError, codeView } ) => {
398- container . update ( {
399- hoverOrError,
400- // Reset the hover position, it's gonna be repositioned after the hover was rendered
401- hoverOverlayPosition : undefined ,
396+ hoverObservables
397+ . pipe ( switchMap ( hoverObservable => hoverObservable ) )
398+ . subscribe ( ( { hoverOrError, codeView, dom } ) => {
399+ container . update ( {
400+ hoverOrError,
401+ // Reset the hover position, it's gonna be repositioned after the hover was rendered
402+ hoverOverlayPosition : undefined ,
403+ } )
404+ const currentHighlighted = codeView ! . querySelector ( '.selection-highlight' )
405+ if ( currentHighlighted ) {
406+ currentHighlighted . classList . remove ( 'selection-highlight' )
407+ }
408+ if ( ! HoverMerged . is ( hoverOrError ) || ! hoverOrError . range ) {
409+ return
410+ }
411+ // LSP is 0-indexed, the code in the webapp currently is 1-indexed
412+ const { line, character } = hoverOrError . range . start
413+ const token = getTokenAtPosition ( codeView , { line : line + 1 , character : character + 1 } , dom )
414+ if ( ! token ) {
415+ return
416+ }
417+ token . classList . add ( 'selection-highlight' )
402418 } )
403- const currentHighlighted = codeView ! . querySelector ( '.selection-highlight' )
404- if ( currentHighlighted ) {
405- currentHighlighted . classList . remove ( 'selection-highlight' )
406- }
407- if ( ! HoverMerged . is ( hoverOrError ) || ! hoverOrError . range ) {
408- return
409- }
410- // LSP is 0-indexed, the code in the webapp currently is 1-indexed
411- const { line, character } = hoverOrError . range . start
412- const token = getTokenAtPosition ( codeView ! , { line : line + 1 , character : character + 1 } , dom )
413- if ( ! token ) {
414- return
415- }
416- token . classList . add ( 'selection-highlight' )
417- } )
418419 )
419420 // Telemetry for hovers
420421 subscription . add (
@@ -535,12 +536,12 @@ export const createHoverifier = ({
535536
536537 // LOCATION CHANGES
537538 subscription . add (
538- allPositionJumps . subscribe ( ( { position, scrollElement, codeView } ) => {
539+ allPositionJumps . subscribe ( ( { position, scrollElement, codeView, dom : { getCodeElementFromLineNumber } } ) => {
539540 container . update ( {
540541 // Remember active position in state for blame and range expansion
541542 selectedPosition : position ,
542543 } )
543- const rows = getCodeElementsInRange ( codeView , { position, ... dom } )
544+ const rows = getCodeElementsInRange ( { codeView, position, getCodeElementFromLineNumber } )
544545 for ( const { element } of rows ) {
545546 convertNode ( element )
546547 }
@@ -573,15 +574,14 @@ export const createHoverifier = ({
573574 map ( internalToExternalState ) ,
574575 distinctUntilChanged ( ( a , b ) => isEqual ( a , b ) )
575576 ) ,
576- hoverify ( { positionEvents, positionJumps, resolveContext } : HoverifyOptions ) : Subscription {
577+ hoverify ( { positionEvents, positionJumps, ... eventOptions } : HoverifyOptions ) : Subscription {
577578 const subscription = new Subscription ( )
578- const eventWithContextResolver = map ( ( event : PositionEvent ) => ( {
579- ...event ,
580- resolveContext,
581- } ) )
579+ const eventWithOptions = map ( ( event : PositionEvent ) => ( { ...event , ...eventOptions } ) )
582580 // Broadcast all events from this code view
583- subscription . add ( positionEvents . pipe ( eventWithContextResolver ) . subscribe ( allPositionsFromEvents ) )
584- subscription . add ( positionJumps . pipe ( map ( jump => ( { ...jump , resolveContext } ) ) ) . subscribe ( allPositionJumps ) )
581+ subscription . add ( positionEvents . pipe ( eventWithOptions ) . subscribe ( allPositionsFromEvents ) )
582+ subscription . add (
583+ positionJumps . pipe ( map ( jump => ( { ...jump , ...eventOptions } ) ) ) . subscribe ( allPositionJumps )
584+ )
585585 return subscription
586586 } ,
587587 unsubscribe ( ) : void {
0 commit comments