@@ -521,13 +521,49 @@ async function webviewPreloads(ctx: PreloadContext) {
521
521
}
522
522
} ;
523
523
524
+ let previousDelta : number | undefined ;
524
525
let scrollTimeout : any /* NodeJS.Timeout */ | undefined ;
525
526
let scrolledElement : Element | undefined ;
526
- function flagRecentlyScrolled ( node : Element ) {
527
+ let lastTimeScrolled : number | undefined ;
528
+ function flagRecentlyScrolled ( node : Element , deltaY ?: number ) {
527
529
scrolledElement = node ;
528
- node . setAttribute ( 'recentlyScrolled' , 'true' ) ;
529
- clearTimeout ( scrollTimeout ) ;
530
- scrollTimeout = setTimeout ( ( ) => { scrolledElement ?. removeAttribute ( 'recentlyScrolled' ) ; } , 300 ) ;
530
+ if ( ! deltaY ) {
531
+ lastTimeScrolled = Date . now ( ) ;
532
+ previousDelta = undefined ;
533
+ node . setAttribute ( 'recentlyScrolled' , 'true' ) ;
534
+ clearTimeout ( scrollTimeout ) ;
535
+ scrollTimeout = setTimeout ( ( ) => { scrolledElement ?. removeAttribute ( 'recentlyScrolled' ) ; } , 300 ) ;
536
+ return true ;
537
+ }
538
+
539
+ if ( node . hasAttribute ( 'recentlyScrolled' ) ) {
540
+ if ( lastTimeScrolled && Date . now ( ) - lastTimeScrolled > 300 ) {
541
+ // it has been a while since we actually scrolled
542
+ // if scroll velocity increases, it's likely a new scroll event
543
+ if ( ! ! previousDelta && deltaY < 0 && deltaY < previousDelta - 2 ) {
544
+ clearTimeout ( scrollTimeout ) ;
545
+ scrolledElement ?. removeAttribute ( 'recentlyScrolled' ) ;
546
+ return false ;
547
+ } else if ( ! ! previousDelta && deltaY > 0 && deltaY > previousDelta + 2 ) {
548
+ clearTimeout ( scrollTimeout ) ;
549
+ scrolledElement ?. removeAttribute ( 'recentlyScrolled' ) ;
550
+ return false ;
551
+ }
552
+
553
+ // the tail end of a smooth scrolling event (from a trackpad) can go on for a while
554
+ // so keep swallowing it, but we can shorten the timeout since the events occur rapidly
555
+ clearTimeout ( scrollTimeout ) ;
556
+ scrollTimeout = setTimeout ( ( ) => { scrolledElement ?. removeAttribute ( 'recentlyScrolled' ) ; } , 50 ) ;
557
+ } else {
558
+ clearTimeout ( scrollTimeout ) ;
559
+ scrollTimeout = setTimeout ( ( ) => { scrolledElement ?. removeAttribute ( 'recentlyScrolled' ) ; } , 300 ) ;
560
+ }
561
+
562
+ previousDelta = deltaY ;
563
+ return true ;
564
+ }
565
+
566
+ return false ;
531
567
}
532
568
533
569
function eventTargetShouldHandleScroll ( event : WheelEvent ) {
@@ -536,11 +572,6 @@ async function webviewPreloads(ctx: PreloadContext) {
536
572
return false ;
537
573
}
538
574
539
- if ( node . hasAttribute ( 'recentlyScrolled' ) && scrolledElement === node ) {
540
- flagRecentlyScrolled ( node ) ;
541
- return true ;
542
- }
543
-
544
575
// scroll up
545
576
if ( event . deltaY < 0 && node . scrollTop > 0 ) {
546
577
// there is still some content to scroll
@@ -565,6 +596,10 @@ async function webviewPreloads(ctx: PreloadContext) {
565
596
flagRecentlyScrolled ( node ) ;
566
597
return true ;
567
598
}
599
+
600
+ if ( flagRecentlyScrolled ( node , event . deltaY ) ) {
601
+ return true ;
602
+ }
568
603
}
569
604
570
605
return false ;
0 commit comments