1- const dSurface = document . getElementById ( "dSurface" ) ;
1+ async function getDAll ( { timeoutMs = 5000 } = { } ) {
2+ const existing = document . getElementById ( "dAll" ) ;
3+ if ( existing ) {
4+ return existing ;
5+ }
6+
7+ // if the DOM isn't ready yet, wait for it first
8+ if ( document . readyState === "loading" ) {
9+ await new Promise ( ( resolve ) => document . addEventListener ( "DOMContentLoaded" , resolve , { once : true } ) ) ;
10+ const afterDom = document . getElementById ( "dAll" ) ;
11+ if ( afterDom ) {
12+ return afterDom ;
13+ }
14+ }
15+
16+ // wait for late insertion of #dAll
17+ return await new Promise ( ( resolve , reject ) => {
18+ const start = Date . now ( ) ;
19+ const observer = new MutationObserver ( ( ) => {
20+ const el = document . getElementById ( "dAll" ) ;
21+ if ( el ) {
22+ observer . disconnect ( ) ;
23+ resolve ( el ) ;
24+ }
25+ } ) ;
26+
27+ observer . observe ( document . documentElement , { childList : true , subtree : true } ) ;
28+
29+ const tick = ( ) => {
30+ const el = document . getElementById ( "dAll" ) ;
31+ if ( el ) {
32+ observer . disconnect ( ) ;
33+ resolve ( el ) ;
34+ return ;
35+ }
36+ if ( Date . now ( ) - start >= timeoutMs ) {
37+ observer . disconnect ( ) ;
38+ reject ( new Error ( "LoadMenu: #dAll was not found (timed out waiting for it)." ) ) ;
39+ return ;
40+ }
41+ requestAnimationFrame ( tick ) ;
42+ } ;
43+ tick ( ) ;
44+ } ) ;
45+ }
46+
47+ const visibleMenus = [ ] ;
48+ let menusAmount = 0 ;
249
350async function PreloadMenu ( menuId ) {
451 // fetch menu/html/{menuId}.html and menu/js/{menuId}.js, return nothing and do nothing with it
@@ -9,7 +56,9 @@ async function PreloadMenu(menuId) {
956}
1057
1158async function LoadMenu ( menuId , background ) {
12- // fetch menu/html/{menuId}.html and menu/js/{menuId}.js. run the js code after injecting the html into the #dSurface element.
59+ menusAmount ++ ;
60+ const dAll = await getDAll ( ) ;
61+ // fetch menu/html/{menuId}.html and menu/js/{menuId}.js. run the js code after injecting the html into the #dAll element.
1362 const [ htmlResponse , jsResponse ] = await Promise . all ( [ fetch ( `menu/html/${ menuId } .html` ) , fetch ( `menu/js/${ menuId } .js` ) ] ) ;
1463
1564 const html = await htmlResponse . text ( ) ;
@@ -24,23 +73,35 @@ async function LoadMenu(menuId, background) {
2473 menuContainer . style . height = "100%" ;
2574 menuContainer . style . top = "0" ;
2675 menuContainer . style . left = "0" ;
76+ menuContainer . style . zIndex = 9999 + menusAmount ;
2777 if ( background ) {
2878 menuContainer . style . background = `url(${ background } ) no-repeat` ;
2979 }
3080 menuContainer . innerHTML = html ;
31- dSurface . appendChild ( menuContainer ) ;
81+
82+ // inject first so the menu script can query its DOM
83+ dAll . appendChild ( menuContainer ) ;
84+ await new Promise ( ( resolve ) => requestAnimationFrame ( resolve ) ) ;
3285
3386 // run the js code (provide menuContainer to the menu script)
3487 const runMenuScript = new Function ( "menuContainer" , "menuId" , `"use strict";\n${ js } \n` ) ;
3588 runMenuScript ( menuContainer , menuId , background ) ;
3689
90+ visibleMenus . push ( menuId ) ;
91+ console . log ( menuContainer ) ;
92+
3793 return menuContainer ;
3894}
3995
4096async function UnloadMenu ( menuId ) {
41- // remove the menu menuContainer from #dSurface
97+ const dAll = await getDAll ( ) ;
98+ // remove the menu menuContainer from #dAll
4299 const menuContainer = document . getElementById ( `dMenu_${ menuId } ` ) ;
43100 if ( menuContainer ) {
44- dSurface . removeChild ( menuContainer ) ;
101+ dAll . removeChild ( menuContainer ) ;
102+ }
103+ const index = visibleMenus . indexOf ( menuId ) ;
104+ if ( index !== - 1 ) {
105+ visibleMenus . splice ( index , 1 ) ;
45106 }
46107}
0 commit comments