Skip to content

Commit

Permalink
Bits: Introduce the ability to store and render bits
Browse files Browse the repository at this point in the history
  • Loading branch information
dmsnell committed Apr 14, 2024
1 parent a584c4e commit f25ae3d
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 1 deletion.
2 changes: 2 additions & 0 deletions src/wp-includes/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -1714,6 +1714,8 @@ function render_block( $parsed_block ) {
* @return array[] Array of parsed block objects.
*/
function parse_blocks( $content ) {
$content = wp_replace_bits( $content );

/**
* Filter to allow plugins to replace the server-side block parser.
*
Expand Down
77 changes: 77 additions & 0 deletions src/wp-includes/html-api/class-wp-bits.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php

function wp_replace_bits( $content ) {
$processor = new class ( $content ) extends WP_HTML_Tag_Processor {

Check failure on line 4 in src/wp-includes/html-api/class-wp-bits.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

There must be no space between the class keyword and the open parenthesis for an anonymous class. Found: 1 space
private $deferred_updates = array();

public function replace_token( $new_content ) {
$this->set_bookmark( 'here' );
$here = $this->bookmarks['here'];

$this->deferred_updates[] = new WP_HTML_Text_Replacement(
$here->start,
$here->length,
$new_content
);
}

public function flush_updates() {
foreach ( $this->deferred_updates as $update ) {
$this->lexical_updates[] = $update;
}
}
};

while ( $processor->next_token() ) {
switch ( $processor->get_token_type() ) {
case '#funky-comment':
$processor->replace_token( '<b>bl<em>ar</em>g</b>' );
break;

case '#tag':
foreach ( $processor->get_attribute_names_with_prefix( '' ) ?? [] as $name ) {

Check failure on line 32 in src/wp-includes/html-api/class-wp-bits.php

View workflow job for this annotation

GitHub Actions / PHP coding standards

Short array syntax is not allowed
$value = $processor->get_attribute( $name );
if ( is_string( $value ) ) {
$new_value = preg_replace_callback(
'~<//wp:([^>]+)>~',
static function ( $bit ) {
return 'blarg';
},
$value
);

if ( $new_value !== $value ) {
$processor->set_attribute( $name, $new_value );
}
}
}
break;

case '#comment':
if ( WP_HTML_Tag_Processor::COMMENT_AS_HTML_COMMENT !== $processor->get_comment_type() ) {
break;
}

$text = $processor->get_modifiable_text();
if ( 1 === preg_match( '~^<//wp:([^>]+)>$~', $text ) ) {
$processor->replace_token( '<b>Bla<em>rg</em>!</b>' );
break;
}

$new_value = preg_replace_callback(
'~<//wp:([^>]+)>~',
static function ( $bit ) {
return 'blarg';
},
$text
);

$processor->replace_token( "<!--{$new_value}-->" );
break;
}
}
$processor->flush_updates();
$content = $processor->get_updated_html();

return $content;
}
7 changes: 6 additions & 1 deletion src/wp-includes/kses.php
Original file line number Diff line number Diff line change
Expand Up @@ -981,7 +981,7 @@ function wp_kses_split( $content, $allowed_html, $allowed_protocols ) {
$pass_allowed_html = $allowed_html;
$pass_allowed_protocols = $allowed_protocols;

return preg_replace_callback( '%(<!--.*?(-->|$))|(<[^>]*(>|$)|>)%', '_wp_kses_split_callback', $content );
return preg_replace_callback( '%((?:<!--.*?(-->|$))|</[^a-z][^>]*>)|(<[^>]*(>|$)|>)%', '_wp_kses_split_callback', $content );
}

/**
Expand Down Expand Up @@ -1085,6 +1085,11 @@ function wp_kses_split2( $content, $allowed_html, $allowed_protocols ) {
return '&gt;';
}

// Allows Bits.
if ( 1 === preg_match( '~</[^a-z][^>]*>~', $content ) ) {
return $content;
}

// Allow HTML comments.
if ( str_starts_with( $content, '<!--' ) ) {
$content = str_replace( array( '<!--', '-->' ), '', $content );
Expand Down
1 change: 1 addition & 0 deletions src/wp-settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@
require ABSPATH . WPINC . '/html-api/class-wp-html-token.php';
require ABSPATH . WPINC . '/html-api/class-wp-html-processor-state.php';
require ABSPATH . WPINC . '/html-api/class-wp-html-processor.php';
require ABSPATH . WPINC . '/html-api/class-wp-bits.php';
require ABSPATH . WPINC . '/class-wp-http.php';
require ABSPATH . WPINC . '/class-wp-http-streams.php';
require ABSPATH . WPINC . '/class-wp-http-curl.php';
Expand Down

0 comments on commit f25ae3d

Please sign in to comment.