Skip to content

Commit bca7cea

Browse files
committed
Interactivity API: Print data-wp-html tokens as the wpServerHtml marker.
Encode `WP_Interactivity_Dangerous_HTML` tokens as `{"wpServerHtml":true}` on both paths of `wp_json_encode()`, so the client keeps the server-rendered content of a `data-wp-html` host wherever the reference reaches the token, including `data-wp-each` items read from context. Stop listing tokens reached through state in `derivedStateClosures`, which the marker makes unnecessary. Follow-up to [64386]. Props santosguillamot. Fixes #66246. Built from https://develop.svn.wordpress.org/trunk@64501 git-svn-id: http://core.svn.wordpress.org/trunk@63651 1a063a9b-81f0-0310-95a4-ce76da25c4cd
1 parent 89639c4 commit bca7cea

3 files changed

Lines changed: 43 additions & 33 deletions

File tree

‎wp-includes/interactivity-api/class-wp-interactivity-api.php‎

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,6 @@ private function _process_directives( string $html ) {
706706
* @since 6.6.0 Removed `default_namespace` and `context` arguments.
707707
* @since 6.6.0 Add support for derived state.
708708
* @since 6.9.0 Receive $entry as an argument instead of the directive value string.
709-
* @since 7.2.0 Tracks the path of a token that marks HTML as trusted, reached through state.
710709
*
711710
* @param array $entry An array containing a whole directive entry with its namespace, value, suffix, or unique ID.
712711
* @return mixed|null The result of the evaluation. Null if the reference path doesn't exist or the namespace is falsy.
@@ -732,9 +731,8 @@ private function evaluate( $entry ) {
732731
$path = $should_negate_value ? substr( $path, 1 ) : $path;
733732

734733
// Extracts the value from the store using the reference path.
735-
$path_segments = explode( '.', $path );
736-
$current = $store;
737-
$called_closure = false;
734+
$path_segments = explode( '.', $path );
735+
$current = $store;
738736
foreach ( $path_segments as $index => $path_segment ) {
739737
/*
740738
* Special case for numeric arrays and strings. Add length
@@ -783,8 +781,7 @@ private function evaluate( $entry ) {
783781
*/
784782
array_push( $this->namespace_stack, $ns );
785783
try {
786-
$called_closure = true;
787-
$current = $current();
784+
$current = $current();
788785

789786
/*
790787
* Tracks derived state properties that are accessed during
@@ -818,28 +815,6 @@ private function evaluate( $entry ) {
818815
}
819816
}
820817

821-
/*
822-
* Tracks the tokens that mark HTML as trusted and that a reference
823-
* reaches through state, the way derived state closures are tracked, so
824-
* the client keeps the server-rendered content of a token until its
825-
* store supplies a value. A token reached through context, or through
826-
* the result of a derived state closure, is not tracked: the client has
827-
* no context store to resolve it from, and the closure is tracked
828-
* instead.
829-
*
830-
* @since 7.2.0
831-
*/
832-
if (
833-
'state' === $path_segments[0] &&
834-
! $called_closure &&
835-
$current instanceof WP_Interactivity_Dangerous_HTML
836-
) {
837-
$this->derived_state_closures[ $ns ] ??= array();
838-
if ( ! in_array( $path, $this->derived_state_closures[ $ns ], true ) ) {
839-
$this->derived_state_closures[ $ns ][] = $path;
840-
}
841-
}
842-
843818
// Returns the opposite if it contains a negation operator (!).
844819
return $should_negate_value ? ! $current : $current;
845820
}

‎wp-includes/interactivity-api/class-wp-interactivity-dangerous-html.php‎

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,22 @@
1414
* Create tokens with {@see wp_interactivity_as_dangerous_html()}, which
1515
* documents the risks of marking HTML as trusted.
1616
*
17-
* The HTML is kept in a private property, so encoding a token as JSON never
18-
* includes it. A token restored by unserialization is inert: it holds no HTML,
19-
* so it never renders.
17+
* The HTML is kept in a private property, so it never reaches JSON: a token
18+
* encodes as the marker `{"wpServerHtml":true}`, which tells the client to
19+
* keep the content the element already has. The marker holds no HTML. A token
20+
* restored by unserialization is inert: it holds no HTML, so it never renders,
21+
* and it encodes as the marker too.
22+
*
23+
* Both JSON encoding paths of `wp_json_encode()` print the marker: `json_encode()`
24+
* uses {@see WP_Interactivity_Dangerous_HTML::jsonSerialize()}, and the fallback
25+
* for data that is not valid UTF-8 rebuilds the object by iterating it with
26+
* {@see WP_Interactivity_Dangerous_HTML::getIterator()}.
2027
*
2128
* @since 7.2.0
2229
*
2330
* @access private
2431
*/
25-
final class WP_Interactivity_Dangerous_HTML {
32+
final class WP_Interactivity_Dangerous_HTML implements JsonSerializable, IteratorAggregate {
2633
/**
2734
* The trusted HTML. It is `null` for a token restored by unserialization,
2835
* which never renders.
@@ -73,4 +80,32 @@ public function __wakeup(): void {
7380
'7.2.0'
7481
);
7582
}
83+
84+
/**
85+
* Gets the value that JSON encoding prints in place of the token.
86+
*
87+
* It is the same for every token and holds none of its HTML.
88+
*
89+
* @since 7.2.0
90+
*
91+
* @return array<string, bool> The marker: a single `wpServerHtml` entry set to `true`,
92+
* which `json_encode()` prints as `{"wpServerHtml":true}`.
93+
*/
94+
public function jsonSerialize(): array {
95+
return array( 'wpServerHtml' => true );
96+
}
97+
98+
/**
99+
* Gets the iterator that `foreach` and the fallback of `wp_json_encode()` read.
100+
*
101+
* It yields the same single entry as {@see WP_Interactivity_Dangerous_HTML::jsonSerialize()}
102+
* and none of the token's HTML.
103+
*
104+
* @since 7.2.0
105+
*
106+
* @return Traversable<string, bool> An iterator yielding `wpServerHtml` => `true`, once.
107+
*/
108+
public function getIterator(): Traversable {
109+
return new ArrayIterator( $this->jsonSerialize() );
110+
}
76111
}

‎wp-includes/version.php‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
* @global string $wp_version
1818
*/
19-
$wp_version = '7.2-alpha-64500';
19+
$wp_version = '7.2-alpha-64501';
2020

2121
/**
2222
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.

0 commit comments

Comments
 (0)