fix: stop the menu-editor button-patch interval once it succeeds

setupOldButton() polled the DOM every 4s forever after the menu editor
first opened, with no way to ever stop - the interval id was not even
kept in a variable. It now returns whether the button was found, the
interval only starts when the first attempt fails, and clears itself
on the first successful attempt (also wired into the existing
disconnect() cleanup alongside the other timers).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
pavlov346346-source 2026-09-12 14:09:06 +03:00
parent a08633f9d0
commit 4106452f56

View File

@ -53,7 +53,7 @@
} }
// ---------- Developer support: full read-only visibility + live refresh ---------- // ---------- Developer support: full read-only visibility + live refresh ----------
let supportBusy=false,supportLastAt=0,supportTimer=0,originalHasPermission=null; let supportBusy=false,supportLastAt=0,supportTimer=0,originalHasPermission=null,oldButtonTimer=0;
function supportReadPermission(permission){ function supportReadPermission(permission){
const p=String(permission||''); const p=String(permission||'');
if(p==='app.read'||p.endsWith('.view'))return true; if(p==='app.read'||p.endsWith('.view'))return true;
@ -163,7 +163,8 @@
$('sunMenuSearchV1762').oninput=e=>{menuQuery=e.target.value||'';renderMenuList()}; $('sunMenuSearchV1762').oninput=e=>{menuQuery=e.target.value||'';renderMenuList()};
$('sunMenuAddV1762').onclick=()=>{if(!menuCanEdit())return toast('В этом режиме каталог доступен только для просмотра.','warn');window.editBox?.(null);setTimeout(()=>{const select=$('itemCategory');if(select){select.value=String(menuCategory);select.dispatchEvent(new Event('change',{bubbles:true}))}dockEditor();},0)}; $('sunMenuAddV1762').onclick=()=>{if(!menuCanEdit())return toast('В этом режиме каталог доступен только для просмотра.','warn');window.editBox?.(null);setTimeout(()=>{const select=$('itemCategory');if(select){select.value=String(menuCategory);select.dispatchEvent(new Event('change',{bubbles:true}))}dockEditor();},0)};
document.addEventListener('click',e=>{const b=e.target.closest('header nav button');if(b&&b!==menuButton)leaveMenu();},true); document.addEventListener('click',e=>{const b=e.target.closest('header nav button');if(b&&b!==menuButton)leaveMenu();},true);
const setupOldButton=()=>{const old=qa('#new .catalog-head button').find(b=>/настроить|редактор/i.test(b.textContent||''));if(old&&!old.__sunV1762){old.__sunV1762=true;old.textContent='Меню';old.onclick=e=>{e.preventDefault();e.stopPropagation();openMenu();};}};setupOldButton();setInterval(setupOldButton,4000); const setupOldButton=()=>{const old=qa('#new .catalog-head button').find(b=>/настроить|редактор/i.test(b.textContent||''));if(!old)return false;if(!old.__sunV1762){old.__sunV1762=true;old.textContent='Меню';old.onclick=e=>{e.preventDefault();e.stopPropagation();openMenu();};}return true;};
if(!setupOldButton()&&!oldButtonTimer)oldButtonTimer=setInterval(()=>{if(setupOldButton()){clearInterval(oldButtonTimer);oldButtonTimer=0;}},4000);
syncMenuPermission(); syncMenuPermission();
} }
function syncMenuPermission(){if(!menuButton)return;const c=cloud();const signed=Boolean(c?.getSession?.()?.user);const allowed=!signed||support()||can('catalog.view')||can('catalog.edit');menuButton.hidden=!allowed;menuButton.style.display=allowed?'':'none';const add=$('sunMenuAddV1762');if(add){add.disabled=!menuCanEdit();add.title=menuCanEdit()?'':'Только просмотр';}} function syncMenuPermission(){if(!menuButton)return;const c=cloud();const signed=Boolean(c?.getSession?.()?.user);const allowed=!signed||support()||can('catalog.view')||can('catalog.edit');menuButton.hidden=!allowed;menuButton.style.display=allowed?'':'none';const add=$('sunMenuAddV1762');if(add){add.disabled=!menuCanEdit();add.title=menuCanEdit()?'':'Только просмотр';}}
@ -253,7 +254,7 @@
window.addEventListener('sun:cloud-state-applied',()=>{maintainSupport();syncMenuPermission();if(menuActive)renderMenuList();setTimeout(enhanceRoutePage,80)}); window.addEventListener('sun:cloud-state-applied',()=>{maintainSupport();syncMenuPermission();if(menuActive)renderMenuList();setTimeout(enhanceRoutePage,80)});
const mo=new MutationObserver(records=>{let route=false,supportBanner=false;for(const r of records){for(const n of r.addedNodes){if(n.nodeType!==1)continue;if(n.id==='routeContent'||n.querySelector?.('#routeContent')||n.closest?.('#sun-routes-view'))route=true;if(n.id==='sunDevSupportBannerV22'||n.querySelector?.('#sunDevSupportBannerV22'))supportBanner=true;}}if(route)setTimeout(enhanceRoutePage,30);if(supportBanner)setTimeout(renderSupportStatus,20);});mo.observe(document.documentElement,{childList:true,subtree:true}); const mo=new MutationObserver(records=>{let route=false,supportBanner=false;for(const r of records){for(const n of r.addedNodes){if(n.nodeType!==1)continue;if(n.id==='routeContent'||n.querySelector?.('#routeContent')||n.closest?.('#sun-routes-view'))route=true;if(n.id==='sunDevSupportBannerV22'||n.querySelector?.('#sunDevSupportBannerV22'))supportBanner=true;}}if(route)setTimeout(enhanceRoutePage,30);if(supportBanner)setTimeout(renderSupportStatus,20);});mo.observe(document.documentElement,{childList:true,subtree:true});
if(!maintenanceTimer)maintenanceTimer=setInterval(()=>{if(document.hidden)return;maintainSupport();syncMenuPermission();if($('sun-routes-view')?.classList.contains('on'))enhanceRoutePage();},8000); if(!maintenanceTimer)maintenanceTimer=setInterval(()=>{if(document.hidden)return;maintainSupport();syncMenuPermission();if($('sun-routes-view')?.classList.contains('on'))enhanceRoutePage();},8000);
window.SunOpsUXV1762={VERSION,RELEASE,refreshSupport,openMenu,showRouteOrder,enhanceRoutePage,checks:loadSelfChecks,disconnect:()=>{mo.disconnect();if(maintenanceTimer){clearInterval(maintenanceTimer);maintenanceTimer=0}if(supportTimer){clearInterval(supportTimer);supportTimer=0}if(waitTimer){clearTimeout(waitTimer);waitTimer=0}}}; window.SunOpsUXV1762={VERSION,RELEASE,refreshSupport,openMenu,showRouteOrder,enhanceRoutePage,checks:loadSelfChecks,disconnect:()=>{mo.disconnect();if(maintenanceTimer){clearInterval(maintenanceTimer);maintenanceTimer=0}if(supportTimer){clearInterval(supportTimer);supportTimer=0}if(waitTimer){clearTimeout(waitTimer);waitTimer=0}if(oldButtonTimer){clearInterval(oldButtonTimer);oldButtonTimer=0}}};
} }
const waitForApp=()=>{if(window.SunCloudV2&&document.querySelector('header nav')&&typeof window.editBox==='function'){if(waitTimer){clearTimeout(waitTimer);waitTimer=0}boot();return}waitAttempts++;if(waitAttempts>=120){console.warn('[Caterium ops UX] app prerequisites timed out; waiting for a cloud-state event');return}waitTimer=setTimeout(waitForApp,250)}; const waitForApp=()=>{if(window.SunCloudV2&&document.querySelector('header nav')&&typeof window.editBox==='function'){if(waitTimer){clearTimeout(waitTimer);waitTimer=0}boot();return}waitAttempts++;if(waitAttempts>=120){console.warn('[Caterium ops UX] app prerequisites timed out; waiting for a cloud-state event');return}waitTimer=setTimeout(waitForApp,250)};
window.addEventListener('sun:cloud-state-applied',()=>{if(!window.SunOpsUXV1762&&waitAttempts>=120){waitAttempts=0;waitForApp()}}); window.addEventListener('sun:cloud-state-applied',()=>{if(!window.SunOpsUXV1762&&waitAttempts>=120){waitAttempts=0;waitForApp()}});