Skip to content

Commit d72cd02

Browse files
Add event listeners for navigate and prefetch in JS
1 parent d7e6ddb commit d72cd02

File tree

2 files changed

+52
-55
lines changed

2 files changed

+52
-55
lines changed

lib/experimental/full-page-client-side-navigation.php

-8
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,6 @@ function _gutenberg_add_enhanced_pagination_to_query_block( $parsed_block ) {
4343
*/
4444
function _gutenberg_add_client_side_navigation_directives( $content ) {
4545
$p = new WP_HTML_Tag_Processor( $content );
46-
while ( $p->next_tag( array( 'tag_name' => 'a' ) ) ) {
47-
if ( empty( $p->get_attribute( 'data-wp-on--click' ) ) ) {
48-
$p->set_attribute( 'data-wp-on--click', 'core/router::actions.navigate' );
49-
}
50-
if ( empty( $p->get_attribute( 'data-wp-on--mouseenter' ) ) ) {
51-
$p->set_attribute( 'data-wp-on--mouseenter', 'core/router::actions.prefetch' );
52-
}
53-
}
5446
// Hack to add the necessary directives to the body tag.
5547
// TODO: Find a proper way to add directives to the body tag.
5648
static $body_interactive_added;

packages/interactivity-router/src/index.js

+52-47
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,7 @@
11
/**
22
* WordPress dependencies
33
*/
4-
import {
5-
store,
6-
privateApis,
7-
getConfig,
8-
getElement,
9-
} from '@wordpress/interactivity';
4+
import { store, privateApis, getConfig } from '@wordpress/interactivity';
105

116
/**
127
* Internal dependencies
@@ -200,34 +195,23 @@ export const { state, actions } = store( 'core/router', {
200195
* needed, and updates any interactive regions whose contents have
201196
* changed. It also creates a new entry in the browser session history.
202197
*
203-
* @param {string|Event} eventOrUrl The page href or the event handler in case it is used directly in a directive.
204-
* @param {Object} [options] Options object.
205-
* @param {boolean} [options.force] If true, it forces re-fetching the URL.
206-
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
207-
* @param {boolean} [options.replace] If true, it replaces the current entry in the browser session history.
208-
* @param {number} [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
209-
* @param {boolean} [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
210-
* @param {boolean} [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
198+
* @param {string} href The page href.
199+
* @param {Object} [options] Options object.
200+
* @param {boolean} [options.force] If true, it forces re-fetching the URL.
201+
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
202+
* @param {boolean} [options.replace] If true, it replaces the current entry in the browser session history.
203+
* @param {number} [options.timeout] Time until the navigation is aborted, in milliseconds. Default is 10000.
204+
* @param {boolean} [options.loadingAnimation] Whether an animation should be shown while navigating. Default to `true`.
205+
* @param {boolean} [options.screenReaderAnnouncement] Whether a message for screen readers should be announced while navigating. Default to `true`.
211206
*
212207
* @return {Promise} Promise that resolves once the navigation is completed or aborted.
213208
*/
214-
*navigate( eventOrUrl, options = {} ) {
209+
*navigate( href, options = {} ) {
215210
const { clientNavigationDisabled } = getConfig();
216-
const url = ! ( eventOrUrl instanceof Event ) && eventOrUrl;
217-
const event = eventOrUrl instanceof Event && eventOrUrl;
218-
let ref;
219-
// The getElement() function can only be called when it is an event.
220-
if ( event ) {
221-
ref = getElement().ref;
222-
}
223-
if (
224-
clientNavigationDisabled ||
225-
! ( url || ( isValidLink( ref ) && isValidEvent( event ) ) )
226-
) {
227-
yield forcePageReload( url );
211+
if ( clientNavigationDisabled ) {
212+
yield forcePageReload( href );
228213
}
229-
if ( event ) event.preventDefault();
230-
const href = url ? url : ref.href;
214+
231215
const pagePath = getPagePath( href );
232216
const { navigation } = state;
233217
const {
@@ -316,29 +300,50 @@ export const { state, actions } = store( 'core/router', {
316300
* The function normalizes the URL and stores internally the fetch
317301
* promise, to avoid triggering a second fetch for an ongoing request.
318302
*
319-
* @param {string|Event} eventOrUrl The page href or the event handler in case it is used directly in a directive.
320-
* @param {Object} [options] Options object.
321-
* @param {boolean} [options.force] Force fetching the URL again.
322-
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
303+
* @param {string} url The page URL.
304+
* @param {Object} [options] Options object.
305+
* @param {boolean} [options.force] Force fetching the URL again.
306+
* @param {string} [options.html] HTML string to be used instead of fetching the requested URL.
323307
*/
324-
prefetch( eventOrUrl, options = {} ) {
325-
const url = ! ( eventOrUrl instanceof Event ) && eventOrUrl;
326-
const event = eventOrUrl instanceof Event && eventOrUrl;
327-
let ref;
328-
// The getElement() function can only be called when it is an event.
329-
if ( event ) {
330-
ref = getElement().ref;
331-
}
308+
prefetch( url, options = {} ) {
332309
const { clientNavigationDisabled } = getConfig();
333-
if (
334-
clientNavigationDisabled ||
335-
! ( url || ( isValidLink( ref ) && isValidEvent( event ) ) )
336-
)
337-
return;
338-
const pagePath = getPagePath( url ? url : ref.href );
310+
if ( clientNavigationDisabled ) return;
311+
312+
const pagePath = getPagePath( url );
339313
if ( options.force || ! pages.has( pagePath ) ) {
340314
pages.set( pagePath, fetchPage( pagePath, options ) );
341315
}
342316
},
343317
},
344318
} );
319+
320+
// Add click and prefetch to all links.
321+
if ( process.env.IS_GUTENBERG_PLUGIN ) {
322+
if ( navigationMode === 'fullPage' ) {
323+
// Navigate on click.
324+
document.addEventListener(
325+
'click',
326+
function ( event ) {
327+
const ref = event.target.closest( 'a' );
328+
if ( isValidLink( ref ) && isValidEvent( event ) ) {
329+
event.preventDefault();
330+
actions.navigate( ref.href );
331+
}
332+
},
333+
true
334+
);
335+
// Prefetch on hover.
336+
document.addEventListener(
337+
'mouseenter',
338+
function ( event ) {
339+
if ( event.target?.nodeName === 'A' ) {
340+
const ref = event.target.closest( 'a' );
341+
if ( isValidLink( ref ) && isValidEvent( event ) ) {
342+
actions.prefetch( ref.href );
343+
}
344+
}
345+
},
346+
true
347+
);
348+
}
349+
}

0 commit comments

Comments
 (0)