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 Refactor #58066

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
573bfe2
Initial SDP version
luisherranz Jan 16, 2024
a1495fc
Rename `initialState` to `state`
luisherranz Jan 22, 2024
bcefd09
Fix incorrect package
luisherranz Jan 22, 2024
d563a90
Properly remove the SDP during the e2e tests
luisherranz Jan 22, 2024
5535d29
Merge branch 'trunk' into interactivity-api-server-directive-processi…
luisherranz Jan 23, 2024
f94ecc1
Update multiline comments to fit WP standards
cbravobernal Jan 23, 2024
5d68f19
Add @access private to WP_Interactivity_API_Directives_Processor
luisherranz Jan 24, 2024
388cfc0
Merge remote-tracking branch 'origin/interactivity-api-server-directi…
luisherranz Jan 24, 2024
4ca55a5
Remove array check and rename bookmarks in WP_Interactivity_API_Direc…
luisherranz Jan 24, 2024
3425e5d
Dont print config/state if it's empty
luisherranz Jan 24, 2024
fbda36b
Add failing test for </ >
luisherranz Jan 24, 2024
d4f584a
Add missing `object` word
luisherranz Jan 24, 2024
246317a
Missing indentation on ternary conditionals
luisherranz Jan 24, 2024
560a17e
Improve namespace extraction from directive value
luisherranz Jan 24, 2024
8ef546f
Move modified properties to the end in set_style_property
luisherranz Jan 24, 2024
d7e73b5
Replace tabindex comment
luisherranz Jan 24, 2024
56f3747
Remove filter after processing and bump priority
luisherranz Jan 24, 2024
614ef66
Replace own is_void with HTML API one
luisherranz Jan 24, 2024
c45893f
Missing ternary indentation
luisherranz Jan 24, 2024
fab5662
Avoid early returns
luisherranz Jan 24, 2024
5de71d2
Merge branch 'trunk' into interactivity-api-server-directive-processi…
luisherranz Jan 24, 2024
bdd0fad
Update wp_register_script_module function
luisherranz Jan 24, 2024
c3c87d3
Replaces some incorrect docblock comments with block comments
luisherranz Jan 24, 2024
6cee3ba
Fix indent ternaries (again)
luisherranz Jan 24, 2024
6b62b97
Add more info about how extract_directive_value behaves
luisherranz Jan 24, 2024
93eefeb
Add more edge cases
luisherranz Jan 24, 2024
1954f45
Improve wp_interactivity_process_directives_of_interactive_blocks com…
luisherranz Jan 24, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
<?php
/**
* Interactivity API: WP_Interactivity_API_Directives_Processor class.
*
* @package WordPress
* @subpackage Interactivity API
*/

if ( ! class_exists( 'WP_Interactivity_API_Directives_Processor' ) ) {
/**
* Class used to iterate over the tags of an HTML string and help process the
* directive attributes.
*
luisherranz marked this conversation as resolved.
Show resolved Hide resolved
* @access private
*/
class WP_Interactivity_API_Directives_Processor extends Gutenberg_HTML_Tag_Processor_6_5 {
/**
* Returns the content between two balanced tags.
*
* @access private
*
* @return string|null The content between the current opening and its matching closing tag or null if it doesn't
* find the matching closing tag.
*/
public function get_content_between_balanced_tags() {
$bookmarks = $this->get_balanced_tag_bookmarks();
if ( ! $bookmarks ) {
return null;
}
list( $start_name, $end_name ) = $bookmarks;

$start = $this->bookmarks[ $start_name ]->start + $this->bookmarks[ $start_name ]->length + 1;
$end = $this->bookmarks[ $end_name ]->start;

$this->seek( $start_name );
$this->release_bookmark( $start_name );
$this->release_bookmark( $end_name );

return substr( $this->html, $start, $end - $start );
}

/**
* Sets the content between two balanced tags.
*
* @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 {
$this->get_updated_html();

$bookmarks = $this->get_balanced_tag_bookmarks();
if ( ! $bookmarks ) {
return false;
}
list( $start_name, $end_name ) = $bookmarks;

$start = $this->bookmarks[ $start_name ]->start + $this->bookmarks[ $start_name ]->length + 1;
$end = $this->bookmarks[ $end_name ]->start;

$this->seek( $start_name );
$this->release_bookmark( $start_name );
$this->release_bookmark( $end_name );

$this->lexical_updates[] = new Gutenberg_HTML_Text_Replacement_6_5( $start, $end - $start, esc_html( $new_content ) );
return true;
}

/**
* Returns a pair of bookmarks for the current opening tag and the matching
* closing tag.
*
* @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;
$start_name = 'start_of_balanced_tag_' . ++$i;

$this->set_bookmark( $start_name );
if ( ! $this->next_balanced_closer() ) {
$this->release_bookmark( $start_name );
return null;
}

$end_name = 'end_of_balanced_tag_' . ++$i;
$this->set_bookmark( $end_name );

return array( $start_name, $end_name );
}

/**
* 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 closing tag, respecting any in-between content,
* including nested tags of the same name. Returns false when called on a
* closing or void tag, or if no matching closing tag was found.
*
* @return bool Whether a matching closing tag was found.
*/
private function next_balanced_closer(): bool {
$depth = 0;
$tag_name = $this->get_tag();

if ( $this->is_void() ) {
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;
}

--$depth;
}

return false;
}

/**
* Checks whether the current tag is void.
*
* @access private
*
* @return bool Whether the current tag is void or not.
*/
public function is_void(): bool {
$tag_name = $this->get_tag();
return Gutenberg_HTML_Processor_6_5::is_void( null !== $tag_name ? $tag_name : '' );
}
}
}
Loading
Loading