Skip to content

Commit 163c3fd

Browse files
committed
HTML API: Report real and virtual nodes in the HTML Processor.
HTML is a kind of short-hand for a DOM structure. This means that there are many cases in HTML where an element's opening tag or closing tag is missing (or both). This is because many of the parsing rules imply creating elements in the DOM which may not exist in the text of the HTML. The HTML Processor, being the higher-level counterpart to the Tag Processor, is already aware of these nodes, but since it's inception has not paused on them when scanning through a document. Instead, these are visible when pausing on a child of such an element, but otherwise not seen. In this patch the HTML Processor starts exposing those implicitly-created nodes, including opening tags, and closing tags, that aren't foudn in the text content of the HTML input document. Previously, the sequence of matched tokens when scanning with `WP_HTML_Processor::next_token()` would depend on how the HTML document was written, but with this patch, all semantically equal HTML documents will parse and scan in the same exact manner, presenting an idealized or "perfect" view of the document the same way as would occur when traversing a DOM in a browser. Developed in #6348 Discussed in https://core.trac.wordpress.org/ticket/61348 Props audrasjb, dmsnell, gziolo, jonsurrell. Fixes #61348. git-svn-id: https://develop.svn.wordpress.org/trunk@58304 602fd350-edb4-49c9-b593-d223f7449a82
1 parent 06914f5 commit 163c3fd

6 files changed

Lines changed: 481 additions & 42 deletions

File tree

src/wp-includes/html-api/class-wp-html-open-elements.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,56 @@ class WP_HTML_Open_Elements {
5151
*/
5252
private $has_p_in_button_scope = false;
5353

54+
/**
55+
* A function that will be called when an item is popped off the stack of open elements.
56+
*
57+
* The function will be called with the popped item as its argument.
58+
*
59+
* @since 6.6.0
60+
*
61+
* @var Closure
62+
*/
63+
private $pop_handler = null;
64+
65+
/**
66+
* A function that will be called when an item is pushed onto the stack of open elements.
67+
*
68+
* The function will be called with the pushed item as its argument.
69+
*
70+
* @since 6.6.0
71+
*
72+
* @var Closure
73+
*/
74+
private $push_handler = null;
75+
76+
/**
77+
* Sets a pop handler that will be called when an item is popped off the stack of
78+
* open elements.
79+
*
80+
* The function will be called with the pushed item as its argument.
81+
*
82+
* @since 6.6.0
83+
*
84+
* @param Closure $handler The handler function.
85+
*/
86+
public function set_pop_handler( Closure $handler ) {
87+
$this->pop_handler = $handler;
88+
}
89+
90+
/**
91+
* Sets a push handler that will be called when an item is pushed onto the stack of
92+
* open elements.
93+
*
94+
* The function will be called with the pushed item as its argument.
95+
*
96+
* @since 6.6.0
97+
*
98+
* @param Closure $handler The handler function.
99+
*/
100+
public function set_push_handler( Closure $handler ) {
101+
$this->push_handler = $handler;
102+
}
103+
54104
/**
55105
* Reports if a specific node is in the stack of open elements.
56106
*
@@ -429,6 +479,10 @@ public function after_element_push( $item ) {
429479
$this->has_p_in_button_scope = true;
430480
break;
431481
}
482+
483+
if ( null !== $this->push_handler ) {
484+
( $this->push_handler )( $item );
485+
}
432486
}
433487

434488
/**
@@ -458,5 +512,9 @@ public function after_element_pop( $item ) {
458512
$this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' );
459513
break;
460514
}
515+
516+
if ( null !== $this->pop_handler ) {
517+
( $this->pop_handler )( $item );
518+
}
461519
}
462520
}

0 commit comments

Comments
 (0)