run:R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:52
R W Run
DIR
2026-03-11 16:18:51
R W Run
DIR
2026-03-11 16:18:51
R W Run
23.8 KB
2026-03-11 16:18:51
R W Run
7.8 KB
2026-03-11 16:18:52
R W Run
36.1 KB
2026-03-11 16:18:51
R W Run
11.9 KB
2026-03-11 16:18:52
R W Run
18.94 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:52
R W Run
28.6 KB
2026-03-11 16:18:51
R W Run
316 By
2026-03-11 16:18:51
R W Run
12.9 KB
2026-03-11 16:18:51
R W Run
61.02 KB
2026-03-11 16:18:52
R W Run
15 KB
2026-03-11 16:18:51
R W Run
112.05 KB
2026-03-11 16:18:51
R W Run
12.47 KB
2026-03-11 16:18:51
R W Run
15.07 KB
2026-03-11 16:18:52
R W Run
9.84 KB
2026-03-11 16:18:52
R W Run
13.17 KB
2026-03-11 16:18:52
R W Run
33.83 KB
2026-03-11 16:18:51
R W Run
42.63 KB
2026-03-11 16:18:51
R W Run
55.71 KB
2026-03-11 16:18:52
R W Run
12.53 KB
2026-03-11 16:18:51
R W Run
2.55 KB
2026-03-11 16:18:52
R W Run
28.92 KB
2026-03-11 16:18:52
R W Run
539 By
2026-03-11 16:18:51
R W Run
367 By
2026-03-11 16:18:52
R W Run
42.65 KB
2026-03-11 16:18:51
R W Run
401 By
2026-03-11 16:18:51
R W Run
6.61 KB
2026-03-11 16:18:51
R W Run
664 By
2026-03-11 16:18:52
R W Run
20.63 KB
2026-03-11 16:18:51
R W Run
2.18 KB
2026-03-11 16:18:52
R W Run
453 By
2026-03-11 16:18:52
R W Run
457 By
2026-03-11 16:18:51
R W Run
36.83 KB
2026-03-11 16:18:52
R W Run
2.41 KB
2026-03-11 16:18:52
R W Run
8.28 KB
2026-03-11 16:18:51
R W Run
13.89 KB
2026-03-11 16:18:51
R W Run
11.76 KB
2026-03-11 16:18:51
R W Run
2.65 KB
2026-03-11 16:18:51
R W Run
7.43 KB
2026-03-11 16:18:51
R W Run
17.46 KB
2026-03-11 16:18:51
R W Run
5.14 KB
2026-03-11 16:18:52
R W Run
16.7 KB
2026-03-11 16:18:51
R W Run
8.28 KB
2026-03-11 16:18:52
R W Run
2.92 KB
2026-03-11 16:18:52
R W Run
1.32 KB
2026-03-11 16:18:51
R W Run
4.6 KB
2026-03-11 16:18:52
R W Run
11.62 KB
2026-03-11 16:18:52
R W Run
2.5 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
11.25 KB
2026-03-11 16:18:52
R W Run
5.32 KB
2026-03-11 16:18:51
R W Run
10.99 KB
2026-03-11 16:18:52
R W Run
68.32 KB
2026-03-11 16:18:51
R W Run
6.34 KB
2026-03-11 16:18:51
R W Run
5.49 KB
2026-03-11 16:18:51
R W Run
1.99 KB
2026-03-11 16:18:52
R W Run
7.02 KB
2026-03-11 16:18:51
R W Run
4.91 KB
2026-03-11 16:18:52
R W Run
16.86 KB
2026-03-11 16:18:51
R W Run
24.23 KB
2026-03-11 16:18:51
R W Run
3.97 KB
2026-03-11 16:18:51
R W Run
47.66 KB
2026-03-11 16:18:51
R W Run
9.22 KB
2026-03-11 16:18:51
R W Run
25.51 KB
2026-03-11 16:18:51
R W Run
198.38 KB
2026-03-11 16:18:52
R W Run
56.65 KB
2026-03-11 16:18:51
R W Run
10.46 KB
2026-03-11 16:18:51
R W Run
10.95 KB
2026-03-11 16:18:52
R W Run
29.26 KB
2026-03-11 16:18:51
R W Run
70.91 KB
2026-03-11 16:18:52
R W Run
35.3 KB
2026-03-11 16:18:52
R W Run
16.61 KB
2026-03-11 16:18:52
R W Run
2.57 KB
2026-03-11 16:18:52
R W Run
39.83 KB
2026-03-11 16:18:51
R W Run
70.64 KB
2026-03-11 16:18:51
R W Run
15.56 KB
2026-03-11 16:18:52
R W Run
7.33 KB
2026-03-11 16:18:52
R W Run
253 By
2026-03-11 16:18:51
R W Run
7.96 KB
2026-03-11 16:18:52
R W Run
3.23 KB
2026-03-11 16:18:52
R W Run
969 By
2026-03-11 16:18:52
R W Run
16.28 KB
2026-03-11 16:18:51
R W Run
7.22 KB
2026-03-11 16:18:51
R W Run
12.95 KB
2026-03-11 16:18:51
R W Run
6.53 KB
2026-03-11 16:18:51
R W Run
3.42 KB
2026-03-11 16:18:52
R W Run
5.84 KB
2026-03-11 16:18:51
R W Run
1.97 KB
2026-03-11 16:18:51
R W Run
4.3 KB
2026-03-11 16:18:52
R W Run
2.91 KB
2026-03-11 16:18:51
R W Run
16.46 KB
2026-03-11 16:18:52
R W Run
40.6 KB
2026-03-11 16:18:51
R W Run
20.22 KB
2026-03-11 16:18:51
R W Run
36.11 KB
2026-03-11 16:18:52
R W Run
17.01 KB
2026-03-11 16:18:51
R W Run
7.27 KB
2026-03-11 16:18:52
R W Run
6.62 KB
2026-03-11 16:18:52
R W Run
16.49 KB
2026-03-11 16:18:52
R W Run
1.79 KB
2026-03-11 16:18:52
R W Run
29.82 KB
2026-03-11 16:18:51
R W Run
6.67 KB
2026-03-11 16:18:52
R W Run
8.98 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:51
R W Run
12.01 KB
2026-03-11 16:18:51
R W Run
17.11 KB
2026-03-11 16:18:51
R W Run
6.74 KB
2026-03-11 16:18:52
R W Run
30.93 KB
2026-03-11 16:18:51
R W Run
4.99 KB
2026-03-11 16:18:51
R W Run
4.25 KB
2026-03-11 16:18:51
R W Run
24.72 KB
2026-03-11 16:18:51
R W Run
29.96 KB
2026-03-11 16:18:52
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
160 KB
2026-03-11 16:18:51
R W Run
6.72 KB
2026-03-11 16:18:52
R W Run
10.92 KB
2026-03-11 16:18:51
R W Run
4.77 KB
2026-03-11 16:18:51
R W Run
3.38 KB
2026-03-11 16:18:51
R W Run
11.18 KB
2026-03-11 16:18:51
R W Run
62.19 KB
2026-03-11 16:18:51
R W Run
2.46 KB
2026-03-11 16:18:51
R W Run
9.17 KB
2026-03-11 16:18:51
R W Run
32.15 KB
2026-03-11 16:18:51
R W Run
34.05 KB
2026-03-11 16:18:52
R W Run
7.15 KB
2026-03-11 16:18:51
R W Run
3.47 KB
2026-03-11 16:18:52
R W Run
1.87 KB
2026-03-11 16:18:52
R W Run
30.91 KB
2026-03-11 16:18:51
R W Run
7.29 KB
2026-03-11 16:18:52
R W Run
7.35 KB
2026-03-11 16:18:51
R W Run
12.54 KB
2026-03-11 16:18:51
R W Run
19.12 KB
2026-03-11 16:18:51
R W Run
18.12 KB
2026-03-11 16:18:52
R W Run
39.99 KB
2026-03-11 16:18:52
R W Run
5.17 KB
2026-03-11 16:18:52
R W Run
979 By
2026-03-11 16:18:51
R W Run
18.44 KB
2026-03-11 16:18:52
R W Run
10.24 KB
2026-03-11 16:18:51
R W Run
1.77 KB
2026-03-11 16:18:52
R W Run
34.9 KB
2026-03-11 16:18:51
R W Run
7.19 KB
2026-03-11 16:18:52
R W Run
160.5 KB
2026-03-11 16:18:51
R W Run
64.27 KB
2026-03-11 16:18:51
R W Run
27.95 KB
2026-03-11 16:18:51
R W Run
4.69 KB
2026-03-11 16:18:51
R W Run
2.94 KB
2026-03-11 16:18:51
R W Run
43.13 KB
2026-03-11 16:18:52
R W Run
2.25 KB
2026-03-11 16:18:52
R W Run
22.5 KB
2026-03-11 16:18:51
R W Run
13.01 KB
2026-03-11 16:18:52
R W Run
3.27 KB
2026-03-11 16:18:51
R W Run
18 KB
2026-03-11 16:18:51
R W Run
210.4 KB
2026-03-11 16:18:52
R W Run
25.86 KB
2026-03-11 16:18:52
R W Run
115.85 KB
2026-03-11 16:18:51
R W Run
373 By
2026-03-11 16:18:52
R W Run
343 By
2026-03-11 16:18:52
R W Run
338 By
2026-03-11 16:18:51
R W Run
100.73 KB
2026-03-11 16:18:52
R W Run
130.93 KB
2026-03-11 16:18:51
R W Run
19.1 KB
2026-03-11 16:18:51
R W Run
17.41 KB
2026-03-11 16:18:52
R W Run
41.98 KB
2026-03-11 16:18:52
R W Run
400 By
2026-03-11 16:18:52
R W Run
11.1 KB
2026-03-11 16:18:52
R W Run
37.02 KB
2026-03-11 16:18:51
R W Run
2.24 KB
2026-03-11 16:18:51
R W Run
188.13 KB
2026-03-11 16:18:51
R W Run
338 By
2026-03-11 16:18:51
R W Run
38 KB
2026-03-11 16:18:51
R W Run
4.02 KB
2026-03-11 16:18:52
R W Run
5.38 KB
2026-03-11 16:18:51
R W Run
3.05 KB
2026-03-11 16:18:52
R W Run
2.61 KB
2026-03-11 16:18:51
R W Run
1.16 KB
2026-03-11 16:18:52
R W Run
4.04 KB
2026-03-11 16:18:51
R W Run
3.71 KB
2026-03-11 16:18:51
R W Run
24.6 KB
2026-03-11 16:18:51
R W Run
9.56 KB
2026-03-11 16:18:51
R W Run
346.43 KB
2026-03-11 16:18:52
R W Run
281.84 KB
2026-03-11 16:18:52
R W Run
14.95 KB
2026-03-11 16:18:51
R W Run
8.44 KB
2026-03-11 16:18:52
R W Run
168.95 KB
2026-03-11 16:18:52
R W Run
20.71 KB
2026-03-11 16:18:52
R W Run
25.27 KB
2026-03-11 16:18:51
R W Run
5.72 KB
2026-03-11 16:18:51
R W Run
4.63 KB
2026-03-11 16:18:52
R W Run
81.73 KB
2026-03-11 16:18:51
R W Run
67.18 KB
2026-03-11 16:18:51
R W Run
156.36 KB
2026-03-11 16:18:52
R W Run
55.19 KB
2026-03-11 16:18:51
R W Run
162 By
2026-03-11 16:18:51
R W Run
61.72 KB
2026-03-11 16:18:51
R W Run
216.06 KB
2026-03-11 16:18:52
R W Run
65.09 KB
2026-03-11 16:18:51
R W Run
25.24 KB
2026-03-11 16:18:52
R W Run
4.81 KB
2026-03-11 16:18:51
R W Run
6.48 KB
2026-03-11 16:18:52
R W Run
21.25 KB
2026-03-11 16:18:51
R W Run
2.79 KB
2026-03-11 16:18:52
R W Run
89.69 KB
2026-03-11 16:18:52
R W Run
19.42 KB
2026-03-11 16:18:52
R W Run
3.69 KB
2026-03-11 16:18:52
R W Run
4.11 KB
2026-03-11 16:18:51
R W Run
40.74 KB
2026-03-11 16:18:51
R W Run
25.38 KB
2026-03-11 16:18:51
R W Run
43.31 KB
2026-03-11 16:18:52
R W Run
102.57 KB
2026-03-11 16:18:52
R W Run
6.18 KB
2026-03-11 16:18:51
R W Run
124.47 KB
2026-03-11 16:18:52
R W Run
35.65 KB
2026-03-11 16:18:52
R W Run
6.94 KB
2026-03-11 16:18:52
R W Run
67.04 KB
2026-03-11 16:18:52
R W Run
10.62 KB
2026-03-11 16:18:51
R W Run
289.35 KB
2026-03-11 16:18:52
R W Run
36.23 KB
2026-03-11 16:18:51
R W Run
200 By
2026-03-11 16:18:52
R W Run
200 By
2026-03-11 16:18:52
R W Run
98.29 KB
2026-03-11 16:18:52
R W Run
30.02 KB
2026-03-11 16:18:52
R W Run
19.03 KB
2026-03-11 16:18:52
R W Run
5.06 KB
2026-03-11 16:18:52
R W Run
255 By
2026-03-11 16:18:51
R W Run
22.66 KB
2026-03-11 16:18:52
R W Run
154.63 KB
2026-03-11 16:18:51
R W Run
9.68 KB
2026-03-11 16:18:51
R W Run
258 By
2026-03-11 16:18:51
R W Run
23.49 KB
2026-03-11 16:18:51
R W Run
3.16 KB
2026-03-11 16:18:51
R W Run
8.4 KB
2026-03-11 16:18:52
R W Run
441 By
2026-03-11 16:18:51
R W Run
7.39 KB
2026-03-11 16:18:51
R W Run
173 KB
2026-03-11 16:18:52
R W Run
544 By
2026-03-11 16:18:52
R W Run
4.17 KB
2026-03-11 16:18:51
R W Run
35.97 KB
2026-03-11 16:18:52
R W Run
1.69 KB
2026-03-11 16:18:51
R W Run
2.84 KB
2026-03-11 16:18:52
R W Run
6.09 KB
2026-03-11 16:18:51
R W Run
8.71 KB
2026-03-11 16:18:51
R W Run
131.84 KB
2026-03-11 16:18:51
R W Run
37.45 KB
2026-03-11 16:18:51
R W Run
173.89 KB
2026-03-11 16:18:51
R W Run
7.09 KB
2026-03-11 16:18:51
R W Run
6.41 KB
2026-03-11 16:18:51
R W Run
1.08 KB
2026-03-11 16:18:51
R W Run
69.46 KB
2026-03-11 16:18:52
R W Run
445 By
2026-03-11 16:18:51
R W Run
799 By
2026-03-11 16:18:52
R W Run
error_log
📄class-wp-block-parser.php
1<?php
2/**
3 * Block Serialization Parser
4 *
5 * @package WordPress
6 */
7
8/**
9 * Class WP_Block_Parser
10 *
11 * Parses a document and constructs a list of parsed block objects
12 *
13 * @since 5.0.0
14 * @since 4.0.0 returns arrays not objects, all attributes are arrays
15 */
16class WP_Block_Parser {
17 /**
18 * Input document being parsed
19 *
20 * @example "Pre-text\n<!-- wp:paragraph -->This is inside a block!<!-- /wp:paragraph -->"
21 *
22 * @since 5.0.0
23 * @var string
24 */
25 public $document;
26
27 /**
28 * Tracks parsing progress through document
29 *
30 * @since 5.0.0
31 * @var int
32 */
33 public $offset;
34
35 /**
36 * List of parsed blocks
37 *
38 * @since 5.0.0
39 * @var array[]
40 */
41 public $output;
42
43 /**
44 * Stack of partially-parsed structures in memory during parse
45 *
46 * @since 5.0.0
47 * @var WP_Block_Parser_Frame[]
48 */
49 public $stack;
50
51 /**
52 * Parses a document and returns a list of block structures
53 *
54 * When encountering an invalid parse will return a best-effort
55 * parse. In contrast to the specification parser this does not
56 * return an error on invalid inputs.
57 *
58 * @since 5.0.0
59 *
60 * @param string $document Input document being parsed.
61 * @return array[]
62 */
63 public function parse( $document ) {
64 $this->document = $document;
65 $this->offset = 0;
66 $this->output = array();
67 $this->stack = array();
68
69 while ( $this->proceed() ) {
70 continue;
71 }
72
73 return $this->output;
74 }
75
76 /**
77 * Processes the next token from the input document
78 * and returns whether to proceed eating more tokens
79 *
80 * This is the "next step" function that essentially
81 * takes a token as its input and decides what to do
82 * with that token before descending deeper into a
83 * nested block tree or continuing along the document
84 * or breaking out of a level of nesting.
85 *
86 * @internal
87 * @since 5.0.0
88 * @return bool
89 */
90 public function proceed() {
91 $next_token = $this->next_token();
92 list( $token_type, $block_name, $attrs, $start_offset, $token_length ) = $next_token;
93 $stack_depth = count( $this->stack );
94
95 // we may have some HTML soup before the next block.
96 $leading_html_start = $start_offset > $this->offset ? $this->offset : null;
97
98 switch ( $token_type ) {
99 case 'no-more-tokens':
100 // if not in a block then flush output.
101 if ( 0 === $stack_depth ) {
102 $this->add_freeform();
103 return false;
104 }
105
106 /*
107 * Otherwise we have a problem
108 * This is an error
109 *
110 * we have options
111 * - treat it all as freeform text
112 * - assume an implicit closer (easiest when not nesting)
113 */
114
115 // for the easy case we'll assume an implicit closer.
116 if ( 1 === $stack_depth ) {
117 $this->add_block_from_stack();
118 return false;
119 }
120
121 /*
122 * for the nested case where it's more difficult we'll
123 * have to assume that multiple closers are missing
124 * and so we'll collapse the whole stack piecewise
125 */
126 while ( 0 < count( $this->stack ) ) {
127 $this->add_block_from_stack();
128 }
129 return false;
130
131 case 'void-block':
132 /*
133 * easy case is if we stumbled upon a void block
134 * in the top-level of the document
135 */
136 if ( 0 === $stack_depth ) {
137 if ( isset( $leading_html_start ) ) {
138 $this->output[] = (array) $this->freeform(
139 substr(
140 $this->document,
141 $leading_html_start,
142 $start_offset - $leading_html_start
143 )
144 );
145 }
146
147 $this->output[] = (array) new WP_Block_Parser_Block( $block_name, $attrs, array(), '', array() );
148 $this->offset = $start_offset + $token_length;
149 return true;
150 }
151
152 // otherwise we found an inner block.
153 $this->add_inner_block(
154 new WP_Block_Parser_Block( $block_name, $attrs, array(), '', array() ),
155 $start_offset,
156 $token_length
157 );
158 $this->offset = $start_offset + $token_length;
159 return true;
160
161 case 'block-opener':
162 // track all newly-opened blocks on the stack.
163 array_push(
164 $this->stack,
165 new WP_Block_Parser_Frame(
166 new WP_Block_Parser_Block( $block_name, $attrs, array(), '', array() ),
167 $start_offset,
168 $token_length,
169 $start_offset + $token_length,
170 $leading_html_start
171 )
172 );
173 $this->offset = $start_offset + $token_length;
174 return true;
175
176 case 'block-closer':
177 /*
178 * if we're missing an opener we're in trouble
179 * This is an error
180 */
181 if ( 0 === $stack_depth ) {
182 /*
183 * we have options
184 * - assume an implicit opener
185 * - assume _this_ is the opener
186 * - give up and close out the document
187 */
188 $this->add_freeform();
189 return false;
190 }
191
192 // if we're not nesting then this is easy - close the block.
193 if ( 1 === $stack_depth ) {
194 $this->add_block_from_stack( $start_offset );
195 $this->offset = $start_offset + $token_length;
196 return true;
197 }
198
199 /*
200 * otherwise we're nested and we have to close out the current
201 * block and add it as a new innerBlock to the parent
202 */
203 $stack_top = array_pop( $this->stack );
204 $html = substr( $this->document, $stack_top->prev_offset, $start_offset - $stack_top->prev_offset );
205 $stack_top->block->innerHTML .= $html;
206 $stack_top->block->innerContent[] = $html;
207 $stack_top->prev_offset = $start_offset + $token_length;
208
209 $this->add_inner_block(
210 $stack_top->block,
211 $stack_top->token_start,
212 $stack_top->token_length,
213 $start_offset + $token_length
214 );
215 $this->offset = $start_offset + $token_length;
216 return true;
217
218 default:
219 // This is an error.
220 $this->add_freeform();
221 return false;
222 }
223 }
224
225 /**
226 * Scans the document from where we last left off
227 * and finds the next valid token to parse if it exists
228 *
229 * Returns the type of the find: kind of find, block information, attributes
230 *
231 * @internal
232 * @since 5.0.0
233 * @since 4.6.1 fixed a bug in attribute parsing which caused catastrophic backtracking on invalid block comments
234 * @return array
235 */
236 public function next_token() {
237 $matches = null;
238
239 /*
240 * aye the magic
241 * we're using a single RegExp to tokenize the block comment delimiters
242 * we're also using a trick here because the only difference between a
243 * block opener and a block closer is the leading `/` before `wp:` (and
244 * a closer has no attributes). we can trap them both and process the
245 * match back in PHP to see which one it was.
246 */
247 $has_match = preg_match(
248 '/<!--\s+(?P<closer>\/)?wp:(?P<namespace>[a-z][a-z0-9_-]*\/)?(?P<name>[a-z][a-z0-9_-]*)\s+(?P<attrs>{(?:(?:[^}]+|}+(?=})|(?!}\s+\/?-->).)*+)?}\s+)?(?P<void>\/)?-->/s',
249 $this->document,
250 $matches,
251 PREG_OFFSET_CAPTURE,
252 $this->offset
253 );
254
255 // if we get here we probably have catastrophic backtracking or out-of-memory in the PCRE.
256 if ( false === $has_match ) {
257 return array( 'no-more-tokens', null, null, null, null );
258 }
259
260 // we have no more tokens.
261 if ( 0 === $has_match ) {
262 return array( 'no-more-tokens', null, null, null, null );
263 }
264
265 list( $match, $started_at ) = $matches[0];
266
267 $length = strlen( $match );
268 $is_closer = isset( $matches['closer'] ) && -1 !== $matches['closer'][1];
269 $is_void = isset( $matches['void'] ) && -1 !== $matches['void'][1];
270 $namespace = $matches['namespace'];
271 $namespace = ( isset( $namespace ) && -1 !== $namespace[1] ) ? $namespace[0] : 'core/';
272 $name = $namespace . $matches['name'][0];
273 $has_attrs = isset( $matches['attrs'] ) && -1 !== $matches['attrs'][1];
274
275 /*
276 * Fun fact! It's not trivial in PHP to create "an empty associative array" since all arrays
277 * are associative arrays. If we use `array()` we get a JSON `[]`
278 */
279 $attrs = $has_attrs
280 ? json_decode( $matches['attrs'][0], /* as-associative */ true )
281 : array();
282
283 /*
284 * This state isn't allowed
285 * This is an error
286 */
287 if ( $is_closer && ( $is_void || $has_attrs ) ) {
288 // we can ignore them since they don't hurt anything.
289 }
290
291 if ( $is_void ) {
292 return array( 'void-block', $name, $attrs, $started_at, $length );
293 }
294
295 if ( $is_closer ) {
296 return array( 'block-closer', $name, null, $started_at, $length );
297 }
298
299 return array( 'block-opener', $name, $attrs, $started_at, $length );
300 }
301
302 /**
303 * Returns a new block object for freeform HTML
304 *
305 * @internal
306 * @since 5.0.0
307 *
308 * @param string $inner_html HTML content of block.
309 * @return WP_Block_Parser_Block freeform block object.
310 */
311 public function freeform( $inner_html ) {
312 return new WP_Block_Parser_Block( null, array(), array(), $inner_html, array( $inner_html ) );
313 }
314
315 /**
316 * Pushes a length of text from the input document
317 * to the output list as a freeform block.
318 *
319 * @internal
320 * @since 5.0.0
321 * @param null $length how many bytes of document text to output.
322 */
323 public function add_freeform( $length = null ) {
324 $length = $length ? $length : strlen( $this->document ) - $this->offset;
325
326 if ( 0 === $length ) {
327 return;
328 }
329
330 $this->output[] = (array) $this->freeform( substr( $this->document, $this->offset, $length ) );
331 }
332
333 /**
334 * Given a block structure from memory pushes
335 * a new block to the output list.
336 *
337 * @internal
338 * @since 5.0.0
339 * @param WP_Block_Parser_Block $block The block to add to the output.
340 * @param int $token_start Byte offset into the document where the first token for the block starts.
341 * @param int $token_length Byte length of entire block from start of opening token to end of closing token.
342 * @param int|null $last_offset Last byte offset into document if continuing form earlier output.
343 */
344 public function add_inner_block( WP_Block_Parser_Block $block, $token_start, $token_length, $last_offset = null ) {
345 $parent = $this->stack[ count( $this->stack ) - 1 ];
346 $parent->block->innerBlocks[] = (array) $block;
347 $html = substr( $this->document, $parent->prev_offset, $token_start - $parent->prev_offset );
348
349 if ( ! empty( $html ) ) {
350 $parent->block->innerHTML .= $html;
351 $parent->block->innerContent[] = $html;
352 }
353
354 $parent->block->innerContent[] = null;
355 $parent->prev_offset = $last_offset ? $last_offset : $token_start + $token_length;
356 }
357
358 /**
359 * Pushes the top block from the parsing stack to the output list.
360 *
361 * @internal
362 * @since 5.0.0
363 * @param int|null $end_offset byte offset into document for where we should stop sending text output as HTML.
364 */
365 public function add_block_from_stack( $end_offset = null ) {
366 $stack_top = array_pop( $this->stack );
367 $prev_offset = $stack_top->prev_offset;
368
369 $html = isset( $end_offset )
370 ? substr( $this->document, $prev_offset, $end_offset - $prev_offset )
371 : substr( $this->document, $prev_offset );
372
373 if ( ! empty( $html ) ) {
374 $stack_top->block->innerHTML .= $html;
375 $stack_top->block->innerContent[] = $html;
376 }
377
378 if ( isset( $stack_top->leading_html_start ) ) {
379 $this->output[] = (array) $this->freeform(
380 substr(
381 $this->document,
382 $stack_top->leading_html_start,
383 $stack_top->token_start - $stack_top->leading_html_start
384 )
385 );
386 }
387
388 $this->output[] = (array) $stack_top->block;
389 }
390}
391
392/**
393 * WP_Block_Parser_Block class.
394 *
395 * Required for backward compatibility in WordPress Core.
396 */
397require_once __DIR__ . '/class-wp-block-parser-block.php';
398
399/**
400 * WP_Block_Parser_Frame class.
401 *
402 * Required for backward compatibility in WordPress Core.
403 */
404require_once __DIR__ . '/class-wp-block-parser-frame.php';
405