Skip to content

Commit 8955fac

Browse files
authored
Bug: inner blocks "anchor" field being applied to parent block resulting in duplicates (#63)
* Bug: inner blocks "anchor" field being applied to parent block resulting in duplicates * Refactor: Use parse_block instead of innerHTML * Chore: Check for is HTML is empty * Chore: Add Changeset
1 parent e9967c8 commit 8955fac

File tree

4 files changed

+53
-16
lines changed

4 files changed

+53
-16
lines changed

.changeset/quiet-insects-mate.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@wpengine/wp-graphql-content-blocks": patch
3+
---
4+
5+
Bug Fix: inner blocks "anchor" field being applied to parent block resulting in duplicates

includes/Field/BlockSupports/Anchor.php

+1-7
Original file line numberDiff line numberDiff line change
@@ -31,18 +31,12 @@ public static function register( WP_Block_Type $block_spec ) {
3131
'type' => 'string',
3232
'description' => __( 'The anchor field for the block.', 'wp-graphql-content-blocks' ),
3333
'resolve' => function ( $block ) {
34-
$attribute_config = array(
35-
'type' => 'string',
36-
'source' => 'attribute',
37-
'attribute' => 'id',
38-
'selector' => '*',
39-
);
4034
$rendered_block = wp_unslash( render_block( $block ) );
4135
$value = null;
4236
if ( empty( $rendered_block ) ) {
4337
return $value;
4438
}
45-
$value = DOMHelpers::parseAttribute( $rendered_block, $attribute_config['selector'], $attribute_config['attribute'], null );
39+
$value = DOMHelpers::parseFirstNodeAttribute( $rendered_block, 'id' );
4640
return $value;
4741
},
4842
),

includes/utilities/DomHelpers.php

+31-8
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,29 @@ public static function parseAttribute( $html, $selector, $attribute, $default =
3333
return $value;
3434
}
3535

36+
/**
37+
* Parses the given HTML string to extract the specified attribute selector of the first node.
38+
*
39+
* @param string $html The HTML string to parse.
40+
* @param string $attribute The attribute to extract of the first node.
41+
*
42+
* @return string|null extracted attribute
43+
*/
44+
public static function parseFirstNodeAttribute( $html, $attribute ) {
45+
$value = null;
46+
if ( trim( empty( $html ) ) ) {
47+
return $value;
48+
}
49+
$doc = new Document( $html );
50+
// <html><body>$html</body></html>
51+
$elem = $doc->find( '*' )[2];
52+
if ( $elem ) {
53+
$value = $elem->getAttribute( $attribute );
54+
}
55+
56+
return $value;
57+
}
58+
3659
/**
3760
* Parses the given HTML string to extract the innerHTML contents.
3861
*
@@ -53,16 +76,16 @@ public static function parseHTML( $html, $selector, $default = null ) {
5376
}
5477
return $inner_html;
5578
}
56-
79+
5780
/**
5881
* Parses the given HTML string and extracts the specified elements.
59-
*
82+
*
6083
* @param string $html The HTML string to parse.
6184
* @param string $element The element (selector) to extract.
62-
*
85+
*
6386
* @return string|null the HTML string of the extracted elements
6487
*/
65-
public static function getElementsFromHTML($html, $element) {
88+
public static function getElementsFromHTML( $html, $element ) {
6689
$doc = new Document();
6790
$doc->loadHTML( $html );
6891
$elements = $doc->find( $element );
@@ -79,18 +102,18 @@ public static function getElementsFromHTML($html, $element) {
79102
/**
80103
* Gets the text content of a given selector. If multiple selectors exist,
81104
* the first result will be used.
82-
*
105+
*
83106
* @param string $html The HTML string to parse.
84107
* @param string $selector The selector to get the text content from.
85-
*
108+
*
86109
* @return string|null The text content of the selector if found.
87110
*/
88-
public static function getTextFromSelector($html, $selector) {
111+
public static function getTextFromSelector( $html, $selector ) {
89112
$doc = new Document();
90113
$doc->loadHTML( $html );
91114
$nodes = $doc->find( $selector );
92115

93-
if( count( $nodes ) === 0 ) {
116+
if ( count( $nodes ) === 0 ) {
94117
return null;
95118
}
96119

tests/unit/BlockSupportsAnchorTest.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ public function setUp(): void {
2727
<!-- wp:paragraph -->
2828
<p>Example paragraph without Anchor</p>
2929
<!-- /wp:paragraph -->
30+
31+
<!-- wp:group -->
32+
<div class="wp-block-group">
33+
<!-- wp:paragraph -->
34+
<p id="example-inner">Example inner block</p>
35+
<!-- /wp:paragraph -->
36+
<!-- /wp:group -->
3037
'
3138
)
3239
),
@@ -109,10 +116,18 @@ public function test_register_anchor_query_field() {
109116
}';
110117
$actual = graphql( array( 'query' => $query ) );
111118
$node = $actual['data']['posts']['nodes'][0];
112-
$this->assertEquals( count( $node['editorBlocks'] ), 2 );
119+
120+
$this->assertEquals( count( $node['editorBlocks'] ), 4 );
113121
$this->assertEquals( $node['editorBlocks'][0]['name'], 'core/paragraph' );
114122
$this->assertEquals( $node['editorBlocks'][0]['anchor'], 'example' );
123+
115124
$this->assertEquals( $node['editorBlocks'][1]['name'], 'core/paragraph' );
116125
$this->assertNull( $node['editorBlocks'][1]['anchor'] );
126+
127+
$this->assertEquals( $node['editorBlocks'][2]['name'], 'core/group' );
128+
$this->assertNull( $node['editorBlocks'][2]['anchor'] );
129+
130+
$this->assertEquals( $node['editorBlocks'][3]['name'], 'core/paragraph' );
131+
$this->assertEquals( $node['editorBlocks'][3]['anchor'], 'example-inner' );
117132
}
118133
}

0 commit comments

Comments
 (0)