1- import { div , handleClick , hide , press , release , show } from './util'
1+ import { div , enableScroll , handleClick , hide , press , release , show } from './util'
22
33export function hideContextMenu ( ) {
44 hide ( document . querySelector ( '.fcitx-keyboard-contextmenu-container' ) ! )
@@ -7,6 +7,7 @@ export function hideContextMenu() {
77export function renderContextmenu ( ) {
88 const container = div ( 'fcitx-keyboard-contextmenu-container' )
99 const contextmenu = div ( 'fcitx-keyboard-contextmenu' )
10+ enableScroll ( contextmenu )
1011 container . appendChild ( contextmenu )
1112 container . addEventListener ( 'touchstart' , ( event ) => {
1213 // Don't hide if touching menu instead of outside.
@@ -29,17 +30,27 @@ function renderItem(text: string) {
2930
3031export function showContextmenu ( element : Element , items : {
3132 text : string
33+ separator ?: boolean
3234 callback : ( ) => void
3335} [ ] ) {
3436 const contextmenu = document . querySelector ( '.fcitx-keyboard-contextmenu' ) as HTMLElement
3537 contextmenu . innerHTML = ''
36- for ( const item of items ) {
37- const element = renderItem ( item . text )
38- handleClick ( element , ( ) => {
39- item . callback ( )
40- hideContextMenu ( )
41- } )
42- contextmenu . appendChild ( element )
38+ for ( let i = 0 ; i < items . length ; i ++ ) {
39+ const item = items [ i ]
40+ if ( item . separator ) {
41+ if ( i === 0 || i === items . length - 1 || items [ i - 1 ] . separator ) {
42+ continue
43+ }
44+ contextmenu . appendChild ( document . createElement ( 'hr' ) )
45+ }
46+ else {
47+ const element = renderItem ( item . text )
48+ handleClick ( element , ( ) => {
49+ item . callback ( )
50+ hideContextMenu ( )
51+ } )
52+ contextmenu . appendChild ( element )
53+ }
4354 }
4455 show ( contextmenu . parentElement ! )
4556 const containerBox = contextmenu . parentElement ! . getBoundingClientRect ( )
@@ -48,12 +59,21 @@ export function showContextmenu(element: Element, items: {
4859 const containerYBar = ( containerBox . top + containerBox . bottom ) / 2
4960 const targetYBar = ( targetBox . top + targetBox . bottom ) / 2
5061 let y : number
62+ // First step: place it above or below the target element.
5163 if ( targetYBar < containerYBar ) {
5264 y = targetBox . bottom
5365 }
5466 else {
5567 y = targetBox . top - menuBox . height
5668 }
69+ // Next step: adjust the bottom position if it exceeds the container.
70+ if ( y + menuBox . height > containerBox . bottom ) {
71+ y = containerBox . bottom - menuBox . height
72+ }
73+ // Final step: adjust the top position if it exceeds the container.
74+ if ( y < containerBox . top ) {
75+ y = containerBox . top
76+ }
5777 const x = Math . min ( targetBox . left , containerBox . right - menuBox . width )
5878 contextmenu . style . left = `${ x } px`
5979 contextmenu . style . top = `${ y } px`
0 commit comments