@wordpress/interactivity-router 1.7.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"names":["store","privateApis","getConfig","fetchHeadAssets","updateHead","directivePrefix","getRegionRootFragment","initialVdom","toVdom","render","parseInitialData","populateInitialData","batch","navigationMode","_getConfig$navigation","pages","Map","headElements","getPagePath","url","u","URL","window","location","pathname","search","fetchPage","html","res","fetch","status","text","dom","DOMParser","parseFromString","regionsToVdom","e","vdom","regions","head","process","env","IS_GUTENBERG_PLUGIN","body","get","document","attrName","querySelectorAll","forEach","region","id","getAttribute","has","title","querySelector","innerText","initialData","renderRegions","page","fragment","forcePageReload","href","assign","Promise","addEventListener","pagePath","state","reload","map","call","script","set","tag","textContent","resolve","isValidLink","ref","HTMLAnchorElement","target","origin","startsWith","searchParams","isValidEvent","event","button","metaKey","ctrlKey","altKey","shiftKey","defaultPrevented","navigatingTo","actions","navigation","hasStarted","hasFinished","texts","navigate","options","clientNavigationDisabled","loadingAnimation","screenReaderAnnouncement","timeout","prefetch","timeoutPromise","setTimeout","loadingTimeout","message","loading","race","clearTimeout","config","history","replace","loaded","hash","scrollIntoView","force","closest","preventDefault","nodeName"],"sources":["@wordpress/interactivity-router/src/index.js"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { store, privateApis, getConfig } from '@wordpress/interactivity';\n\n/**\n * Internal dependencies\n */\nimport { fetchHeadAssets, updateHead } from './head';\n\nconst {\n\tdirectivePrefix,\n\tgetRegionRootFragment,\n\tinitialVdom,\n\ttoVdom,\n\trender,\n\tparseInitialData,\n\tpopulateInitialData,\n\tbatch,\n} = privateApis(\n\t'I acknowledge that using private APIs means my theme or plugin will inevitably break in the next version of WordPress.'\n);\n\n// Check if the navigation mode is full page or region based.\nconst navigationMode =\n\tgetConfig( 'core/router' ).navigationMode ?? 'regionBased';\n\n// The cache of visited and prefetched pages, stylesheets and scripts.\nconst pages = new Map();\nconst headElements = new Map();\n\n// Helper to remove domain and hash from the URL. We are only interesting in\n// caching the path and the query.\nconst getPagePath = ( url ) => {\n\tconst u = new URL( url, window.location );\n\treturn u.pathname + u.search;\n};\n\n// Fetch a new page and convert it to a static virtual DOM.\nconst fetchPage = async ( url, { html } ) => {\n\ttry {\n\t\tif ( ! html ) {\n\t\t\tconst res = await window.fetch( url );\n\t\t\tif ( res.status !== 200 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\thtml = await res.text();\n\t\t}\n\t\tconst dom = new window.DOMParser().parseFromString( html, 'text/html' );\n\t\treturn regionsToVdom( dom );\n\t} catch ( e ) {\n\t\treturn false;\n\t}\n};\n\n// Return an object with VDOM trees of those HTML regions marked with a\n// `router-region` directive.\nconst regionsToVdom = async ( dom, { vdom } = {} ) => {\n\tconst regions = {};\n\tlet head;\n\tif ( process.env.IS_GUTENBERG_PLUGIN ) {\n\t\tif ( navigationMode === 'fullPage' ) {\n\t\t\thead = await fetchHeadAssets( dom, headElements );\n\t\t\tregions.body = vdom\n\t\t\t\t? vdom.get( document.body )\n\t\t\t\t: toVdom( dom.body );\n\t\t}\n\t}\n\tif ( navigationMode === 'regionBased' ) {\n\t\tconst attrName = `data-${ directivePrefix }-router-region`;\n\t\tdom.querySelectorAll( `[${ attrName }]` ).forEach( ( region ) => {\n\t\t\tconst id = region.getAttribute( attrName );\n\t\t\tregions[ id ] = vdom?.has( region )\n\t\t\t\t? vdom.get( region )\n\t\t\t\t: toVdom( region );\n\t\t} );\n\t}\n\tconst title = dom.querySelector( 'title' )?.innerText;\n\tconst initialData = parseInitialData( dom );\n\treturn { regions, head, title, initialData };\n};\n\n// Render all interactive regions contained in the given page.\nconst renderRegions = ( page ) => {\n\tbatch( () => {\n\t\tif ( process.env.IS_GUTENBERG_PLUGIN ) {\n\t\t\tif ( navigationMode === 'fullPage' ) {\n\t\t\t\t// Once this code is tested and more mature, the head should be updated for region based navigation as well.\n\t\t\t\tupdateHead( page.head );\n\t\t\t\tconst fragment = getRegionRootFragment( document.body );\n\t\t\t\trender( page.regions.body, fragment );\n\t\t\t}\n\t\t}\n\t\tif ( navigationMode === 'regionBased' ) {\n\t\t\tpopulateInitialData( page.initialData );\n\t\t\tconst attrName = `data-${ directivePrefix }-router-region`;\n\t\t\tdocument\n\t\t\t\t.querySelectorAll( `[${ attrName }]` )\n\t\t\t\t.forEach( ( region ) => {\n\t\t\t\t\tconst id = region.getAttribute( attrName );\n\t\t\t\t\tconst fragment = getRegionRootFragment( region );\n\t\t\t\t\trender( page.regions[ id ], fragment );\n\t\t\t\t} );\n\t\t}\n\t\tif ( page.title ) {\n\t\t\tdocument.title = page.title;\n\t\t}\n\t} );\n};\n\n/**\n * Load the given page forcing a full page reload.\n *\n * The function returns a promise that won't resolve, useful to prevent any\n * potential feedback indicating that the navigation has finished while the new\n * page is being loaded.\n *\n * @param {string} href The page href.\n * @return {Promise} Promise that never resolves.\n */\nconst forcePageReload = ( href ) => {\n\twindow.location.assign( href );\n\treturn new Promise( () => {} );\n};\n\n// Listen to the back and forward buttons and restore the page if it's in the\n// cache.\nwindow.addEventListener( 'popstate', async () => {\n\tconst pagePath = getPagePath( window.location ); // Remove hash.\n\tconst page = pages.has( pagePath ) && ( await pages.get( pagePath ) );\n\tif ( page ) {\n\t\trenderRegions( page );\n\t\t// Update the URL in the state.\n\t\tstate.url = window.location.href;\n\t} else {\n\t\twindow.location.reload();\n\t}\n} );\n\n// Initialize the router and cache the initial page using the initial vDOM.\n// Once this code is tested and more mature, the head should be updated for region based navigation as well.\nif ( process.env.IS_GUTENBERG_PLUGIN ) {\n\tif ( navigationMode === 'fullPage' ) {\n\t\t// Cache the scripts. Has to be called before fetching the assets.\n\t\t[].map.call( document.querySelectorAll( 'script[src]' ), ( script ) => {\n\t\t\theadElements.set( script.getAttribute( 'src' ), {\n\t\t\t\ttag: script,\n\t\t\t\ttext: script.textContent,\n\t\t\t} );\n\t\t} );\n\t\tawait fetchHeadAssets( document, headElements );\n\t}\n}\npages.set(\n\tgetPagePath( window.location ),\n\tPromise.resolve( regionsToVdom( document, { vdom: initialVdom } ) )\n);\n\n// Check if the link is valid for client-side navigation.\nconst isValidLink = ( ref ) =>\n\tref &&\n\tref instanceof window.HTMLAnchorElement &&\n\tref.href &&\n\t( ! ref.target || ref.target === '_self' ) &&\n\tref.origin === window.location.origin &&\n\t! ref.pathname.startsWith( '/wp-admin' ) &&\n\t! ref.pathname.startsWith( '/wp-login.php' ) &&\n\t! ref.getAttribute( 'href' ).startsWith( '#' ) &&\n\t! new URL( ref.href ).searchParams.has( '_wpnonce' );\n\n// Check if the event is valid for client-side navigation.\nconst isValidEvent = ( event ) =>\n\tevent &&\n\tevent.button === 0 && // Left clicks only.\n\t! event.metaKey && // Open in new tab (Mac).\n\t! event.ctrlKey && // Open in new tab (Windows).\n\t! event.altKey && // Download.\n\t! event.shiftKey &&\n\t! event.defaultPrevented;\n\n// Variable to store the current navigation.\nlet navigatingTo = '';\n\nexport const { state, actions } = store( 'core/router', {\n\tstate: {\n\t\turl: window.location.href,\n\t\tnavigation: {\n\t\t\thasStarted: false,\n\t\t\thasFinished: false,\n\t\t\ttexts: {},\n\t\t},\n\t},\n\tactions: {\n\t\t/**\n\t\t * Navigates to the specified page.\n\t\t *\n\t\t * This function normalizes the passed href, fetchs the page HTML if\n\t\t * needed, and updates any interactive regions whose contents have\n\t\t * changed. It also creates a new entry in the browser session history.\n\t\t *\n\t\t * @param {string} href The page href.\n\t\t * @param {Object} [options] Options object.\n\t\t * @param {boolean} [options.force] If true, it forces re-fetching the URL.\n\t\t * @param {string} [options.html] HTML string to be used instead of fetching the requested URL.\n\t\t * @param {boolean} [options.replace] If true, it replaces the current entry in the browser session history.\n\t\t * @param {number} [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.\n\t\t * @param {boolean} [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.\n\t\t * @param {boolean} [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.\n\t\t *\n\t\t * @return {Promise} Promise that resolves once the navigation is completed or aborted.\n\t\t */\n\t\t*navigate( href, options = {} ) {\n\t\t\tconst { clientNavigationDisabled } = getConfig();\n\t\t\tif ( clientNavigationDisabled ) {\n\t\t\t\tyield forcePageReload( href );\n\t\t\t}\n\n\t\t\tconst pagePath = getPagePath( href );\n\t\t\tconst { navigation } = state;\n\t\t\tconst {\n\t\t\t\tloadingAnimation = true,\n\t\t\t\tscreenReaderAnnouncement = true,\n\t\t\t\ttimeout = 10000,\n\t\t\t} = options;\n\n\t\t\tnavigatingTo = href;\n\t\t\tactions.prefetch( pagePath, options );\n\n\t\t\t// Create a promise that resolves when the specified timeout ends.\n\t\t\t// The timeout value is 10 seconds by default.\n\t\t\tconst timeoutPromise = new Promise( ( resolve ) =>\n\t\t\t\tsetTimeout( resolve, timeout )\n\t\t\t);\n\n\t\t\t// Don't update the navigation status immediately, wait 400 ms.\n\t\t\tconst loadingTimeout = setTimeout( () => {\n\t\t\t\tif ( navigatingTo !== href ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( loadingAnimation ) {\n\t\t\t\t\tnavigation.hasStarted = true;\n\t\t\t\t\tnavigation.hasFinished = false;\n\t\t\t\t}\n\t\t\t\tif ( screenReaderAnnouncement ) {\n\t\t\t\t\tnavigation.message = navigation.texts.loading;\n\t\t\t\t}\n\t\t\t}, 400 );\n\n\t\t\tconst page = yield Promise.race( [\n\t\t\t\tpages.get( pagePath ),\n\t\t\t\ttimeoutPromise,\n\t\t\t] );\n\n\t\t\t// Dismiss loading message if it hasn't been added yet.\n\t\t\tclearTimeout( loadingTimeout );\n\n\t\t\t// Once the page is fetched, the destination URL could have changed\n\t\t\t// (e.g., by clicking another link in the meantime). If so, bail\n\t\t\t// out, and let the newer execution to update the HTML.\n\t\t\tif ( navigatingTo !== href ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tpage &&\n\t\t\t\t! page.initialData?.config?.[ 'core/router' ]\n\t\t\t\t\t?.clientNavigationDisabled\n\t\t\t) {\n\t\t\t\tyield renderRegions( page );\n\t\t\t\twindow.history[\n\t\t\t\t\toptions.replace ? 'replaceState' : 'pushState'\n\t\t\t\t]( {}, '', href );\n\n\t\t\t\t// Update the URL in the state.\n\t\t\t\tstate.url = href;\n\n\t\t\t\t// Update the navigation status once the the new page rendering\n\t\t\t\t// has been completed.\n\t\t\t\tif ( loadingAnimation ) {\n\t\t\t\t\tnavigation.hasStarted = false;\n\t\t\t\t\tnavigation.hasFinished = true;\n\t\t\t\t}\n\n\t\t\t\tif ( screenReaderAnnouncement ) {\n\t\t\t\t\t// Announce that the page has been loaded. If the message is the\n\t\t\t\t\t// same, we use a no-break space similar to the @wordpress/a11y\n\t\t\t\t\t// package: https://github.com/WordPress/gutenberg/blob/c395242b8e6ee20f8b06c199e4fc2920d7018af1/packages/a11y/src/filter-message.js#L20-L26\n\t\t\t\t\tnavigation.message =\n\t\t\t\t\t\tnavigation.texts.loaded +\n\t\t\t\t\t\t( navigation.message === navigation.texts.loaded\n\t\t\t\t\t\t\t? '\\u00A0'\n\t\t\t\t\t\t\t: '' );\n\t\t\t\t}\n\n\t\t\t\t// Scroll to the anchor if exits in the link.\n\t\t\t\tconst { hash } = new URL( href, window.location );\n\t\t\t\tif ( hash ) {\n\t\t\t\t\tdocument.querySelector( hash )?.scrollIntoView();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tyield forcePageReload( href );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Prefetchs the page with the passed URL.\n\t\t *\n\t\t * The function normalizes the URL and stores internally the fetch\n\t\t * promise, to avoid triggering a second fetch for an ongoing request.\n\t\t *\n\t\t * @param {string} url The page URL.\n\t\t * @param {Object} [options] Options object.\n\t\t * @param {boolean} [options.force] Force fetching the URL again.\n\t\t * @param {string} [options.html] HTML string to be used instead of fetching the requested URL.\n\t\t */\n\t\tprefetch( url, options = {} ) {\n\t\t\tconst { clientNavigationDisabled } = getConfig();\n\t\t\tif ( clientNavigationDisabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pagePath = getPagePath( url );\n\t\t\tif ( options.force || ! pages.has( pagePath ) ) {\n\t\t\t\tpages.set( pagePath, fetchPage( pagePath, options ) );\n\t\t\t}\n\t\t},\n\t},\n} );\n\n// Add click and prefetch to all links.\nif ( process.env.IS_GUTENBERG_PLUGIN ) {\n\tif ( navigationMode === 'fullPage' ) {\n\t\t// Navigate on click.\n\t\tdocument.addEventListener(\n\t\t\t'click',\n\t\t\tfunction ( event ) {\n\t\t\t\tconst ref = event.target.closest( 'a' );\n\t\t\t\tif ( isValidLink( ref ) && isValidEvent( event ) ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tactions.navigate( ref.href );\n\t\t\t\t}\n\t\t\t},\n\t\t\ttrue\n\t\t);\n\t\t// Prefetch on hover.\n\t\tdocument.addEventListener(\n\t\t\t'mouseenter',\n\t\t\tfunction ( event ) {\n\t\t\t\tif ( event.target?.nodeName === 'A' ) {\n\t\t\t\t\tconst ref = event.target.closest( 'a' );\n\t\t\t\t\tif ( isValidLink( ref ) && isValidEvent( event ) ) {\n\t\t\t\t\t\tactions.prefetch( ref.href );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\ttrue\n\t\t);\n\t}\n}\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["store","privateApis","getConfig","fetchHeadAssets","updateHead","directivePrefix","getRegionRootFragment","initialVdom","toVdom","render","parseInitialData","populateInitialData","batch","navigationMode","_getConfig$navigation","pages","Map","headElements","getPagePath","url","u","URL","window","location","href","pathname","search","fetchPage","html","res","fetch","status","text","dom","DOMParser","parseFromString","regionsToVdom","e","vdom","regions","body","undefined","head","globalThis","IS_GUTENBERG_PLUGIN","get","document","attrName","querySelectorAll","forEach","region","id","getAttribute","has","title","querySelector","innerText","initialData","renderRegions","page","fragment","forcePageReload","assign","Promise","addEventListener","pagePath","state","reload","map","call","script","set","tag","textContent","resolve","isValidLink","ref","HTMLAnchorElement","target","origin","startsWith","searchParams","isValidEvent","event","button","metaKey","ctrlKey","altKey","shiftKey","defaultPrevented","navigatingTo","actions","navigation","hasStarted","hasFinished","texts","loading","loaded","message","navigate","options","clientNavigationDisabled","loadingAnimation","screenReaderAnnouncement","timeout","prefetch","timeoutPromise","setTimeout","loadingTimeout","race","clearTimeout","config","history","replace","hash","scrollIntoView","force","closest","preventDefault","nodeName"],"sources":["@wordpress/interactivity-router/src/index.ts"],"sourcesContent":["/**\n * WordPress dependencies\n */\nimport { store, privateApis, getConfig } from '@wordpress/interactivity';\n\n/**\n * Internal dependencies\n */\nimport { fetchHeadAssets, updateHead } from './head';\n\nconst {\n\tdirectivePrefix,\n\tgetRegionRootFragment,\n\tinitialVdom,\n\ttoVdom,\n\trender,\n\tparseInitialData,\n\tpopulateInitialData,\n\tbatch,\n} = privateApis(\n\t'I acknowledge that using private APIs means my theme or plugin will inevitably break in the next version of WordPress.'\n);\n\ninterface NavigateOptions {\n\tforce?: boolean;\n\thtml?: string;\n\treplace?: boolean;\n\ttimeout?: number;\n\tloadingAnimation?: boolean;\n\tscreenReaderAnnouncement?: boolean;\n}\n\ninterface PrefetchOptions {\n\tforce?: boolean;\n\thtml?: string;\n}\n\ninterface VdomParams {\n\tvdom?: typeof initialVdom;\n}\n\ninterface Page {\n\tregions: Record< string, any >;\n\thead: HTMLHeadElement[];\n\ttitle: string;\n\tinitialData: any;\n}\n\ntype RegionsToVdom = ( dom: Document, params?: VdomParams ) => Promise< Page >;\n\n// Check if the navigation mode is full page or region based.\nconst navigationMode: 'regionBased' | 'fullPage' =\n\tgetConfig( 'core/router' ).navigationMode ?? 'regionBased';\n\n// The cache of visited and prefetched pages, stylesheets and scripts.\nconst pages = new Map< string, Promise< Page | false > >();\nconst headElements = new Map< string, { tag: HTMLElement; text: string } >();\n\n// Helper to remove domain and hash from the URL. We are only interesting in\n// caching the path and the query.\nconst getPagePath = ( url: string ) => {\n\tconst u = new URL( url, window.location.href );\n\treturn u.pathname + u.search;\n};\n\n// Fetch a new page and convert it to a static virtual DOM.\nconst fetchPage = async ( url: string, { html }: { html: string } ) => {\n\ttry {\n\t\tif ( ! html ) {\n\t\t\tconst res = await window.fetch( url );\n\t\t\tif ( res.status !== 200 ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\thtml = await res.text();\n\t\t}\n\t\tconst dom = new window.DOMParser().parseFromString( html, 'text/html' );\n\t\treturn regionsToVdom( dom );\n\t} catch ( e ) {\n\t\treturn false;\n\t}\n};\n\n// Return an object with VDOM trees of those HTML regions marked with a\n// `router-region` directive.\nconst regionsToVdom: RegionsToVdom = async ( dom, { vdom } = {} ) => {\n\tconst regions = { body: undefined };\n\tlet head: HTMLElement[];\n\tif ( globalThis.IS_GUTENBERG_PLUGIN ) {\n\t\tif ( navigationMode === 'fullPage' ) {\n\t\t\thead = await fetchHeadAssets( dom, headElements );\n\t\t\tregions.body = vdom\n\t\t\t\t? vdom.get( document.body )\n\t\t\t\t: toVdom( dom.body );\n\t\t}\n\t}\n\tif ( navigationMode === 'regionBased' ) {\n\t\tconst attrName = `data-${ directivePrefix }-router-region`;\n\t\tdom.querySelectorAll( `[${ attrName }]` ).forEach( ( region ) => {\n\t\t\tconst id = region.getAttribute( attrName );\n\t\t\tregions[ id ] = vdom?.has( region )\n\t\t\t\t? vdom.get( region )\n\t\t\t\t: toVdom( region );\n\t\t} );\n\t}\n\tconst title = dom.querySelector( 'title' )?.innerText;\n\tconst initialData = parseInitialData( dom );\n\treturn { regions, head, title, initialData };\n};\n\n// Render all interactive regions contained in the given page.\nconst renderRegions = ( page: Page ) => {\n\tbatch( () => {\n\t\tif ( globalThis.IS_GUTENBERG_PLUGIN ) {\n\t\t\tif ( navigationMode === 'fullPage' ) {\n\t\t\t\t// Once this code is tested and more mature, the head should be updated for region based navigation as well.\n\t\t\t\tupdateHead( page.head );\n\t\t\t\tconst fragment = getRegionRootFragment( document.body );\n\t\t\t\trender( page.regions.body, fragment );\n\t\t\t}\n\t\t}\n\t\tif ( navigationMode === 'regionBased' ) {\n\t\t\tpopulateInitialData( page.initialData );\n\t\t\tconst attrName = `data-${ directivePrefix }-router-region`;\n\t\t\tdocument\n\t\t\t\t.querySelectorAll( `[${ attrName }]` )\n\t\t\t\t.forEach( ( region ) => {\n\t\t\t\t\tconst id = region.getAttribute( attrName );\n\t\t\t\t\tconst fragment = getRegionRootFragment( region );\n\t\t\t\t\trender( page.regions[ id ], fragment );\n\t\t\t\t} );\n\t\t}\n\t\tif ( page.title ) {\n\t\t\tdocument.title = page.title;\n\t\t}\n\t} );\n};\n\n/**\n * Load the given page forcing a full page reload.\n *\n * The function returns a promise that won't resolve, useful to prevent any\n * potential feedback indicating that the navigation has finished while the new\n * page is being loaded.\n *\n * @param href The page href.\n * @return Promise that never resolves.\n */\nconst forcePageReload = ( href: string ) => {\n\twindow.location.assign( href );\n\treturn new Promise( () => {} );\n};\n\n// Listen to the back and forward buttons and restore the page if it's in the\n// cache.\nwindow.addEventListener( 'popstate', async () => {\n\tconst pagePath = getPagePath( window.location.href ); // Remove hash.\n\tconst page = pages.has( pagePath ) && ( await pages.get( pagePath ) );\n\tif ( page ) {\n\t\trenderRegions( page );\n\t\t// Update the URL in the state.\n\t\tstate.url = window.location.href;\n\t} else {\n\t\twindow.location.reload();\n\t}\n} );\n\n// Initialize the router and cache the initial page using the initial vDOM.\n// Once this code is tested and more mature, the head should be updated for\n// region based navigation as well.\nif ( globalThis.IS_GUTENBERG_PLUGIN ) {\n\tif ( navigationMode === 'fullPage' ) {\n\t\t// Cache the scripts. Has to be called before fetching the assets.\n\t\t[].map.call( document.querySelectorAll( 'script[src]' ), ( script ) => {\n\t\t\theadElements.set( script.getAttribute( 'src' ), {\n\t\t\t\ttag: script,\n\t\t\t\ttext: script.textContent,\n\t\t\t} );\n\t\t} );\n\t\tawait fetchHeadAssets( document, headElements );\n\t}\n}\npages.set(\n\tgetPagePath( window.location.href ),\n\tPromise.resolve( regionsToVdom( document, { vdom: initialVdom } ) )\n);\n\n// Check if the link is valid for client-side navigation.\nconst isValidLink = ( ref: HTMLAnchorElement ) =>\n\tref &&\n\tref instanceof window.HTMLAnchorElement &&\n\tref.href &&\n\t( ! ref.target || ref.target === '_self' ) &&\n\tref.origin === window.location.origin &&\n\t! ref.pathname.startsWith( '/wp-admin' ) &&\n\t! ref.pathname.startsWith( '/wp-login.php' ) &&\n\t! ref.getAttribute( 'href' ).startsWith( '#' ) &&\n\t! new URL( ref.href ).searchParams.has( '_wpnonce' );\n\n// Check if the event is valid for client-side navigation.\nconst isValidEvent = ( event: MouseEvent ) =>\n\tevent &&\n\tevent.button === 0 && // Left clicks only.\n\t! event.metaKey && // Open in new tab (Mac).\n\t! event.ctrlKey && // Open in new tab (Windows).\n\t! event.altKey && // Download.\n\t! event.shiftKey &&\n\t! event.defaultPrevented;\n\n// Variable to store the current navigation.\nlet navigatingTo = '';\n\nexport const { state, actions } = store( 'core/router', {\n\tstate: {\n\t\turl: window.location.href,\n\t\tnavigation: {\n\t\t\thasStarted: false,\n\t\t\thasFinished: false,\n\t\t\ttexts: {\n\t\t\t\tloading: '',\n\t\t\t\tloaded: '',\n\t\t\t},\n\t\t\tmessage: '',\n\t\t},\n\t},\n\tactions: {\n\t\t/**\n\t\t * Navigates to the specified page.\n\t\t *\n\t\t * This function normalizes the passed href, fetchs the page HTML if\n\t\t * needed, and updates any interactive regions whose contents have\n\t\t * changed. It also creates a new entry in the browser session history.\n\t\t *\n\t\t * @param href The page href.\n\t\t * @param [options] Options object.\n\t\t * @param [options.force] If true, it forces re-fetching the URL.\n\t\t * @param [options.html] HTML string to be used instead of fetching the requested URL.\n\t\t * @param [options.replace] If true, it replaces the current entry in the browser session history.\n\t\t * @param [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.\n\t\t * @param [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.\n\t\t * @param [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.\n\t\t *\n\t\t * @return Promise that resolves once the navigation is completed or aborted.\n\t\t */\n\t\t*navigate( href: string, options: NavigateOptions = {} ) {\n\t\t\tconst { clientNavigationDisabled } = getConfig();\n\t\t\tif ( clientNavigationDisabled ) {\n\t\t\t\tyield forcePageReload( href );\n\t\t\t}\n\n\t\t\tconst pagePath = getPagePath( href );\n\t\t\tconst { navigation } = state;\n\t\t\tconst {\n\t\t\t\tloadingAnimation = true,\n\t\t\t\tscreenReaderAnnouncement = true,\n\t\t\t\ttimeout = 10000,\n\t\t\t} = options;\n\n\t\t\tnavigatingTo = href;\n\t\t\tactions.prefetch( pagePath, options );\n\n\t\t\t// Create a promise that resolves when the specified timeout ends.\n\t\t\t// The timeout value is 10 seconds by default.\n\t\t\tconst timeoutPromise = new Promise< void >( ( resolve ) =>\n\t\t\t\tsetTimeout( resolve, timeout )\n\t\t\t);\n\n\t\t\t// Don't update the navigation status immediately, wait 400 ms.\n\t\t\tconst loadingTimeout = setTimeout( () => {\n\t\t\t\tif ( navigatingTo !== href ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tif ( loadingAnimation ) {\n\t\t\t\t\tnavigation.hasStarted = true;\n\t\t\t\t\tnavigation.hasFinished = false;\n\t\t\t\t}\n\t\t\t\tif ( screenReaderAnnouncement ) {\n\t\t\t\t\tnavigation.message = navigation.texts.loading;\n\t\t\t\t}\n\t\t\t}, 400 );\n\n\t\t\tconst page = yield Promise.race( [\n\t\t\t\tpages.get( pagePath ),\n\t\t\t\ttimeoutPromise,\n\t\t\t] );\n\n\t\t\t// Dismiss loading message if it hasn't been added yet.\n\t\t\tclearTimeout( loadingTimeout );\n\n\t\t\t// Once the page is fetched, the destination URL could have changed\n\t\t\t// (e.g., by clicking another link in the meantime). If so, bail\n\t\t\t// out, and let the newer execution to update the HTML.\n\t\t\tif ( navigatingTo !== href ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tpage &&\n\t\t\t\t! page.initialData?.config?.[ 'core/router' ]\n\t\t\t\t\t?.clientNavigationDisabled\n\t\t\t) {\n\t\t\t\tyield renderRegions( page );\n\t\t\t\twindow.history[\n\t\t\t\t\toptions.replace ? 'replaceState' : 'pushState'\n\t\t\t\t]( {}, '', href );\n\n\t\t\t\t// Update the URL in the state.\n\t\t\t\tstate.url = href;\n\n\t\t\t\t// Update the navigation status once the the new page rendering\n\t\t\t\t// has been completed.\n\t\t\t\tif ( loadingAnimation ) {\n\t\t\t\t\tnavigation.hasStarted = false;\n\t\t\t\t\tnavigation.hasFinished = true;\n\t\t\t\t}\n\n\t\t\t\tif ( screenReaderAnnouncement ) {\n\t\t\t\t\t// Announce that the page has been loaded. If the message is the\n\t\t\t\t\t// same, we use a no-break space similar to the @wordpress/a11y\n\t\t\t\t\t// package: https://github.com/WordPress/gutenberg/blob/c395242b8e6ee20f8b06c199e4fc2920d7018af1/packages/a11y/src/filter-message.js#L20-L26\n\t\t\t\t\tnavigation.message =\n\t\t\t\t\t\tnavigation.texts.loaded +\n\t\t\t\t\t\t( navigation.message === navigation.texts.loaded\n\t\t\t\t\t\t\t? '\\u00A0'\n\t\t\t\t\t\t\t: '' );\n\t\t\t\t}\n\n\t\t\t\t// Scroll to the anchor if exits in the link.\n\t\t\t\tconst { hash } = new URL( href, window.location.href );\n\t\t\t\tif ( hash ) {\n\t\t\t\t\tdocument.querySelector( hash )?.scrollIntoView();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tyield forcePageReload( href );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Prefetchs the page with the passed URL.\n\t\t *\n\t\t * The function normalizes the URL and stores internally the fetch\n\t\t * promise, to avoid triggering a second fetch for an ongoing request.\n\t\t *\n\t\t * @param url The page URL.\n\t\t * @param [options] Options object.\n\t\t * @param [options.force] Force fetching the URL again.\n\t\t * @param [options.html] HTML string to be used instead of fetching the requested URL.\n\t\t */\n\t\tprefetch( url: string, options: PrefetchOptions = {} ) {\n\t\t\tconst { clientNavigationDisabled } = getConfig();\n\t\t\tif ( clientNavigationDisabled ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pagePath = getPagePath( url );\n\t\t\tif ( options.force || ! pages.has( pagePath ) ) {\n\t\t\t\tpages.set(\n\t\t\t\t\tpagePath,\n\t\t\t\t\tfetchPage( pagePath, { html: options.html } )\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t},\n} );\n\n// Add click and prefetch to all links.\nif ( globalThis.IS_GUTENBERG_PLUGIN ) {\n\tif ( navigationMode === 'fullPage' ) {\n\t\t// Navigate on click.\n\t\tdocument.addEventListener(\n\t\t\t'click',\n\t\t\tfunction ( event ) {\n\t\t\t\tconst ref = ( event.target as Element ).closest( 'a' );\n\t\t\t\tif ( isValidLink( ref ) && isValidEvent( event ) ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tactions.navigate( ref.href );\n\t\t\t\t}\n\t\t\t},\n\t\t\ttrue\n\t\t);\n\t\t// Prefetch on hover.\n\t\tdocument.addEventListener(\n\t\t\t'mouseenter',\n\t\t\tfunction ( event ) {\n\t\t\t\tif ( ( event.target as Element )?.nodeName === 'A' ) {\n\t\t\t\t\tconst ref = ( event.target as Element ).closest( 'a' );\n\t\t\t\t\tif ( isValidLink( ref ) && isValidEvent( event ) ) {\n\t\t\t\t\t\tactions.prefetch( ref.href );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\ttrue\n\t\t);\n\t}\n}\n"],"mappings":"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","ignoreList":[]}
@@ -1,3 +1,23 @@
1
- export function updateHead(newHead: any[]): Promise<void>;
2
- export function fetchHeadAssets(doc: Document, headElements: Map<any, any>): Promise<HTMLElement[]>;
1
+ /**
2
+ * Helper to update only the necessary tags in the head.
3
+ *
4
+ * @async
5
+ * @param newHead The head elements of the new page.
6
+ */
7
+ export declare const updateHead: (newHead: HTMLHeadElement[]) => Promise<void>;
8
+ /**
9
+ * Fetches and processes head assets (stylesheets and scripts) from a specified document.
10
+ *
11
+ * @async
12
+ * @param doc The document from which to fetch head assets. It should support standard DOM querying methods.
13
+ * @param headElements A map of head elements to modify tracking the URLs of already processed assets to avoid duplicates.
14
+ * @param headElements.tag
15
+ * @param headElements.text
16
+ *
17
+ * @return Returns an array of HTML elements representing the head assets.
18
+ */
19
+ export declare const fetchHeadAssets: (doc: Document, headElements: Map<string, {
20
+ tag: HTMLElement;
21
+ text: string;
22
+ }>) => Promise<HTMLElement[]>;
3
23
  //# sourceMappingURL=head.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../src/head.js"],"names":[],"mappings":"AAOO,0DA+BN;AAWM,qCALI,QAAQ,gCAGP,QAAQ,WAAW,EAAE,CAAC,CAkDjC"}
1
+ {"version":3,"file":"head.d.ts","sourceRoot":"","sources":["../src/head.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,eAAO,MAAM,UAAU,YAAoB,eAAe,EAAE,kBA+B3D,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,eAAe,QACtB,QAAQ,gBACC,IAAK,MAAM,EAAE;IAAE,GAAG,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAE,KAC7D,QAAS,WAAW,EAAE,CAkDxB,CAAC"}
@@ -1,12 +1,27 @@
1
- export namespace state {
2
- let url: string;
3
- namespace navigation {
4
- let hasStarted: boolean;
5
- let hasFinished: boolean;
6
- let texts: {};
7
- }
1
+ interface NavigateOptions {
2
+ force?: boolean;
3
+ html?: string;
4
+ replace?: boolean;
5
+ timeout?: number;
6
+ loadingAnimation?: boolean;
7
+ screenReaderAnnouncement?: boolean;
8
8
  }
9
- export namespace actions {
9
+ interface PrefetchOptions {
10
+ force?: boolean;
11
+ html?: string;
12
+ }
13
+ export declare const state: {
14
+ url: string;
15
+ navigation: {
16
+ hasStarted: boolean;
17
+ hasFinished: boolean;
18
+ texts: {
19
+ loading: string;
20
+ loaded: string;
21
+ };
22
+ message: string;
23
+ };
24
+ }, actions: {
10
25
  /**
11
26
  * Navigates to the specified page.
12
27
  *
@@ -14,39 +29,30 @@ export namespace actions {
14
29
  * needed, and updates any interactive regions whose contents have
15
30
  * changed. It also creates a new entry in the browser session history.
16
31
  *
17
- * @param {string} href The page href.
18
- * @param {Object} [options] Options object.
19
- * @param {boolean} [options.force] If true, it forces re-fetching the URL.
20
- * @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
21
- * @param {boolean} [options.replace] If true, it replaces the current entry in the browser session history.
22
- * @param {number} [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
23
- * @param {boolean} [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
24
- * @param {boolean} [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
32
+ * @param href The page href.
33
+ * @param [options] Options object.
34
+ * @param [options.force] If true, it forces re-fetching the URL.
35
+ * @param [options.html] HTML string to be used instead of fetching the requested URL.
36
+ * @param [options.replace] If true, it replaces the current entry in the browser session history.
37
+ * @param [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
38
+ * @param [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
39
+ * @param [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
25
40
  *
26
- * @return {Promise} Promise that resolves once the navigation is completed or aborted.
41
+ * @return Promise that resolves once the navigation is completed or aborted.
27
42
  */
28
- function navigate(href: string, options?: {
29
- force?: boolean;
30
- html?: string;
31
- replace?: boolean;
32
- timeout?: number;
33
- loadingAnimation?: boolean;
34
- screenReaderAnnouncement?: boolean;
35
- }): Promise<any>;
43
+ navigate(href: string, options?: NavigateOptions): Generator<void | Promise<unknown>, void, unknown>;
36
44
  /**
37
45
  * Prefetchs the page with the passed URL.
38
46
  *
39
47
  * The function normalizes the URL and stores internally the fetch
40
48
  * promise, to avoid triggering a second fetch for an ongoing request.
41
49
  *
42
- * @param {string} url The page URL.
43
- * @param {Object} [options] Options object.
44
- * @param {boolean} [options.force] Force fetching the URL again.
45
- * @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
50
+ * @param url The page URL.
51
+ * @param [options] Options object.
52
+ * @param [options.force] Force fetching the URL again.
53
+ * @param [options.html] HTML string to be used instead of fetching the requested URL.
46
54
  */
47
- function prefetch(url: string, options?: {
48
- force?: boolean;
49
- html?: string;
50
- }): void;
51
- }
55
+ prefetch(url: string, options?: PrefetchOptions): void;
56
+ };
57
+ export {};
52
58
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.js"],"names":[],"mappings":";;;;;;;;;IAiME;;;;;;;;;;;;;;;;;OAiBG;IACH;;;;;;;qBA4FC;IAED;;;;;;;;;;OAUG;IACH;;;aAUC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuBA,UAAU,eAAe;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,wBAAwB,CAAC,EAAE,OAAO,CAAC;CACnC;AAED,UAAU,eAAe;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAgLD,eAAO,MAAQ,KAAK;;;;;;;;;;;GAAE,OAAO;IAc3B;;;;;;;;;;;;;;;;;OAiBG;mBACc,MAAM,YAAW,eAAe;IA8FjD;;;;;;;;;;OAUG;kBACY,MAAM,YAAW,eAAe;CAe9C,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wordpress/interactivity-router",
3
- "version": "1.7.0",
3
+ "version": "2.0.0",
4
4
  "description": "Package that exposes state and actions from the `core/router` store, part of the Interactivity API.",
5
5
  "author": "The WordPress Contributors",
6
6
  "license": "GPL-2.0-or-later",
@@ -19,17 +19,18 @@
19
19
  "url": "https://github.com/WordPress/gutenberg/labels/%5BFeature%5D%20Interactivity%20API"
20
20
  },
21
21
  "engines": {
22
- "node": ">=12"
22
+ "node": ">=18.12.0",
23
+ "npm": ">=8.19.2"
23
24
  },
24
25
  "main": "build/index.js",
25
26
  "module": "build-module/index.js",
26
27
  "react-native": "src/index",
27
28
  "types": "build-types",
28
29
  "dependencies": {
29
- "@wordpress/interactivity": "^5.6.0"
30
+ "@wordpress/interactivity": "^6.0.0"
30
31
  },
31
32
  "publishConfig": {
32
33
  "access": "public"
33
34
  },
34
- "gitHead": "581d8a5580dba8f600b7268d51eb554771ae482c"
35
+ "gitHead": "2f30cddff15723ac7017fd009fc5913b7b419400"
35
36
  }
@@ -2,20 +2,19 @@
2
2
  * Helper to update only the necessary tags in the head.
3
3
  *
4
4
  * @async
5
- * @param {Array} newHead The head elements of the new page.
6
- *
5
+ * @param newHead The head elements of the new page.
7
6
  */
8
- export const updateHead = async ( newHead ) => {
7
+ export const updateHead = async ( newHead: HTMLHeadElement[] ) => {
9
8
  // Helper to get the tag id store in the cache.
10
- const getTagId = ( tag ) => tag.id || tag.outerHTML;
9
+ const getTagId = ( tag: Element ) => tag.id || tag.outerHTML;
11
10
 
12
11
  // Map incoming head tags by their content.
13
- const newHeadMap = new Map();
12
+ const newHeadMap = new Map< string, Element >();
14
13
  for ( const child of newHead ) {
15
14
  newHeadMap.set( getTagId( child ), child );
16
15
  }
17
16
 
18
- const toRemove = [];
17
+ const toRemove: Element[] = [];
19
18
 
20
19
  // Detect nodes that should be added or removed.
21
20
  for ( const child of document.head.children ) {
@@ -42,12 +41,17 @@ export const updateHead = async ( newHead ) => {
42
41
  * Fetches and processes head assets (stylesheets and scripts) from a specified document.
43
42
  *
44
43
  * @async
45
- * @param {Document} doc The document from which to fetch head assets. It should support standard DOM querying methods.
46
- * @param {Map} headElements A map of head elements to modify tracking the URLs of already processed assets to avoid duplicates.
44
+ * @param doc The document from which to fetch head assets. It should support standard DOM querying methods.
45
+ * @param headElements A map of head elements to modify tracking the URLs of already processed assets to avoid duplicates.
46
+ * @param headElements.tag
47
+ * @param headElements.text
47
48
  *
48
- * @return {Promise<HTMLElement[]>} Returns an array of HTML elements representing the head assets.
49
+ * @return Returns an array of HTML elements representing the head assets.
49
50
  */
50
- export const fetchHeadAssets = async ( doc, headElements ) => {
51
+ export const fetchHeadAssets = async (
52
+ doc: Document,
53
+ headElements: Map< string, { tag: HTMLElement; text: string } >
54
+ ): Promise< HTMLElement[] > => {
51
55
  const headTags = [];
52
56
  const assets = [
53
57
  {
@@ -59,7 +63,9 @@ export const fetchHeadAssets = async ( doc, headElements ) => {
59
63
  ];
60
64
  for ( const asset of assets ) {
61
65
  const { tagName, selector, attribute } = asset;
62
- const tags = doc.querySelectorAll( selector );
66
+ const tags = doc.querySelectorAll<
67
+ HTMLScriptElement | HTMLStyleElement
68
+ >( selector );
63
69
 
64
70
  // Use Promise.all to wait for fetch to complete
65
71
  await Promise.all(
@@ -21,23 +21,50 @@ const {
21
21
  'I acknowledge that using private APIs means my theme or plugin will inevitably break in the next version of WordPress.'
22
22
  );
23
23
 
24
+ interface NavigateOptions {
25
+ force?: boolean;
26
+ html?: string;
27
+ replace?: boolean;
28
+ timeout?: number;
29
+ loadingAnimation?: boolean;
30
+ screenReaderAnnouncement?: boolean;
31
+ }
32
+
33
+ interface PrefetchOptions {
34
+ force?: boolean;
35
+ html?: string;
36
+ }
37
+
38
+ interface VdomParams {
39
+ vdom?: typeof initialVdom;
40
+ }
41
+
42
+ interface Page {
43
+ regions: Record< string, any >;
44
+ head: HTMLHeadElement[];
45
+ title: string;
46
+ initialData: any;
47
+ }
48
+
49
+ type RegionsToVdom = ( dom: Document, params?: VdomParams ) => Promise< Page >;
50
+
24
51
  // Check if the navigation mode is full page or region based.
25
- const navigationMode =
52
+ const navigationMode: 'regionBased' | 'fullPage' =
26
53
  getConfig( 'core/router' ).navigationMode ?? 'regionBased';
27
54
 
28
55
  // The cache of visited and prefetched pages, stylesheets and scripts.
29
- const pages = new Map();
30
- const headElements = new Map();
56
+ const pages = new Map< string, Promise< Page | false > >();
57
+ const headElements = new Map< string, { tag: HTMLElement; text: string } >();
31
58
 
32
59
  // Helper to remove domain and hash from the URL. We are only interesting in
33
60
  // caching the path and the query.
34
- const getPagePath = ( url ) => {
35
- const u = new URL( url, window.location );
61
+ const getPagePath = ( url: string ) => {
62
+ const u = new URL( url, window.location.href );
36
63
  return u.pathname + u.search;
37
64
  };
38
65
 
39
66
  // Fetch a new page and convert it to a static virtual DOM.
40
- const fetchPage = async ( url, { html } ) => {
67
+ const fetchPage = async ( url: string, { html }: { html: string } ) => {
41
68
  try {
42
69
  if ( ! html ) {
43
70
  const res = await window.fetch( url );
@@ -55,10 +82,10 @@ const fetchPage = async ( url, { html } ) => {
55
82
 
56
83
  // Return an object with VDOM trees of those HTML regions marked with a
57
84
  // `router-region` directive.
58
- const regionsToVdom = async ( dom, { vdom } = {} ) => {
59
- const regions = {};
60
- let head;
61
- if ( process.env.IS_GUTENBERG_PLUGIN ) {
85
+ const regionsToVdom: RegionsToVdom = async ( dom, { vdom } = {} ) => {
86
+ const regions = { body: undefined };
87
+ let head: HTMLElement[];
88
+ if ( globalThis.IS_GUTENBERG_PLUGIN ) {
62
89
  if ( navigationMode === 'fullPage' ) {
63
90
  head = await fetchHeadAssets( dom, headElements );
64
91
  regions.body = vdom
@@ -81,9 +108,9 @@ const regionsToVdom = async ( dom, { vdom } = {} ) => {
81
108
  };
82
109
 
83
110
  // Render all interactive regions contained in the given page.
84
- const renderRegions = ( page ) => {
111
+ const renderRegions = ( page: Page ) => {
85
112
  batch( () => {
86
- if ( process.env.IS_GUTENBERG_PLUGIN ) {
113
+ if ( globalThis.IS_GUTENBERG_PLUGIN ) {
87
114
  if ( navigationMode === 'fullPage' ) {
88
115
  // Once this code is tested and more mature, the head should be updated for region based navigation as well.
89
116
  updateHead( page.head );
@@ -115,10 +142,10 @@ const renderRegions = ( page ) => {
115
142
  * potential feedback indicating that the navigation has finished while the new
116
143
  * page is being loaded.
117
144
  *
118
- * @param {string} href The page href.
119
- * @return {Promise} Promise that never resolves.
145
+ * @param href The page href.
146
+ * @return Promise that never resolves.
120
147
  */
121
- const forcePageReload = ( href ) => {
148
+ const forcePageReload = ( href: string ) => {
122
149
  window.location.assign( href );
123
150
  return new Promise( () => {} );
124
151
  };
@@ -126,7 +153,7 @@ const forcePageReload = ( href ) => {
126
153
  // Listen to the back and forward buttons and restore the page if it's in the
127
154
  // cache.
128
155
  window.addEventListener( 'popstate', async () => {
129
- const pagePath = getPagePath( window.location ); // Remove hash.
156
+ const pagePath = getPagePath( window.location.href ); // Remove hash.
130
157
  const page = pages.has( pagePath ) && ( await pages.get( pagePath ) );
131
158
  if ( page ) {
132
159
  renderRegions( page );
@@ -138,8 +165,9 @@ window.addEventListener( 'popstate', async () => {
138
165
  } );
139
166
 
140
167
  // Initialize the router and cache the initial page using the initial vDOM.
141
- // Once this code is tested and more mature, the head should be updated for region based navigation as well.
142
- if ( process.env.IS_GUTENBERG_PLUGIN ) {
168
+ // Once this code is tested and more mature, the head should be updated for
169
+ // region based navigation as well.
170
+ if ( globalThis.IS_GUTENBERG_PLUGIN ) {
143
171
  if ( navigationMode === 'fullPage' ) {
144
172
  // Cache the scripts. Has to be called before fetching the assets.
145
173
  [].map.call( document.querySelectorAll( 'script[src]' ), ( script ) => {
@@ -152,12 +180,12 @@ if ( process.env.IS_GUTENBERG_PLUGIN ) {
152
180
  }
153
181
  }
154
182
  pages.set(
155
- getPagePath( window.location ),
183
+ getPagePath( window.location.href ),
156
184
  Promise.resolve( regionsToVdom( document, { vdom: initialVdom } ) )
157
185
  );
158
186
 
159
187
  // Check if the link is valid for client-side navigation.
160
- const isValidLink = ( ref ) =>
188
+ const isValidLink = ( ref: HTMLAnchorElement ) =>
161
189
  ref &&
162
190
  ref instanceof window.HTMLAnchorElement &&
163
191
  ref.href &&
@@ -169,7 +197,7 @@ const isValidLink = ( ref ) =>
169
197
  ! new URL( ref.href ).searchParams.has( '_wpnonce' );
170
198
 
171
199
  // Check if the event is valid for client-side navigation.
172
- const isValidEvent = ( event ) =>
200
+ const isValidEvent = ( event: MouseEvent ) =>
173
201
  event &&
174
202
  event.button === 0 && // Left clicks only.
175
203
  ! event.metaKey && // Open in new tab (Mac).
@@ -187,7 +215,11 @@ export const { state, actions } = store( 'core/router', {
187
215
  navigation: {
188
216
  hasStarted: false,
189
217
  hasFinished: false,
190
- texts: {},
218
+ texts: {
219
+ loading: '',
220
+ loaded: '',
221
+ },
222
+ message: '',
191
223
  },
192
224
  },
193
225
  actions: {
@@ -198,18 +230,18 @@ export const { state, actions } = store( 'core/router', {
198
230
  * needed, and updates any interactive regions whose contents have
199
231
  * changed. It also creates a new entry in the browser session history.
200
232
  *
201
- * @param {string} href The page href.
202
- * @param {Object} [options] Options object.
203
- * @param {boolean} [options.force] If true, it forces re-fetching the URL.
204
- * @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
205
- * @param {boolean} [options.replace] If true, it replaces the current entry in the browser session history.
206
- * @param {number} [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
207
- * @param {boolean} [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
208
- * @param {boolean} [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
233
+ * @param href The page href.
234
+ * @param [options] Options object.
235
+ * @param [options.force] If true, it forces re-fetching the URL.
236
+ * @param [options.html] HTML string to be used instead of fetching the requested URL.
237
+ * @param [options.replace] If true, it replaces the current entry in the browser session history.
238
+ * @param [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
239
+ * @param [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
240
+ * @param [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
209
241
  *
210
- * @return {Promise} Promise that resolves once the navigation is completed or aborted.
242
+ * @return Promise that resolves once the navigation is completed or aborted.
211
243
  */
212
- *navigate( href, options = {} ) {
244
+ *navigate( href: string, options: NavigateOptions = {} ) {
213
245
  const { clientNavigationDisabled } = getConfig();
214
246
  if ( clientNavigationDisabled ) {
215
247
  yield forcePageReload( href );
@@ -228,7 +260,7 @@ export const { state, actions } = store( 'core/router', {
228
260
 
229
261
  // Create a promise that resolves when the specified timeout ends.
230
262
  // The timeout value is 10 seconds by default.
231
- const timeoutPromise = new Promise( ( resolve ) =>
263
+ const timeoutPromise = new Promise< void >( ( resolve ) =>
232
264
  setTimeout( resolve, timeout )
233
265
  );
234
266
 
@@ -294,7 +326,7 @@ export const { state, actions } = store( 'core/router', {
294
326
  }
295
327
 
296
328
  // Scroll to the anchor if exits in the link.
297
- const { hash } = new URL( href, window.location );
329
+ const { hash } = new URL( href, window.location.href );
298
330
  if ( hash ) {
299
331
  document.querySelector( hash )?.scrollIntoView();
300
332
  }
@@ -309,12 +341,12 @@ export const { state, actions } = store( 'core/router', {
309
341
  * The function normalizes the URL and stores internally the fetch
310
342
  * promise, to avoid triggering a second fetch for an ongoing request.
311
343
  *
312
- * @param {string} url The page URL.
313
- * @param {Object} [options] Options object.
314
- * @param {boolean} [options.force] Force fetching the URL again.
315
- * @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
344
+ * @param url The page URL.
345
+ * @param [options] Options object.
346
+ * @param [options.force] Force fetching the URL again.
347
+ * @param [options.html] HTML string to be used instead of fetching the requested URL.
316
348
  */
317
- prefetch( url, options = {} ) {
349
+ prefetch( url: string, options: PrefetchOptions = {} ) {
318
350
  const { clientNavigationDisabled } = getConfig();
319
351
  if ( clientNavigationDisabled ) {
320
352
  return;
@@ -322,20 +354,23 @@ export const { state, actions } = store( 'core/router', {
322
354
 
323
355
  const pagePath = getPagePath( url );
324
356
  if ( options.force || ! pages.has( pagePath ) ) {
325
- pages.set( pagePath, fetchPage( pagePath, options ) );
357
+ pages.set(
358
+ pagePath,
359
+ fetchPage( pagePath, { html: options.html } )
360
+ );
326
361
  }
327
362
  },
328
363
  },
329
364
  } );
330
365
 
331
366
  // Add click and prefetch to all links.
332
- if ( process.env.IS_GUTENBERG_PLUGIN ) {
367
+ if ( globalThis.IS_GUTENBERG_PLUGIN ) {
333
368
  if ( navigationMode === 'fullPage' ) {
334
369
  // Navigate on click.
335
370
  document.addEventListener(
336
371
  'click',
337
372
  function ( event ) {
338
- const ref = event.target.closest( 'a' );
373
+ const ref = ( event.target as Element ).closest( 'a' );
339
374
  if ( isValidLink( ref ) && isValidEvent( event ) ) {
340
375
  event.preventDefault();
341
376
  actions.navigate( ref.href );
@@ -347,8 +382,8 @@ if ( process.env.IS_GUTENBERG_PLUGIN ) {
347
382
  document.addEventListener(
348
383
  'mouseenter',
349
384
  function ( event ) {
350
- if ( event.target?.nodeName === 'A' ) {
351
- const ref = event.target.closest( 'a' );
385
+ if ( ( event.target as Element )?.nodeName === 'A' ) {
386
+ const ref = ( event.target as Element ).closest( 'a' );
352
387
  if ( isValidLink( ref ) && isValidEvent( event ) ) {
353
388
  actions.prefetch( ref.href );
354
389
  }