@@ -115,8 +115,10 @@ class TouchSelectionMenuController {
115115 #dragState = null ;
116116 #longPressTimer = null ;
117117 #cursorHideTimer = null ;
118+ #scrollTimeout = null ;
118119 #autoScrollRaf = 0 ;
119120 #stateSyncRaf = 0 ;
121+ #isScrolling = false ;
120122 #selectionActive = false ;
121123 #menuActive = false ;
122124 #enabled = true ;
@@ -199,6 +201,7 @@ class TouchSelectionMenuController {
199201 document . removeEventListener ( "touchstart" , this . #onGlobalPointerDown, true ) ;
200202 this . #removeTouchListeners( ) ;
201203 this . #stopAutoScroll( ) ;
204+ this . #clearScrollTimeout( ) ;
202205 cancelAnimationFrame ( this . #stateSyncRaf) ;
203206 this . #stateSyncRaf = 0 ;
204207 this . #pendingPointerTriggered = false ;
@@ -231,6 +234,7 @@ class TouchSelectionMenuController {
231234 this . #dragState = null ;
232235 this . #removeTouchListeners( ) ;
233236 this . #stopAutoScroll( ) ;
237+ this . #clearScrollTimeout( ) ;
234238 cancelAnimationFrame ( this . #stateSyncRaf) ;
235239 this . #stateSyncRaf = 0 ;
236240 this . #pendingPointerTriggered = false ;
@@ -271,6 +275,23 @@ class TouchSelectionMenuController {
271275 onScroll ( ) {
272276 if ( ! this . #enabled) return ;
273277 if ( this . #dragState) return ;
278+ this . #clearScrollTimeout( ) ;
279+ this . #isScrolling = true ;
280+ cancelAnimationFrame ( this . #stateSyncRaf) ;
281+ this . #stateSyncRaf = 0 ;
282+ this . #clearSelectionUi( ) ;
283+ this . #hideMenu( false , false ) ;
284+ this . #scrollTimeout = setTimeout ( ( ) => {
285+ this . #onScrollEnd( ) ;
286+ } , 100 ) ;
287+ }
288+
289+ #onScrollEnd( ) {
290+ this . #scrollTimeout = null ;
291+ if ( ! this . #enabled) return ;
292+ if ( ! this . #isScrolling) return ;
293+ this . #isScrolling = false ;
294+ if ( this . #dragState) return ;
274295
275296 if ( this . #selectionActive && this . #hasSelection( ) ) {
276297 this . #showSelectionHandles( ) ;
@@ -279,7 +300,13 @@ class TouchSelectionMenuController {
279300 }
280301
281302 if ( this . #menuActive) {
282- this . #hideMenu( ) ;
303+ const triggerType =
304+ this . #selectionActive && this . #hasSelection( ) ? "end" : "cursor" ;
305+ this . #showMenuDeferred( triggerType ) ;
306+ }
307+
308+ if ( this . #pendingPointerTriggered || this . #pendingSelectionChanged) {
309+ this . onStateChanged ( ) ;
283310 }
284311 }
285312
@@ -288,6 +315,7 @@ class TouchSelectionMenuController {
288315 if ( this . #handlingMenuAction) return ;
289316 if ( meta . pointerTriggered ) this . #pendingPointerTriggered = true ;
290317 if ( meta . selectionChanged ) this . #pendingSelectionChanged = true ;
318+ if ( this . #isScrolling) return ;
291319 cancelAnimationFrame ( this . #stateSyncRaf) ;
292320 this . #stateSyncRaf = requestAnimationFrame ( ( ) => {
293321 this . #stateSyncRaf = 0 ;
@@ -332,6 +360,14 @@ class TouchSelectionMenuController {
332360 ) {
333361 return ;
334362 }
363+ if (
364+ event . type === "touchstart" &&
365+ target instanceof Node &&
366+ this . #view. dom . contains ( target )
367+ ) {
368+ this . #hideMenu( false , false ) ;
369+ return ;
370+ }
335371 this . #hideMenu( ) ;
336372 } ;
337373
@@ -741,6 +777,12 @@ class TouchSelectionMenuController {
741777 this . #cursorHideTimer = null ;
742778 }
743779
780+ #clearScrollTimeout( ) {
781+ clearTimeout ( this . #scrollTimeout) ;
782+ this . #scrollTimeout = null ;
783+ this . #isScrolling = false ;
784+ }
785+
744786 #showMenu( $trigger ) {
745787 const hasSelection = this . #hasSelection( ) ;
746788 const items = filterSelectionMenuItems ( selectionMenu ( ) , {
@@ -858,10 +900,12 @@ class TouchSelectionMenuController {
858900 } ) ;
859901 }
860902
861- #hideMenu( force = false ) {
903+ #hideMenu( force = false , clearActive = true ) {
862904 if ( ! force && ! this . #menuActive) return ;
863905 this . $menu . remove ( ) ;
864- this . #menuActive = false ;
906+ if ( clearActive ) {
907+ this . #menuActive = false ;
908+ }
865909 }
866910
867911 #moveCursorToCoords( x , y ) {
0 commit comments