Skip to content

Commit

Permalink
Block supports: Restore root DOMDocument save (#25028)
Browse files Browse the repository at this point in the history
  • Loading branch information
sirreal authored Sep 7, 2020
1 parent 353eada commit 124eee7
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 7 deletions.
25 changes: 18 additions & 7 deletions lib/block-supports/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,18 @@ function gutenberg_apply_block_supports( $block_content, $block ) {
return $block_content;
}

// We need to wrap the block in order to handle UTF-8 properly.
$wrapper_left = '<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>';
$wrapper_right = '</body></html>';

$dom = new DOMDocument( '1.0', 'utf-8' );

// Suppress DOMDocument::loadHTML warnings from polluting the front-end.
$previous = libxml_use_internal_errors( true );

$success = $dom->loadHTML( $wrapper_left . $block_content . $wrapper_right, LIBXML_HTML_NODEFDTD | LIBXML_COMPACT );
// We need to wrap the block in order to handle UTF-8 properly.
$wrapped_block_html =
'<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body>'
. $block_content
. '</body></html>';

$success = $dom->loadHTML( $wrapped_block_html, LIBXML_HTML_NODEFDTD | LIBXML_COMPACT );

// Clear errors and reset the use_errors setting.
libxml_clear_errors();
Expand All @@ -71,9 +73,13 @@ function gutenberg_apply_block_supports( $block_content, $block ) {
return $block_content;
}

// Structure is like `<html><head/><body/></html>`, so body is the `lastChild` of our document.
$body_element = $dom->documentElement->lastChild; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase

$xpath = new DOMXPath( $dom );
$block_root = $xpath->query( '/html/body/*' )[0];
$block_root = $xpath->query( './*', $body_element )[0];

// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
if ( empty( $block_root ) ) {
return $block_content;
}
Expand All @@ -98,7 +104,12 @@ function gutenberg_apply_block_supports( $block_content, $block ) {
$block_root->setAttribute( 'style', implode( '; ', $new_styles ) . ';' );
}

return $dom->saveHtml( $block_root );
$result = '';
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
foreach ( $body_element->childNodes as $child_node ) {
$result .= $dom->saveHtml( $child_node );
}
return $result;
}
add_filter( 'render_block', 'gutenberg_apply_block_supports', 10, 2 );

Expand Down
36 changes: 36 additions & 0 deletions phpunit/class-block-supported-styles-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -861,4 +861,40 @@ public function test_render_block_attribute() {
$this->assertEquals( $expected, $result );
}
}

/**
* Ensure that HTML appended to the block content is preserved.
*/
public function test_render_block_includes_appended_html() {
$this->register_block_type(
'core/example',
array(
'render_callback' => function( $attributes, $content ) {
return $content . '<div>Appended</div>';
},
)
);

$result = do_blocks( '<!-- wp:core/example --><p>Hello from the block content!</p><!-- /wp:core/example -->' );

$this->assertEquals( '<p class="wp-block-example">Hello from the block content!</p><div>Appended</div>', $result );
}

/**
* Should not error when the rendered block is text only.
*/
public function test_render_block_rendered_text_node() {
$this->register_block_type(
'core/example',
array(
'render_callback' => function() {
return 'This is rendered as just text.';
},
)
);

$result = do_blocks( '<!-- wp:core/example /-->' );

$this->assertEquals( 'This is rendered as just text.', $result );
}
}

0 comments on commit 124eee7

Please sign in to comment.