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

HTML API: Backport preview #57241

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion lib/block-supports/background.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ function gutenberg_render_background_support( $block_content, $block ) {

if ( ! empty( $styles['css'] ) ) {
// Inject background styles to the first element, presuming it's the wrapper, if it exists.
$tags = new WP_HTML_Tag_Processor( $block_content );
$tags = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );

if ( $tags->next_tag() ) {
$existing_style = $tags->get_attribute( 'style' );
Expand Down
8 changes: 4 additions & 4 deletions lib/block-supports/behaviors.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) {
return $block_content;
}

$processor = new WP_HTML_Tag_Processor( $block_content );
$processor = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );

$aria_label = __( 'Enlarge image', 'gutenberg' );

Expand Down Expand Up @@ -123,7 +123,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) {
$scale_attr = false;
}

$w = new WP_HTML_Tag_Processor( $block_content );
$w = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );
$w->next_tag( 'figure' );
$w->add_class( 'wp-lightbox-container' );
$w->set_attribute( 'data-wp-interactive', true );
Expand Down Expand Up @@ -184,7 +184,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) {
// image is a copy of the one in the body, which animates immediately
// as the lightbox is opened, while the enlarged one is a full-sized
// version that will likely still be loading as the animation begins.
$m = new WP_HTML_Tag_Processor( $block_content );
$m = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );
$m->next_tag( 'figure' );
$m->add_class( 'responsive-image' );
$m->next_tag( 'img' );
Expand All @@ -200,7 +200,7 @@ function gutenberg_render_behaviors_support_lightbox( $block_content, $block ) {
$m->set_attribute( 'data-wp-style--object-fit', 'selectors.core.image.lightboxObjectFit' );
$initial_image_content = $m->get_updated_html();

$q = new WP_HTML_Tag_Processor( $block_content );
$q = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );
$q->next_tag( 'figure' );
$q->add_class( 'enlarged-image' );
$q->next_tag( 'img' );
Expand Down
2 changes: 1 addition & 1 deletion lib/block-supports/elements.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ function gutenberg_render_elements_support( $block_content, $block ) {
* contains a single wrapper and that it's the first element in the
* rendered output. That first element, if it exists, gets the class.
*/
$tags = new WP_HTML_Tag_Processor( $block_content );
$tags = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );
if ( $tags->next_tag() ) {
$tags->add_class( wp_get_elements_class_name( $block ) );
}
Expand Down
8 changes: 4 additions & 4 deletions lib/block-supports/layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
}

// Prep the processor for modifying the block output.
$processor = new WP_HTML_Tag_Processor( $block_content );
$processor = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );

// Having no tags implies there are no tags onto which to add class names.
if ( ! $processor->next_tag() ) {
Expand Down Expand Up @@ -793,7 +793,7 @@ function gutenberg_render_layout_support_flag( $block_content, $block ) {
$inner_block_wrapper_classes = null;
$first_chunk = $block['innerContent'][0] ?? null;
if ( is_string( $first_chunk ) && count( $block['innerContent'] ) > 1 ) {
$first_chunk_processor = new WP_HTML_Tag_Processor( $first_chunk );
$first_chunk_processor = new Gutenberg_HTML_Tag_Processor_6_5( $first_chunk );
while ( $first_chunk_processor->next_tag() ) {
$class_attribute = $first_chunk_processor->get_attribute( 'class' );
if ( is_string( $class_attribute ) && ! empty( $class_attribute ) ) {
Expand Down Expand Up @@ -874,7 +874,7 @@ function gutenberg_restore_group_inner_container( $block_content, $block ) {
* have to be removed from the outer wrapper and then added to the inner.
*/
$layout_classes = array();
$processor = new WP_HTML_Tag_Processor( $block_content );
$processor = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );

if ( $processor->next_tag( array( 'class_name' => 'wp-block-group' ) ) ) {
if ( method_exists( $processor, 'class_list' ) ) {
Expand Down Expand Up @@ -917,7 +917,7 @@ static function ( $matches ) {

// Add layout classes to inner wrapper.
if ( ! empty( $layout_classes ) ) {
$processor = new WP_HTML_Tag_Processor( $updated_content );
$processor = new Gutenberg_HTML_Tag_Processor_6_5( $updated_content );
if ( $processor->next_tag( array( 'class_name' => 'wp-block-group__inner-container' ) ) ) {
foreach ( $layout_classes as $class_name ) {
$processor->add_class( $class_name );
Expand Down
2 changes: 1 addition & 1 deletion lib/block-supports/position.php
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function gutenberg_render_position_support( $block_content, $block ) {
);

// Inject class name to block container markup.
$content = new WP_HTML_Tag_Processor( $block_content );
$content = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );
$content->next_tag();
foreach ( $wrapper_classes as $class ) {
$content->add_class( $class );
Expand Down
2 changes: 1 addition & 1 deletion lib/block-supports/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function _gutenberg_add_block_level_presets_class( $block_content, $block ) {

// Like the layout hook this assumes the hook only applies to blocks with a single wrapper.
// Add the class name to the first element, presuming it's the wrapper, if it exists.
$tags = new WP_HTML_Tag_Processor( $block_content );
$tags = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );
if ( $tags->next_tag() ) {
$tags->add_class( _wp_get_presets_class_name( $block ) );
}
Expand Down
2 changes: 1 addition & 1 deletion lib/class-wp-duotone-gutenberg.php
Original file line number Diff line number Diff line change
Expand Up @@ -892,7 +892,7 @@ public static function render_duotone_support( $block_content, $block ) {
}

// Like the layout hook, this assumes the hook only applies to blocks with a single wrapper.
$tags = new WP_HTML_Tag_Processor( $block_content );
$tags = new Gutenberg_HTML_Tag_Processor_6_5( $block_content );
if ( $tags->next_tag() ) {
$tags->add_class( $filter_id );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
<?php
/**
* HTML API: WP_HTML_Active_Formatting_Elements class
*
* @package WordPress
* @subpackage HTML-API
* @since 6.4.0
*/

/**
* Core class used by the HTML processor during HTML parsing
* for managing the stack of active formatting elements.
*
* This class is designed for internal use by the HTML processor.
*
* > Initially, the list of active formatting elements is empty.
* > It is used to handle mis-nested formatting element tags.
* >
* > The list contains elements in the formatting category, and markers.
* > The markers are inserted when entering applet, object, marquee,
* > template, td, th, and caption elements, and are used to prevent
* > formatting from "leaking" into applet, object, marquee, template,
* > td, th, and caption elements.
* >
* > In addition, each element in the list of active formatting elements
* > is associated with the token for which it was created, so that
* > further elements can be created for that token if necessary.
*
* @since 6.4.0
*
* @access private
*
* @see https://html.spec.whatwg.org/#list-of-active-formatting-elements
* @see WP_HTML_Processor
*/
class Gutenberg_HTML_Active_Formatting_Elements_6_5 {
/**
* Holds the stack of active formatting element references.
*
* @since 6.4.0
*
* @var WP_HTML_Token[]
*/
private $stack = array();

/**
* Reports if a specific node is in the stack of active formatting elements.
*
* @since 6.4.0
*
* @param WP_HTML_Token $token Look for this node in the stack.
* @return bool Whether the referenced node is in the stack of active formatting elements.
*/
public function contains_node( $token ) {
foreach ( $this->walk_up() as $item ) {
if ( $token->bookmark_name === $item->bookmark_name ) {
return true;
}
}

return false;
}

/**
* Returns how many nodes are currently in the stack of active formatting elements.
*
* @since 6.4.0
*
* @return int How many node are in the stack of active formatting elements.
*/
public function count() {
return count( $this->stack );
}

/**
* Returns the node at the end of the stack of active formatting elements,
* if one exists. If the stack is empty, returns null.
*
* @since 6.4.0
*
* @return WP_HTML_Token|null Last node in the stack of active formatting elements, if one exists, otherwise null.
*/
public function current_node() {
$current_node = end( $this->stack );

return $current_node ? $current_node : null;
}

/**
* Pushes a node onto the stack of active formatting elements.
*
* @since 6.4.0
*
* @see https://html.spec.whatwg.org/#push-onto-the-list-of-active-formatting-elements
*
* @param WP_HTML_Token $token Push this node onto the stack.
*/
public function push( $token ) {
/*
* > If there are already three elements in the list of active formatting elements after the last marker,
* > if any, or anywhere in the list if there are no markers, that have the same tag name, namespace, and
* > attributes as element, then remove the earliest such element from the list of active formatting
* > elements. For these purposes, the attributes must be compared as they were when the elements were
* > created by the parser; two elements have the same attributes if all their parsed attributes can be
* > paired such that the two attributes in each pair have identical names, namespaces, and values
* > (the order of the attributes does not matter).
*
* @todo Implement the "Noah's Ark clause" to only add up to three of any given kind of formatting elements to the stack.
*/
// > Add element to the list of active formatting elements.
$this->stack[] = $token;
}

/**
* Removes a node from the stack of active formatting elements.
*
* @since 6.4.0
*
* @param WP_HTML_Token $token Remove this node from the stack, if it's there already.
* @return bool Whether the node was found and removed from the stack of active formatting elements.
*/
public function remove_node( $token ) {
foreach ( $this->walk_up() as $position_from_end => $item ) {
if ( $token->bookmark_name !== $item->bookmark_name ) {
continue;
}

$position_from_start = $this->count() - $position_from_end - 1;
array_splice( $this->stack, $position_from_start, 1 );
return true;
}

return false;
}

/**
* Steps through the stack of active formatting elements, starting with the
* top element (added first) and walking downwards to the one added last.
*
* This generator function is designed to be used inside a "foreach" loop.
*
* Example:
*
* $html = '<em><strong><a>We are here';
* foreach ( $stack->walk_down() as $node ) {
* echo "{$node->node_name} -> ";
* }
* > EM -> STRONG -> A ->
*
* To start with the most-recently added element and walk towards the top,
* see WP_HTML_Active_Formatting_Elements::walk_up().
*
* @since 6.4.0
*/
public function walk_down() {
$count = count( $this->stack );

for ( $i = 0; $i < $count; $i++ ) {
yield $this->stack[ $i ];
}
}

/**
* Steps through the stack of active formatting elements, starting with the
* bottom element (added last) and walking upwards to the one added first.
*
* This generator function is designed to be used inside a "foreach" loop.
*
* Example:
*
* $html = '<em><strong><a>We are here';
* foreach ( $stack->walk_up() as $node ) {
* echo "{$node->node_name} -> ";
* }
* > A -> STRONG -> EM ->
*
* To start with the first added element and walk towards the bottom,
* see WP_HTML_Active_Formatting_Elements::walk_down().
*
* @since 6.4.0
*/
public function walk_up() {
for ( $i = count( $this->stack ) - 1; $i >= 0; $i-- ) {
yield $this->stack[ $i ];
}
}
}
Loading
Loading