Skip to content
7 changes: 7 additions & 0 deletions src/wp-includes/block-editor.php
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,13 @@ function block_editor_rest_api_preload( array $preload_paths, $block_editor_cont
),
'after'
);
add_filter(
'scriptmoduledata_@wordpress/api-fetch',
function ( $data ) use ( $preload_data ) {
$data['preloadData'] = $preload_data;
return $data;
}
);
}

/**
Expand Down
73 changes: 73 additions & 0 deletions src/wp-includes/class-wp-script-modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,13 @@ public function add_hooks() {
add_action( $position, array( $this, 'print_import_map' ) );
add_action( $position, array( $this, 'print_enqueued_script_modules' ) );
add_action( $position, array( $this, 'print_script_module_preloads' ) );

add_action( 'admin_print_footer_scripts', array( $this, 'print_import_map' ) );
add_action( 'admin_print_footer_scripts', array( $this, 'print_enqueued_script_modules' ) );
add_action( 'admin_print_footer_scripts', array( $this, 'print_script_module_preloads' ) );

add_action( 'wp_footer', array( $this, 'print_script_data' ) );
add_action( 'admin_print_footer_scripts', array( $this, 'print_script_data' ) );
}

/**
Expand Down Expand Up @@ -359,4 +366,70 @@ private function get_src( string $id ): string {

return $src;
}

public function print_script_data(): void {
$modules = array();
foreach ( array_keys( $this->get_marked_for_enqueue() ) as $id ) {
$modules[ $id ] = true;
}
foreach ( array_keys( $this->get_import_map()['imports'] ) as $id ) {
$modules[ $id ] = true;
}

foreach ( array_keys( $modules ) as $module_id ) {
$data = apply_filters( 'scriptmoduledata_' . $module_id, array() );
if ( ! empty( $data ) ) {
/*
* This data will be printed as JSON inside a script tag like this:
* <script type="application/json"></script>
*
* A script tag must be closed by a sequence beginning with `</`. It's impossible to
* close a script tag without using `<`. We ensure that `<` is escaped and `/` can
* remain unescaped, so `</script>` will be printed as `\u003C/script\u00E3`.
*
* - JSON_HEX_TAG: All < and > are converted to \u003C and \u003E.
* - JSON_UNESCAPED_SLASHES: Don't escape /.
*
* @see https://www.php.net/manual/en/json.constants.php for details on these constants.
* @see https://html.spec.whatwg.org/#script-data-state for details on script
* tag parsing.
*/
$json_encode_flags = JSON_HEX_TAG | JSON_UNESCAPED_SLASHES;
if ( 'UTF-8' === get_option( 'blog_charset' ) ) {
/*
* If the page will use UTF-8 encoding, it's safe to print unescaped unicode in
* JSON. Set the following flags:
*
* - JSON_UNESCAPED_UNICODE: Encode multibyte Unicode characters literally
* (default is to escape as \uXXXX).
* - JSON_UNESCAPED_LINE_TERMINATORS: The line terminators are kept unescaped when
* JSON_UNESCAPED_UNICODE is supplied. It uses the same behaviour as it was
* before PHP 7.1 without this constant. Available as of PHP 7.1.0.
*
* The JSON specification does not specify a character encoding, RFC-8259
* suggests that UTF-8 be used everywhere. It's risky to print unicode if the page
* uses any other encoding.
*
* > JSON text exchanged between systems that are not part of a closed ecosystem
* > MUST be encoded using UTF-8. Previous specifications of JSON have not required
* > the use of UTF-8 when transmitting JSON text. However, the vast majority of
* > JSON- based software implementations have chosen to use the UTF-8 encoding,
* > to the extent that it is the only encoding that achieves interoperability.
*
* @see https://www.rfc-editor.org/rfc/rfc8259.html
*
*/
$json_encode_flags |= JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_LINE_TERMINATORS;
}

wp_print_inline_script_tag(
wp_json_encode( $data, $json_encode_flags ),
array(
'type' => 'application/json',
'id' => 'wp-scriptmodule-data_' . $module_id,
)
);
}
}
}
}
16 changes: 16 additions & 0 deletions src/wp-includes/script-modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,3 +123,19 @@ function wp_dequeue_script_module( string $id ) {
function wp_deregister_script_module( string $id ) {
wp_script_modules()->deregister( $id );
}


function wp_register_default_script_modules(): void {
add_filter(
'scriptmoduledata_@wordpress/api-fetch',
function ( $data ) {
$data['rootURL'] = sanitize_url( get_rest_url() );
$data['nonce'] = wp_installing() ? '' : wp_create_nonce( 'wp_rest' );
$data['shouldRegisterMediaUploadMiddleware'] = true;
$data['nonceEndpoint'] = admin_url( 'admin-ajax.php?action=rest-nonce' );
return $data;
}
);
wp_enqueue_script_module( '__DEV__/noop', includes_url( '/noop.js' ), array( '@wordpress/api-fetch' ) );
}
add_action( 'init', 'wp_register_default_script_modules', 0 );
8 changes: 8 additions & 0 deletions src/wp-includes/theme-previews.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ function wp_attach_theme_preview_middleware() {
),
'after'
);

add_filter(
'scriptmoduledata_@wordpress/api-fetch',
function ( $data ) {
$data['themePreviewPath'] = sanitize_text_field( wp_unslash( $_GET['wp_theme_preview'] ) );
return $data;
}
);
}

/**
Expand Down