Skip to content

Commit e1b0865

Browse files
DAreRodzDAreRodzluisherranzsirreal
authored andcommitted
iAPI Router: Support new styles and script modules on client-side navigation (WordPress#70353)
* Revert "Remove the iAPI full-page experiment entirely (WordPress#70228)" This reverts commit f693991. * Reapply "iAPI Router: Handle styles assets on region-based navigation (WordPress#67826)" This reverts commit 0a5be06. * Reapply "iAPI Router: Fix CSS rule order in some constructed style sheets (WordPress#68923)" This reverts commit a53bb20. * Clone style elements and enable/disable them * Combine `media` and `disabled` * Add prefetch callback to style tests * Remove `async` from `applyStyles` * Add basic error handling * Rename `baseUrl` to `url` * Improve comment wrappers around new styles sheets * Minor fixes * Use a SCS algorithm to add new style sheets * Refactor and document `updateStylesWithSCS` * Fix promises returned by `updateStylesWithSCS` * First unit tests (claude) * Test improvements (claude) * Tests for shortestCommonSupersequence (claude) * Move scs tests a folder up * Refactor scs tests a bit * Refactor `updateStylesWithSCS` and `applyStyles` unit tests * Add new test for media attributes * Fix last appended elements * Rename and document `areStylesEqual` * Improve `areStyleEqual` TSDoc * Add more TSDocs * Add TSDoc for `shortestCommonSupersequence` * Test stylesheet loading fails * Wrap `url` with `getPagePath` * Make `url` param mandatory in `prepareStyles` * Replace wrong `prefetch` words with `preload` * Fix failed to load message * Clarify the `element.sheet` check. * Wrap unit tests inside an additional `describe` * Remove unnecesary comment * Add TSDocs for helpers in styles.test.ts * Add missing periods in test comments * Normalize elements before calling `shortestCommonSupersequence` * Refactor `normalizeMedia` * Handle script modules * Install dynamic-importmap * Try with dynamic-importmap * Try ignore originally imported modules * Use a local copy of dynamic-importmap * Make it work * Cleaning up WIP * Add test files * Add an initial simple test * Partially fix pattern to intercept js requests * Add missing asset.php files * Try adding a module dependency * Disable module preloading * WIP Attempt code reorganization * WIP type Load objects * WIP Refactor types and add functions for preloading * Update router code * Add prefetch action to tests * Fix modules not being imported * Refactor script file and add TSDocs * Improve types and comments a bit * Improve types and TSDocs a little bit more * Add static dependencies to test modules * Make prefetch action asynchronous * Add failing test * Fix media preload when the target style list is empty * Update more tests * Fix how initial style sheets are detected * Detect first if the link has started prefetching * Add a failing test * Only enable/disable sheets that are ready * Improve failing test * Move styles and module preload to `regionsToVdom` * Add more comments * Remove try..catch around renderRegions call * Rename `prepareStyles` to `preloadStyles` * Start replacing modules term with script modules * Replace modules term with script modules in test files * Remove unnecessary promise around lexer.init * Remove old import fix from edge See https://github.com/guybedford/es-module-shims/pull/450/files#diff-d9f5f5cf3b132cd3d457a02a9202af63e78eb6b8b3284097e5d1cfd28b181e8eR351. * Remove unnecessary fetch pool * Simplify error messages in `fetchModule` * Do not add module type in `fetchModule` * Remove unused code * Catch `regionsToVdom` errors in `fetchPage` * Remove support for `import.meta` * Update package-lock * Ensure CSN checkers are hidden by default * Resolve inconsistencies and rename `markScriptModuleAsResolved` * Reset clientSideNavigation prop when navigation starts * Reapply "Remove the iAPI full-page experiment entirely (WordPress#70228)" This reverts commit 9cfe7ec. * WIP Move full-page logic to its own module * Fix interactivity-router TS with sub-packages * Needs to be composite project * Add empty files for good measure * Add package.json export * Remove extra whitespace * Remove exports property * Add full-page client-side navigation support * Import script modules before render * Turn php logic into a class * Change default mode priority to 9 * Fix init action in WP_Interactivity_API_Full_Page_Navigation * Prevent warning accessing to clientNavigationMode * Change body router region ID to core/body * Remove unnecessary `body` prop inside `regions` * Add a filter to enable/disable the experimental feature * Use `wp_body_open` instead of `wp_footer` * Move the experiment filter to `set_default_mode` * Remove full-page unlock * Only add the client navigation mode when full page is enabled * Move Full Page class to experimental folder * End buffer on `wp_footer` instead of `wp_body_open` * Enable the full-page CSN with a gutenberg experiment * Rename WP to Gutenberg in full-page CSN class * Remove "since" tag * Update changelog * Rename regionsToVdom and renderRegions to preparePage and renderPage * Make url param mandatori in preparePage * Remove unnecessary full-page mode from JS * Remove unnecessary full-page mode from PHP * Mention original code creators * Add descriptive names to props in ModuleLoad * Fix wrong JSON * Use Interactivity API instead of iAPI in experiment label * Avoid error messages in tests * Check the page title after navigation * Prevent warning about missing disable_server_directive_processing * Fix remaining ModuleLoad prop names * Simplify resolve function and remove unnecessary code --------- Co-authored-by: DAreRodz <darerodz@git.wordpress.org> Co-authored-by: luisherranz <luisherranz@git.wordpress.org> Co-authored-by: sirreal <jonsurrell@git.wordpress.org>
1 parent 39a550c commit e1b0865

70 files changed

Lines changed: 3840 additions & 54 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
/**
3+
* Interactivity API: Experimental full-page client-side navigation.
4+
*
5+
* @package Gutenberg
6+
* @subpackage Interactivity API
7+
*/
8+
9+
if ( ! class_exists( 'Gutenberg_Interactivity_API_Full_Page_Navigation' ) ) {
10+
11+
/**
12+
* Class Gutenberg_Interactivity_API_Full_Page_Navigation.
13+
*/
14+
class Gutenberg_Interactivity_API_Full_Page_Navigation {
15+
16+
private static $instance = null;
17+
18+
public static function instance() {
19+
if ( null === self::$instance ) {
20+
self::$instance = new Gutenberg_Interactivity_API_Full_Page_Navigation();
21+
}
22+
return self::$instance;
23+
}
24+
25+
public function __construct() {
26+
add_action( 'wp_head', array( $this, 'buffer_start' ) );
27+
add_action( 'wp_footer', array( $this, 'buffer_end' ), 8 );
28+
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_script_modules' ) );
29+
}
30+
31+
/**
32+
* Enqueues the required script modules.
33+
*/
34+
public function enqueue_script_modules() {
35+
wp_enqueue_script_module(
36+
'@wordpress/interactivity-router/full-page'
37+
);
38+
}
39+
40+
/**
41+
* Starts output buffering at the end of the 'wp_head' action, adding the
42+
* required directives for client-side navigation to the BODY tags when the
43+
* buffer is flushed.
44+
*/
45+
public function buffer_start() {
46+
ob_start( array( $this, 'add_directives_to_body' ) );
47+
}
48+
49+
/**
50+
* Flushes the output buffer at the end of the 'wp_footer' action.
51+
*/
52+
public function buffer_end() {
53+
ob_end_flush();
54+
}
55+
56+
/**
57+
* Adds client-side navigation directives to BODY tag in the passed output
58+
* buffer.
59+
*
60+
* Note: This should probably be done per site, not by default when this option
61+
* is enabled.
62+
*
63+
* @param string $buffer Passed output buffer.
64+
*
65+
* @return string The same HTML with modified BODY attributes.
66+
*/
67+
public function add_directives_to_body( $buffer ) {
68+
$p = new WP_HTML_Tag_Processor( $buffer );
69+
if ( $p->next_tag( array( 'tag_name' => 'BODY' ) ) ) {
70+
$p->set_attribute( 'data-wp-interactive', true );
71+
$p->set_attribute( 'data-wp-router-region', 'core/body' );
72+
return $p->get_updated_html();
73+
} else {
74+
return $buffer;
75+
}
76+
}
77+
}
78+
}

‎lib/experiments-page.php‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,18 @@ function gutenberg_initialize_experiments_settings() {
223223
)
224224
);
225225

226+
add_settings_field(
227+
'gutenberg-full-page-client-side-navigation',
228+
__( 'Interactivity API: Full-page client-side navigation', 'gutenberg' ),
229+
'gutenberg_display_experiment_field',
230+
'gutenberg-experiments',
231+
'gutenberg_experiments_section',
232+
array(
233+
'label' => __( 'Enables full-page client-side navigation, powered by the Interactivity API.', 'gutenberg' ),
234+
'id' => 'gutenberg-full-page-client-side-navigation',
235+
)
236+
);
237+
226238
register_setting(
227239
'gutenberg-experiments',
228240
'gutenberg-experiments'

‎lib/load.php‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,9 @@ function gutenberg_is_experiment_enabled( $name ) {
156156
if ( gutenberg_is_experiment_enabled( 'gutenberg-media-processing' ) ) {
157157
require_once __DIR__ . '/experimental/media/load.php';
158158
}
159+
160+
// Interactivity API full-page client-side navigation.
161+
if ( gutenberg_is_experiment_enabled( 'gutenberg-full-page-client-side-navigation' ) ) {
162+
require __DIR__ . '/experimental/interactivity-api/class-gutenberg-interactivity-api-full-page-navigation.php';
163+
Gutenberg_Interactivity_API_Full_Page_Navigation::instance();
164+
}

‎package-lock.json‎

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎packages/e2e-tests/plugins/interactive-blocks.php‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ function () {
2525
* required to ensure that client hydration works even when the rendered
2626
* HTML contains unbalanced tags and it couldn't be processed in the server.
2727
*/
28-
if ( 'true' === $_GET['disable_server_directive_processing'] ) {
28+
if (
29+
isset( $_GET['disable_server_directive_processing'] ) &&
30+
'true' === $_GET['disable_server_directive_processing']
31+
) {
2932
// Ensure the interactivity API is loaded.
3033
wp_interactivity();
3134
// But remove the server directive processing.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"$schema": "https://schemas.wp.org/trunk/block.json",
3+
"apiVersion": 2,
4+
"name": "test/router-script-modules-alpha",
5+
"title": "E2E Interactivity tests - router modules - Alpha",
6+
"category": "text",
7+
"icon": "heart",
8+
"description": "",
9+
"supports": {
10+
"interactivity": true
11+
},
12+
"textdomain": "e2e-interactivity",
13+
"viewScriptModule": "file:./view.js",
14+
"render": "file:./render.php"
15+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export default 'alpha';
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
/**
3+
* HTML for testing the iAPI's script module assets management.
4+
*
5+
* @package gutenberg-test-interactive-blocks
6+
*
7+
* @phpcs:disable VariableAnalysis.CodeAnalysis.VariableAnalysis.UndefinedVariable
8+
*/
9+
10+
$module_path = '/module.js';
11+
$module_url = plugins_url( $module_path, __FILE__ );
12+
wp_register_script_module(
13+
'test/router-script-modules-alpha',
14+
$module_url,
15+
array(),
16+
filemtime( plugin_dir_path( __FILE__ ) . $module_path )
17+
);
18+
19+
$wrapper_attributes = get_block_wrapper_attributes(
20+
array(
21+
'data-testid' => 'alpha-block',
22+
'data-wp-interactive' => 'test/router-script-modules-alpha',
23+
'data-wp-text' => 'state.name',
24+
)
25+
);
26+
?>
27+
<p <?php echo $wrapper_attributes; ?>></p>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php return array(
2+
'dependencies' => array(
3+
'@wordpress/interactivity',
4+
'test/router-script-modules-alpha',
5+
),
6+
);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* WordPress dependencies
3+
*/
4+
import { store } from '@wordpress/interactivity';
5+
6+
/**
7+
* External dependencies
8+
*/
9+
// eslint-disable-next-line import/no-unresolved
10+
import name from 'test/router-script-modules-alpha';
11+
12+
store( 'test/router-script-modules-alpha', {
13+
state: {
14+
name,
15+
},
16+
} );
17+
18+
const { actions } = store( 'test/router-script-modules' );
19+
actions.pushName?.( name );

0 commit comments

Comments
 (0)