diff --git a/src/Components/Web.JS/src/Boot.Web.ts b/src/Components/Web.JS/src/Boot.Web.ts index df605ceebc52..48b9a51b7e40 100644 --- a/src/Components/Web.JS/src/Boot.Web.ts +++ b/src/Components/Web.JS/src/Boot.Web.ts @@ -65,13 +65,13 @@ function boot(options?: Partial) : Promise { }, }; - attachComponentDescriptorHandler(rootComponentManager); - attachStreamingRenderingListener(options?.ssr, navigationEnhancementCallbacks); - if (!options?.ssr?.disableDomPreservation) { attachProgressivelyEnhancedNavigationListener(navigationEnhancementCallbacks); } + attachComponentDescriptorHandler(rootComponentManager); + attachStreamingRenderingListener(options?.ssr, navigationEnhancementCallbacks); + enableFocusOnNavigate(jsEventRegistry); // Wait until the initial page response completes before activating interactive components. diff --git a/src/Components/Web.JS/src/Services/NavigationEnhancement.ts b/src/Components/Web.JS/src/Services/NavigationEnhancement.ts index e029c77178dd..4ffd97561136 100644 --- a/src/Components/Web.JS/src/Services/NavigationEnhancement.ts +++ b/src/Components/Web.JS/src/Services/NavigationEnhancement.ts @@ -37,11 +37,18 @@ const acceptHeader = 'text/html; blazor-enhanced-nav=on'; let currentEnhancedNavigationAbortController: AbortController | null; let navigationEnhancementCallbacks: NavigationEnhancementCallbacks; let performingEnhancedPageLoad: boolean; +let navigationEnhancementCallbacksPromise: Promise | null = null; +let navigationEnhancementCallbacksResolver: ((callbacks: NavigationEnhancementCallbacks) => void) | null = null; // This gets initialized to the current URL when we load. // After that, it gets updated every time we successfully complete a navigation. let currentContentUrl = location.href; +// Initialize the promise for waiting for navigation enhancement callbacks +navigationEnhancementCallbacksPromise = new Promise((resolve) => { + navigationEnhancementCallbacksResolver = resolve; +}); + export interface NavigationEnhancementCallbacks { enhancedNavigationStarted: () => void; documentUpdated: () => void; @@ -58,6 +65,14 @@ export function hasNeverStartedAnyEnhancedPageLoad() { export function attachProgressivelyEnhancedNavigationListener(callbacks: NavigationEnhancementCallbacks) { navigationEnhancementCallbacks = callbacks; + + // Resolve the promise so any waiting performEnhancedPageLoad calls can proceed + if (navigationEnhancementCallbacksResolver) { + navigationEnhancementCallbacksResolver(callbacks); + navigationEnhancementCallbacksResolver = null; + navigationEnhancementCallbacksPromise = null; + } + document.addEventListener('click', onDocumentClick); document.addEventListener('submit', onDocumentSubmit); window.addEventListener('popstate', onPopState); @@ -195,6 +210,10 @@ function onDocumentSubmit(event: SubmitEvent) { export async function performEnhancedPageLoad(internalDestinationHref: string, interceptedLink: boolean, fetchOptions?: RequestInit, treatAsRedirectionFromMethod?: 'get' | 'post', changeUrl: boolean = true) { performingEnhancedPageLoad = true; + if (!navigationEnhancementCallbacks && navigationEnhancementCallbacksPromise) { + navigationEnhancementCallbacks = await navigationEnhancementCallbacksPromise; + } + // First, stop any preceding enhanced page load currentEnhancedNavigationAbortController?.abort(); diff --git a/src/Components/test/E2ETest/ServerRenderingTests/NoInteractivityTest.cs b/src/Components/test/E2ETest/ServerRenderingTests/NoInteractivityTest.cs index bbeb1ad4d9bb..80ee146b94af 100644 --- a/src/Components/test/E2ETest/ServerRenderingTests/NoInteractivityTest.cs +++ b/src/Components/test/E2ETest/ServerRenderingTests/NoInteractivityTest.cs @@ -205,7 +205,7 @@ private void AssertNotFoundRendered_ResponseStarted_Or_POST(bool hasReExecutionM public void NotFoundSetOnFormSubmit_ResponseNotStarted_SSR(bool hasReExecutionMiddleware, bool hasCustomNotFoundPageSet) { string reexecution = hasReExecutionMiddleware ? "/reexecution" : ""; - string testUrl = $"{ServerPathBase}{reexecution}/post-not-found-ssr-streaming?useCustomNotFoundPage={hasCustomNotFoundPageSet}"; + string testUrl = $"{ServerPathBase}{reexecution}/post-not-found-ssr?useCustomNotFoundPage={hasCustomNotFoundPageSet}"; Navigate(testUrl); Browser.FindElement(By.Id("not-found-form")).FindElement(By.TagName("button")).Click();