From 173eab8026094977996c115485be73aa285a9871 Mon Sep 17 00:00:00 2001 From: Jonathan Sykes Date: Thu, 8 Oct 2026 01:36:47 +0800 Subject: [PATCH] Preserve Settings control search with lazy feature panels --- frontend/settings-sections.js | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/frontend/settings-sections.js b/frontend/settings-sections.js index d5e7f3e..20a21c8 100644 --- a/frontend/settings-sections.js +++ b/frontend/settings-sections.js @@ -24,7 +24,8 @@ const icon = paths => ``; function mount(host, context = {}) { dispose(); - const document = host.ownerDocument, win = document.defaultView, sections = registry.list(), panels = new Map(), rows = new Map(), cleanups = []; + const document = host.ownerDocument, win = document.defaultView, sections = registry.list(), panels = new Map(), rows = new Map(), cleanups = [], searchLoads = new Set(); + let mounted = true; let remembered = ''; try { remembered = win.sessionStorage.getItem('ytpSettingsSection') || ''; } catch {} let active = registry.get(remembered) ? remembered : sections[0]?.id; host.classList.add('settings-browser'); @@ -80,6 +81,19 @@ function filter() { const query = input.value.trim(); results.replaceChildren(); results.hidden = !query; grid.hidden = !!query; if (!query) { empty.hidden = true; return; } + // Searching is explicit feature intent. Mount optional controls so their + // existing labels/help remain searchable without parsing them on opening Settings. + for (const section of sections) { + const panel=panels.get(section.id); + if(!section.lazyGroup || panel.dataset.rendered || searchLoads.has(section.id))continue; + searchLoads.add(section.id); + root.Lazy.load(section.lazyGroup).then(()=>{ + if(!mounted || !host.isConnected || panel.dataset.rendered)return; + panel.dataset.rendered='1'; + const cleanup=registry.get(section.id).render(panel,context);if(typeof cleanup==='function')cleanups.push(cleanup); + filter(); + }).catch(()=>searchLoads.delete(section.id)); + } const entries = []; for (const section of sections) { entries.push({ title: section.title, description: section.description || '', section: section.id }); @@ -101,11 +115,11 @@ const pop = event => { if (!host.isConnected) return; show(event.state?.ytpSettingsSection || active, !!event.state?.ytpSettingsSection); if (!event.state?.ytpSettingsSection) rows.get(active)?.button.focus({ preventScroll: true }); }; win.addEventListener('popstate', pop); input.addEventListener('input', filter); host.addEventListener('change', summaries); host.addEventListener('input', summaries); - const observer = new win.MutationObserver(summaries); observer.observe(detail, { childList: true, subtree: true, characterData: true }); + const observer = new win.MutationObserver(()=>{summaries();if(input.value.trim())filter();}); observer.observe(detail, { childList: true, subtree: true, characterData: true }); const state = win.history.state?.ytpSettingsSection; if (!state) win.history.replaceState({ ...win.history.state, ytpSettingsSection: null }, '', win.location.href); show(state || active, !!state); summaries(); - dispose = () => { observer.disconnect(); win.removeEventListener('popstate', pop); cleanups.forEach(fn => fn()); }; + dispose = () => { mounted=false;observer.disconnect(); win.removeEventListener('popstate', pop); cleanups.forEach(fn => fn()); }; return { open, refresh: summaries, dispose }; } const api = { ...registry, mount, search, normalize, createRegistry, clusters };