Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Interactivity API: Server Directive Processing #5953

Closed
wants to merge 59 commits into from
Closed
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
bb547e4
Code from GB
luisherranz Jan 31, 2024
236eda2
Fix test pollution
luisherranz Jan 31, 2024
7c95ee5
Fix tabs in multiline comments
luisherranz Jan 31, 2024
c084276
Improve state/config return msg and fix arg name
luisherranz Jan 31, 2024
0fe3225
Remove unnecessary module registration
luisherranz Jan 31, 2024
e8daa1c
Fix typos
luisherranz Feb 1, 2024
c0f5804
Add missing @since statements
luisherranz Feb 1, 2024
eab8f28
Switch to null coalescing operator
luisherranz Feb 1, 2024
19e454f
Replace array_push with $array[]
luisherranz Feb 1, 2024
61d896f
Simplify conditional statement
luisherranz Feb 1, 2024
84ea8fd
Replace null with empty array in state/config functions
luisherranz Feb 1, 2024
0503eed
Add missing PHP 7 types
luisherranz Feb 1, 2024
36e8adb
Remove default args passed to filter
luisherranz Feb 1, 2024
2fef289
Add missing tests comments
luisherranz Feb 1, 2024
4100309
Add @ticket to all the tests
luisherranz Feb 1, 2024
8efcc12
Merge branch 'trunk' into wp-interactivity-api
luisherranz Feb 1, 2024
69c6f78
Switch from static to global and move hooks/modules to settings
luisherranz Feb 1, 2024
5462b18
Bail out if it finds an SVG or MathML tag
luisherranz Feb 1, 2024
6dc2d42
Check for tags that don't visit their closer tag
luisherranz Feb 2, 2024
e9cb1fe
Use non-min script module versions
luisherranz Feb 2, 2024
0534970
Add missing PHP 7 types
luisherranz Feb 2, 2024
2bc2bea
Merge branch 'trunk' into wp-interactivity-api
luisherranz Feb 2, 2024
553e8a4
Remove md5 in favor of array comparison
luisherranz Feb 2, 2024
ada6fe5
Use a hook to register the script modules so they can be overwritten …
luisherranz Feb 3, 2024
ee6e780
Omit curly brackets on string variable
luisherranz Feb 4, 2024
1c73521
Make classes final
luisherranz Feb 4, 2024
35ae36b
Fix typos
luisherranz Feb 4, 2024
a81d251
Add @uses to process_directives DocBlock
luisherranz Feb 4, 2024
97d4c98
Don't return the result of array_pop
luisherranz Feb 4, 2024
56a4d48
Don't return true on `has_and_visits_its_closer_tag` on null tag names
luisherranz Feb 4, 2024
33fbc8d
Merge branch 'trunk' into wp-interactivity-api
luisherranz Feb 4, 2024
d19252b
Remove unnecessary file
luisherranz Feb 5, 2024
49d5ebc
Remove more unnecessary files from wp-settings
luisherranz Feb 5, 2024
264d0fb
Update WP_Interactivity_API_Directives_Processor
luisherranz Feb 5, 2024
41ccbc1
Update WP_Interactivity_API
luisherranz Feb 5, 2024
c848fe2
Add tests for the new processors
luisherranz Feb 5, 2024
6345e24
Support data-wp-interactive="myPlugin"
luisherranz Feb 5, 2024
3b12a11
Add support for data_wp_context
luisherranz Feb 5, 2024
4618663
Rename $start/$end to more descriptive names and add get_after_opener…
luisherranz Feb 6, 2024
ff61c7c
Fix some texts
luisherranz Feb 6, 2024
71cda6e
Replace preg_replace with rtrim
luisherranz Feb 6, 2024
4dbb4fe
Rename set_style_property to merge_style_property
luisherranz Feb 6, 2024
330472c
Add json extension requirement to composer
luisherranz Feb 6, 2024
e0533e5
Fix some indentation issues
luisherranz Feb 6, 2024
e5b88fa
Replace array_push
luisherranz Feb 6, 2024
f010314
Use two block names in tests to make sure they render fine
luisherranz Feb 6, 2024
a2b4aae
Switch to render_block_{$this->name} filter
luisherranz Feb 6, 2024
c90d337
Add LanguageTool suggestion
luisherranz Feb 6, 2024
8eec2f3
Add missing processors in @uses
luisherranz Feb 6, 2024
8a1caa9
Try moving styles to a WP inline style
luisherranz Feb 6, 2024
71d1918
Adapt interactivity detection to new schema
luisherranz Feb 6, 2024
69afa13
Fix inline style
luisherranz Feb 6, 2024
1bb9137
Change data-wp-router-region tests to check for the inline styles
luisherranz Feb 6, 2024
30dc904
Checks for valid namespace characters in `data-wp-interactive`
luisherranz Feb 6, 2024
9d21532
Replace underscores with hyphens
luisherranz Feb 6, 2024
a24af7d
Remove % in 0 values of CSS
luisherranz Feb 7, 2024
3b189f7
Rename functions to use `get` and `print`
luisherranz Feb 7, 2024
ef1c9ae
Remove use of `@uses`
luisherranz Feb 7, 2024
76dea4f
Don't use the primary color for the top loading bar
luisherranz Feb 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"issues": "https://core.trac.wordpress.org/"
},
"require": {
"ext-json": "*",
luisherranz marked this conversation as resolved.
Show resolved Hide resolved
"php": ">=7.0"
},
"suggest": {
Expand Down
26 changes: 0 additions & 26 deletions src/wp-includes/interactivity-api.php

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
<?php
luisherranz marked this conversation as resolved.
Show resolved Hide resolved
/**
* Interactivity API: WP_Interactivity_API_Directives_Processor class.
*
* @package WordPress
* @subpackage Interactivity API
* @since 6.5.0
*/

/**
* Class used to iterate over the tags of an HTML string and help process the
* directive attributes.
*
* @since 6.5.0
*
* @access private
*/
final class WP_Interactivity_API_Directives_Processor extends WP_HTML_Tag_Processor {
/**
* List of tags whose closer tag is not visited by the WP_HTML_Tag_Processor.
*
* @since 6.5.0
* @var string[]
*/
const TAGS_THAT_DONT_VISIT_CLOSER_TAG = array(
'SCRIPT',
'IFRAME',
'NOEMBED',
'NOFRAMES',
'STYLE',
'TEXTAREA',
'TITLE',
'XMP',
);

/**
* Returns the content between two balanced template tags.
*
* It positions the cursor in the closer tag of the balanced template tag,
* if it exists.
*
* @since 6.5.0
*
* @access private
swissspidy marked this conversation as resolved.
Show resolved Hide resolved
*
* @return string|null The content between the current opener template tag and its matching closer tag or null if it
* doesn't find the matching closing tag or the current tag is not a template opener tag.
*/
public function get_content_between_balanced_template_tags() {
if ( 'TEMPLATE' !== $this->get_tag() ) {
return null;
}

$positions = $this->get_after_opener_tag_and_before_closer_tag_positions();
if ( ! $positions ) {
return null;
}
list( $after_opener_tag, $before_closer_tag ) = $positions;

return substr( $this->html, $after_opener_tag, $before_closer_tag - $after_opener_tag );
}

/**
* Sets the content between two balanced tags.
*
* @since 6.5.0
*
* @access private
*
* @param string $new_content The string to replace the content between the matching tags.
* @return bool Whether the content was successfully replaced.
*/
public function set_content_between_balanced_tags( string $new_content ): bool {
$positions = $this->get_after_opener_tag_and_before_closer_tag_positions( true );
if ( ! $positions ) {
return false;
}
list( $after_opener_tag, $before_closer_tag ) = $positions;

$this->lexical_updates[] = new WP_HTML_Text_Replacement(
$after_opener_tag,
$before_closer_tag - $after_opener_tag,
esc_html( $new_content )
);

return true;
}

/**
* Appends content after the closing tag of a template tag.
*
* It positions the cursor in the closer tag of the balanced template tag,
* if it exists.
*
* @access private
*
* @param string $new_content The string to append after the closing template tag.
* @return bool Whether the content was successfully appended.
*/
public function append_content_after_template_tag_closer( string $new_content ): bool {
if ( empty( $new_content ) || 'TEMPLATE' !== $this->get_tag() || ! $this->is_tag_closer() ) {
return false;
}

// Flushes any changes.
$this->get_updated_html();

$bookmark = 'append_content_after_template_tag_closer';
$this->set_bookmark( $bookmark );
$after_closing_tag = $this->bookmarks[ $bookmark ]->start + $this->bookmarks[ $bookmark ]->length + 1;
$this->release_bookmark( $bookmark );

// Appends the new content.
$this->lexical_updates[] = new WP_HTML_Text_Replacement( $after_closing_tag, 0, $new_content );

return true;
}

/**
* Gets the positions right after the opener tag and right before the closer
* tag in a balanced tag.
*
* By default, it positions the cursor in the closer tag of the balanced tag.
* If $rewind is true, it seeks back to the opener tag.
*
* @since 6.5.0
*
* @access private
*
* @param bool $rewind Optional. Whether to seek back to the opener tag after finding the positions. Defaults to false.
* @return array|null Start and end byte position, or null when no balanced tag bookmarks.
*/
private function get_after_opener_tag_and_before_closer_tag_positions( bool $rewind = false ) {
// Flushes any changes.
$this->get_updated_html();

$bookmarks = $this->get_balanced_tag_bookmarks();
if ( ! $bookmarks ) {
return null;
}
list( $opener_tag, $closer_tag ) = $bookmarks;

$after_opener_tag = $this->bookmarks[ $opener_tag ]->start + $this->bookmarks[ $opener_tag ]->length + 1;
$before_closer_tag = $this->bookmarks[ $closer_tag ]->start;

if ( $rewind ) {
$this->seek( $opener_tag );
}

$this->release_bookmark( $opener_tag );
$this->release_bookmark( $closer_tag );

return array( $after_opener_tag, $before_closer_tag );
}

/**
* Returns a pair of bookmarks for the current opener tag and the matching
* closer tag.
*
* It positions the cursor in the closer tag of the balanced tag, if it
* exists.
*
* @since 6.5.0
*
* @return array|null A pair of bookmarks, or null if there's no matching closing tag.
*/
private function get_balanced_tag_bookmarks() {
static $i = 0;
$opener_tag = 'opener_tag_of_balanced_tag_' . ++$i;

$this->set_bookmark( $opener_tag );
if ( ! $this->next_balanced_tag_closer_tag() ) {
$this->release_bookmark( $opener_tag );
return null;
}

$closer_tag = 'closer_tag_of_balanced_tag_' . ++$i;
$this->set_bookmark( $closer_tag );

return array( $opener_tag, $closer_tag );
}

/**
* Finds the matching closing tag for an opening tag.
*
* When called while the processor is on an open tag, it traverses the HTML
* until it finds the matching closer tag, respecting any in-between content,
* including nested tags of the same name. Returns false when called on a
* closer tag, a tag that doesn't have a closer tag (void), a tag that
* doesn't visit the closer tag, or if no matching closing tag was found.
*
* @since 6.5.0
*
* @access private
*
* @return bool Whether a matching closing tag was found.
*/
public function next_balanced_tag_closer_tag(): bool {
$depth = 0;
$tag_name = $this->get_tag();

if ( ! $this->has_and_visits_its_closer_tag() ) {
return false;
}

while ( $this->next_tag(
array(
'tag_name' => $tag_name,
'tag_closers' => 'visit',
)
) ) {
if ( ! $this->is_tag_closer() ) {
++$depth;
continue;
}

if ( 0 === $depth ) {
return true;
}
luisherranz marked this conversation as resolved.
Show resolved Hide resolved

--$depth;
}

return false;
}

/**
* Checks whether the current tag has and will visit its matching closer tag.
*
* @since 6.5.0
*
* @access private
*
* @return bool Whether the current tag has a closer tag.
*/
public function has_and_visits_its_closer_tag(): bool {
$tag_name = $this->get_tag();

return null !== $tag_name && (
! WP_HTML_Processor::is_void( $tag_name ) &&
! in_array( $tag_name, self::TAGS_THAT_DONT_VISIT_CLOSER_TAG, true )
);
}
}
Loading
Loading