From 208f6fba8e3895b98585911892b77dab0b9ccef4 Mon Sep 17 00:00:00 2001 From: Shaun Struwig <41984034+Blargian@users.noreply.github.com> Date: Wed, 24 Jun 2026 18:13:34 +0200 Subject: [PATCH] Fix nav scripts: remove dead interceptors, debounce observer, scope navbar hide - ask-ai-button.js: remove capture-phase click/mousedown/keydown interceptors for Mintlify native search ('Can you tell me about') since we replaced native search with Inkeep - tab-nav.js: debounce MutationObserver via RAF so rapid React re-renders batch into one flush instead of thrashing main thread with repeated querySelectorAll calls - styles.css: scope navbar opacity-hide to .ch-homepage only so SPA page navigation doesn't trigger the fade-in on every page Co-Authored-By: Claude Sonnet 4.6 (1M context) --- _site/customizations/ask-ai-button.js | 40 --------------------------- _site/customizations/tab-nav.js | 21 +++++++++----- _site/styles.css | 10 +++---- 3 files changed, 19 insertions(+), 52 deletions(-) diff --git a/_site/customizations/ask-ai-button.js b/_site/customizations/ask-ai-button.js index c5d68922a..d45caccdb 100644 --- a/_site/customizations/ask-ai-button.js +++ b/_site/customizations/ask-ai-button.js @@ -88,50 +88,10 @@ return true; } - function isAskAiOption(el) { - if (!el || el.nodeType !== 1) return false; - var option = el.closest && el.closest('[role="option"]'); - if (!option) return false; - return /^\s*Can you tell me about\b/i.test(option.textContent || ''); - } - - function getSearchQuery() { - var input = document.querySelector('input[placeholder="Search..."]'); - return input ? input.value.trim() : ''; - } - - function openCustomAskAi() { - var query = getSearchQuery(); - document.dispatchEvent(new KeyboardEvent('keydown', { key: 'Escape', bubbles: true })); - openKapa(query); - } - - function interceptAskAi(e) { - if (!isAskAiOption(e.target)) return; - e.preventDefault(); - e.stopPropagation(); - if (typeof e.stopImmediatePropagation === 'function') e.stopImmediatePropagation(); - if (e.type === 'keydown' && e.key !== 'Enter') return; - openCustomAskAi(); - } - function init() { injectButton(); injectMobileButton(); - document.addEventListener('click', interceptAskAi, true); - document.addEventListener('mousedown', interceptAskAi, true); - document.addEventListener('keydown', function (e) { - if (e.key !== 'Enter') return; - var active = document.querySelector('[role="option"][data-headlessui-state*="active"], [role="option"][aria-selected="true"]'); - if (active && /^\s*Can you tell me about\b/i.test(active.textContent || '')) { - e.preventDefault(); - e.stopPropagation(); - if (typeof e.stopImmediatePropagation === 'function') e.stopImmediatePropagation(); - openCustomAskAi(); - } - }, true); - var observer = new MutationObserver(function () { injectButton(); injectMobileButton(); diff --git a/_site/customizations/tab-nav.js b/_site/customizations/tab-nav.js index 8abc0bf79..20379df49 100644 --- a/_site/customizations/tab-nav.js +++ b/_site/customizations/tab-nav.js @@ -207,15 +207,22 @@ setupHomepageNavbar(); patchTabButtons(); styleDropdownHeaders(); - requestAnimationFrame(markNavbarReady); + markNavbarReady(); + // Debounce: batch rapid React re-renders into one RAF flush so repeated + // querySelectorAll calls don't thrash the main thread on every DOM change. + var rafId = null; var observer = new MutationObserver(function () { - applyHomepageClass(); - setupHomepageNavbar(); - updateLogoTheme(); - patchTabButtons(); - styleDropdownHeaders(); - requestAnimationFrame(markNavbarReady); + if (rafId) return; + rafId = requestAnimationFrame(function () { + rafId = null; + applyHomepageClass(); + setupHomepageNavbar(); + updateLogoTheme(); + patchTabButtons(); + styleDropdownHeaders(); + markNavbarReady(); + }); }); observer.observe(document.documentElement, { childList: true, subtree: true }); diff --git a/_site/styles.css b/_site/styles.css index 27073ef50..4a8b51730 100644 --- a/_site/styles.css +++ b/_site/styles.css @@ -144,13 +144,13 @@ body[data-scroll-locked] { padding-right: calc(48px + 206px) !important; } -/* Navbar hidden on initial paint; revealed by tab-nav.js once both the logo - (homepage) and CTA have been injected. Hiding during injection means no - layout shifts are visible regardless of injection order or timing. */ -#navbar-transition-maple { +/* Navbar hidden only on the homepage initial paint to prevent a visible + layout shift when the logo + CTA are injected. Scoping to .ch-homepage + prevents the SPA navigation fade-in on every page change. */ +.ch-homepage #navbar-transition-maple:not(.ch-navbar-ready) { opacity: 0; } -#navbar-transition-maple.ch-navbar-ready { +.ch-homepage #navbar-transition-maple.ch-navbar-ready { opacity: 1; transition: opacity 0.15s ease-out; }