/** Route racine d'une démo (`demo/mail`, `demo/drive`, …). */ export function getDemoRouteRoot(pathname: string): string | null { if (!pathname.startsWith("/demo/")) return null const segments = pathname.split("/").filter(Boolean) if (segments[0] !== "demo" || !segments[1]) return null return `demo/${segments[1]}` } function isExternalHref(href: string): boolean { return ( href.startsWith("http://") || href.startsWith("https://") || href.startsWith("mailto:") || href.startsWith("tel:") || href.startsWith("javascript:") ) } /** Normalise un href interne vers `pathname + search + hash`, ou `null` si hors scope. */ export function normalizeInternalHref(href: string, origin = window.location.origin): string | null { const trimmed = href.trim() if (!trimmed || trimmed === "#" || trimmed.startsWith("#")) return null if (isExternalHref(trimmed)) return null try { const url = new URL(trimmed, origin) if (url.origin !== origin) return null return `${url.pathname}${url.search}${url.hash}` } catch { return null } } /** True si la navigation reste dans la démo courante (`/demo/mail/...`, etc.). */ export function isHrefWithinDemoScope( href: string, demoRouteRoot: string, origin = window.location.origin ): boolean { const internal = normalizeInternalHref(href, origin) if (internal === null) return true const prefix = `/${demoRouteRoot}` return internal === prefix || internal.startsWith(`${prefix}/`) }