Skip to content
This repository was archived by the owner on Nov 25, 2021. It is now read-only.

Commit 50263a6

Browse files
authored
fix: unsubscribe from actions and hover observable (#102)
Only take from the actions and hover Observables until the code view is unsubscribed. Fixes https://github.com/sourcegraph/sourcegraph/issues/3108
1 parent f0c6738 commit 50263a6

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

README.md

+9-7
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ You may have to rebase a branch before merging to ensure it has a proper commit
5050

5151
## Glossary
5252

53-
| Term | Definition |
54-
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
55-
| Code view | The DOM element that contains all the line elements |
56-
| Line number element | The DOM element that contains the line number label for that line |
57-
| Code element | The DOM element that contains the code for one line |
58-
| Diff part | The part of the diff, either base, head or both (if the line didn't change). Each line belongs to one diff part, and therefor to a different commit ID and potentially different file path. |
59-
| Hover overlay | Also called tooltip |
53+
| Term | Definition |
54+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
55+
| Code view | The DOM element that contains all the line elements |
56+
| Line number element | The DOM element that contains the line number label for that line |
57+
| Code element | The DOM element that contains the code for one line |
58+
| Diff part | The part of the diff, either base, head or both (if the line didn't change). Each line belongs to one diff part, and therefor to a different commit ID and potentially different file path. |
59+
| Hover overlay | Also called tooltip |
60+
| hoverify | To attach all the listeners needed to a code view so that it will display overlay on hovers and clicks. |
61+
| unhoverify | To unsubscribe from the Subscription returned by `hoverifier.hoverify()`. Removes all event listeners from the code view again and hides the hover overlay if it was triggered by the unhoverified code view. |

src/hoverifier.test.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -612,8 +612,9 @@ describe('Hoverifier', () => {
612612
closeButtonClicks: NEVER,
613613
hoverOverlayElements: of(null),
614614
hoverOverlayRerenders: EMPTY,
615-
getHover: createStubHoverProvider(),
616-
getActions: () => of(null),
615+
// It's important that getHover() and getActions() emit something
616+
getHover: createStubHoverProvider({}),
617+
getActions: () => of([{}]).pipe(delay(50)),
617618
})
618619
const positionJumps = new Subject<PositionJump>()
619620
const positionEvents = of(codeView.codeView).pipe(findPositionsFromEvents(codeView))

src/hoverifier.ts

+19-5
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,12 @@ export function createHoverifier<C extends object, D, A>({
355355

356356
const allPositionJumps = new Subject<PositionJump & EventOptions<C>>()
357357

358+
/**
359+
* Whenever a Subscription returned by `hoverify()` is unsubscribed,
360+
* emits the code view ID associated with it.
361+
*/
362+
const allUnhoverifies = new Subject<symbol>()
363+
358364
const subscription = new Subscription()
359365

360366
/**
@@ -572,9 +578,9 @@ export function createHoverifier<C extends object, D, A>({
572578
part?: DiffPart
573579
}>
574580
> = resolvedPositions.pipe(
575-
map(({ position, ...rest }) => {
581+
map(({ position, codeViewId, ...rest }) => {
576582
if (!position) {
577-
return of({ hoverOrError: null, position: undefined, part: undefined, ...rest })
583+
return of({ hoverOrError: null, position: undefined, part: undefined, codeViewId, ...rest })
578584
}
579585
// Get the hover for that position
580586
const hover = from(getHover(position)).pipe(
@@ -594,10 +600,13 @@ export function createHoverifier<C extends object, D, A>({
594600
).pipe(
595601
map(hoverOrError => ({
596602
...rest,
603+
codeViewId,
597604
position,
598605
hoverOrError,
599606
part: position.part,
600-
}))
607+
})),
608+
// Do not emit anything after the code view this action came from got unhoverified
609+
takeUntil(allUnhoverifies.pipe(filter(unhoverifiedCodeViewId => unhoverifiedCodeViewId === codeViewId)))
601610
)
602611
}),
603612
share()
@@ -695,11 +704,14 @@ export function createHoverifier<C extends object, D, A>({
695704
*/
696705
const actionObservables = resolvedPositions.pipe(
697706
// Get the actions for that position
698-
map(({ position }) => {
707+
map(({ position, codeViewId }) => {
699708
if (!position) {
700709
return of(null)
701710
}
702-
return concat([LOADING], from(getActions(position)).pipe(catchError(error => [asError(error)])))
711+
return concat([LOADING], from(getActions(position)).pipe(catchError(error => [asError(error)]))).pipe(
712+
// Do not emit anything after the code view this action came from got unhoverified
713+
takeUntil(allUnhoverifies.pipe(filter(unhoverifiedCodeViewId => unhoverifiedCodeViewId === codeViewId)))
714+
)
703715
}),
704716
share()
705717
)
@@ -819,6 +831,8 @@ export function createHoverifier<C extends object, D, A>({
819831
.subscribe(allPositionJumps)
820832
)
821833
subscription.add(() => {
834+
// Make sure hover is hidden and associated subscriptions unsubscribed
835+
allUnhoverifies.next(codeViewId)
822836
if (container.values.codeViewId === codeViewId) {
823837
resetHover()
824838
}

0 commit comments

Comments
 (0)