Skip to content

Commit

Permalink
Add event listeners for navigate and prefetch in JS
Browse files Browse the repository at this point in the history
  • Loading branch information
SantosGuillamot committed Apr 17, 2024
1 parent d7e6ddb commit d72cd02
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 55 deletions.
8 changes: 0 additions & 8 deletions lib/experimental/full-page-client-side-navigation.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,6 @@ function _gutenberg_add_enhanced_pagination_to_query_block( $parsed_block ) {
*/
function _gutenberg_add_client_side_navigation_directives( $content ) {
$p = new WP_HTML_Tag_Processor( $content );
while ( $p->next_tag( array( 'tag_name' => 'a' ) ) ) {
if ( empty( $p->get_attribute( 'data-wp-on--click' ) ) ) {
$p->set_attribute( 'data-wp-on--click', 'core/router::actions.navigate' );
}
if ( empty( $p->get_attribute( 'data-wp-on--mouseenter' ) ) ) {
$p->set_attribute( 'data-wp-on--mouseenter', 'core/router::actions.prefetch' );
}
}
// Hack to add the necessary directives to the body tag.
// TODO: Find a proper way to add directives to the body tag.
static $body_interactive_added;
Expand Down
99 changes: 52 additions & 47 deletions packages/interactivity-router/src/index.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
/**
* WordPress dependencies
*/
import {
store,
privateApis,
getConfig,
getElement,
} from '@wordpress/interactivity';
import { store, privateApis, getConfig } from '@wordpress/interactivity';

/**
* Internal dependencies
Expand Down Expand Up @@ -200,34 +195,23 @@ export const { state, actions } = store( 'core/router', {
* needed, and updates any interactive regions whose contents have
* changed. It also creates a new entry in the browser session history.
*
* @param {string|Event} eventOrUrl The page href or the event handler in case it is used directly in a directive.
* @param {Object} [options] Options object.
* @param {boolean} [options.force] If true, it forces re-fetching the URL.
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
* @param {boolean} [options.replace] If true, it replaces the current entry in the browser session history.
* @param {number} [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
* @param {boolean} [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
* @param {boolean} [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
* @param {string} href The page href.
* @param {Object} [options] Options object.
* @param {boolean} [options.force] If true, it forces re-fetching the URL.
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
* @param {boolean} [options.replace] If true, it replaces the current entry in the browser session history.
* @param {number} [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
* @param {boolean} [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
* @param {boolean} [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
*
* @return {Promise} Promise that resolves once the navigation is completed or aborted.
*/
*navigate( eventOrUrl, options = {} ) {
*navigate( href, options = {} ) {
const { clientNavigationDisabled } = getConfig();
const url = ! ( eventOrUrl instanceof Event ) && eventOrUrl;
const event = eventOrUrl instanceof Event && eventOrUrl;
let ref;
// The getElement() function can only be called when it is an event.
if ( event ) {
ref = getElement().ref;
}
if (
clientNavigationDisabled ||
! ( url || ( isValidLink( ref ) && isValidEvent( event ) ) )
) {
yield forcePageReload( url );
if ( clientNavigationDisabled ) {
yield forcePageReload( href );
}
if ( event ) event.preventDefault();
const href = url ? url : ref.href;

const pagePath = getPagePath( href );
const { navigation } = state;
const {
Expand Down Expand Up @@ -316,29 +300,50 @@ export const { state, actions } = store( 'core/router', {
* The function normalizes the URL and stores internally the fetch
* promise, to avoid triggering a second fetch for an ongoing request.
*
* @param {string|Event} eventOrUrl The page href or the event handler in case it is used directly in a directive.
* @param {Object} [options] Options object.
* @param {boolean} [options.force] Force fetching the URL again.
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
* @param {string} url The page URL.
* @param {Object} [options] Options object.
* @param {boolean} [options.force] Force fetching the URL again.
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
*/
prefetch( eventOrUrl, options = {} ) {
const url = ! ( eventOrUrl instanceof Event ) && eventOrUrl;
const event = eventOrUrl instanceof Event && eventOrUrl;
let ref;
// The getElement() function can only be called when it is an event.
if ( event ) {
ref = getElement().ref;
}
prefetch( url, options = {} ) {
const { clientNavigationDisabled } = getConfig();
if (
clientNavigationDisabled ||
! ( url || ( isValidLink( ref ) && isValidEvent( event ) ) )
)
return;
const pagePath = getPagePath( url ? url : ref.href );
if ( clientNavigationDisabled ) return;

const pagePath = getPagePath( url );
if ( options.force || ! pages.has( pagePath ) ) {
pages.set( pagePath, fetchPage( pagePath, options ) );
}
},
},
} );

// Add click and prefetch to all links.
if ( process.env.IS_GUTENBERG_PLUGIN ) {
if ( navigationMode === 'fullPage' ) {
// Navigate on click.
document.addEventListener(
'click',
function ( event ) {
const ref = event.target.closest( 'a' );
if ( isValidLink( ref ) && isValidEvent( event ) ) {
event.preventDefault();
actions.navigate( ref.href );
}
},
true
);
// Prefetch on hover.
document.addEventListener(
'mouseenter',
function ( event ) {
if ( event.target?.nodeName === 'A' ) {
const ref = event.target.closest( 'a' );
if ( isValidLink( ref ) && isValidEvent( event ) ) {
actions.prefetch( ref.href );
}
}
},
true
);
}
}

0 comments on commit d72cd02

Please sign in to comment.