Skip to content

Commit 0e3ada5

Browse files
committed
Play with an alternate matching syntax
1 parent 98180bc commit 0e3ada5

2 files changed

Lines changed: 134 additions & 7 deletions

File tree

src/wp-includes/html-api/class-wp-html-element-stack.php

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,6 @@ class WP_HTML_Element_Stack {
88
*/
99
public $stack = array();
1010

11-
public function __construct( $bookmark_name, $element, $flags ) {
12-
$this->bookmark_name = $bookmark_name;
13-
$this->element = $element;
14-
$this->flags = $flags;
15-
}
16-
1711
/**
1812
* Add an item to the top of the stack.
1913
*

src/wp-includes/html-api/class-wp-html-processor.php

Lines changed: 134 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,41 @@
11
<?php
22

3+
require_once __DIR__ . '/class-wp-html-element-stack.php';
4+
35
class WP_HTML_Processor extends WP_HTML_Tag_Processor {
46
const NOT_IMPLEMENTED_YET = false;
57

68
private $depth = 0;
79
private static $query = array( 'tag_closers' => 'visit' );
810
private $insertion_mode = 'in-body';
911

12+
/**
13+
* @var int Unique id for creating bookmarks.
14+
*/
15+
private $bookmark_id = 0;
16+
17+
/**
18+
* @var WP_HTML_Element_Stack Refers to element opening tags.
19+
*/
20+
private $tag_openers = null;
21+
22+
/**
23+
* @var WP_HTML_Element_Stack Referes to element closing tags.
24+
*/
25+
private $tag_closers = null;
26+
27+
/**
28+
* Create a new HTML Processor for reading and modifying HTML structure.
29+
*
30+
* @param string $html Input HTML document.
31+
*/
32+
public function __construct( $html ) {
33+
parent::__construct( $html );
34+
35+
$this->tag_openers = new WP_HTML_Element_Stack();
36+
$this->tag_closers = new WP_HTML_Element_Stack();
37+
}
38+
1039
/**
1140
* Advance the parser by one step.
1241
*
@@ -70,6 +99,110 @@ private function step_in_body() {
7099

71100
$tag_name = $this->get_tag();
72101
$tag_type = $this->is_tag_closer() ? 'closer' : 'opener';
102+
$op_sigil = $this->is_tag_closer() ? '-' : '+';
103+
$op = "{$op_sigil}{$tag_name}";
104+
105+
switch ( $op ) {
106+
/*
107+
* > A start tag whose tag name is "html"
108+
*/
109+
case '+HTML':
110+
goto ignored;
111+
112+
/*
113+
* > A start tag whose tag name is one of: "base", "basefont", "bgsound",
114+
* > "link", "meta", "noframes", "script", "style", "template", "title"
115+
*
116+
* > An end tag whose tag name is "template"
117+
*/
118+
case '+BASE':
119+
case '+BASEFONT':
120+
case '+BGSOUND':
121+
case '+LINK':
122+
case '+META':
123+
case '+NOFRAMES':
124+
case '+SCRIPT':
125+
case '+STYLE':
126+
case '+TEMPLATE':
127+
case '+TITLE':
128+
case '-TEMPLATE':
129+
parent::seek( 'current' );
130+
$this->insertion_mode = 'in-head';
131+
return $this->step();
132+
133+
/*
134+
* > A start tag whose tag name is "body"
135+
*/
136+
case '+BODY':
137+
goto ignored;
138+
139+
140+
/*
141+
* > A start tag whose tag name is "frameset"
142+
*/
143+
case '+FRAMESET':
144+
throw new Exception( self::NOT_IMPLEMENTED_YET );
145+
146+
/*
147+
* > An end tag whose tag name is "body"
148+
* > An end tag whose tag name is "html"
149+
*/
150+
case '-BODY':
151+
case '-HTML':
152+
/*
153+
* > If the stack of open elements does not have a body element in scope, this is a parse error; ignore the token.
154+
*
155+
* @TODO: We didn't construct an open HTML or BODY tag, but we have to make a choice here based on that.
156+
* Probably need to create these _or_ assume this will always transfer to "after body".
157+
*/
158+
$this->insertion_mode = 'after-body';
159+
return true;
160+
161+
/*
162+
* > A start tag whose tag name is one of: "address", "article", "aside", "blockquote", "center",
163+
* > "details", "dialog", "dir", "div", "dl", "fieldset", "figcaption", "figure", "footer",
164+
* > "header", "hgroup", "main", "menu", "nav", "ol", "p", "search", "section", "summary", "ul"
165+
*/
166+
case '+ADDRESS':
167+
case '+ARTICLE':
168+
case '+ASIDE':
169+
case '+BLOCKQUOTE':
170+
case '+CENTER':
171+
case '+DETAILS':
172+
case '+DIALOG':
173+
case '+DIR':
174+
case '+DIV':
175+
case '+DL':
176+
case '+FIELDSET':
177+
case '+FIGCAPTION':
178+
case '+FIGURE':
179+
case '+FOOTER':
180+
case '+HEADER':
181+
case '+HGROUP':
182+
case '+MAIN':
183+
case '+MENU':
184+
case '+NAV':
185+
case '+OL':
186+
case '+P':
187+
case '+SEARCH':
188+
case '+SECTION':
189+
case '+SUMMARY':
190+
case '+UL':
191+
if ( $this->has_in_scope( 'P', 'BUTTON' ) ) {
192+
$this->close_p_element();
193+
}
194+
195+
$this->enter_element( $tag_name );
196+
return;
197+
198+
/*
199+
* > An end-of-file token
200+
*
201+
* Stop parsing.
202+
*/
203+
default:
204+
return false;
205+
}
73206

74207
/*
75208
* > A start tag whose tag name is "html"
@@ -260,7 +393,7 @@ private function current_node() {
260393
* @return false
261394
*/
262395
private function has_in_scope( $element, $scope ) {
263-
return self::NOT_IMPLEMENTED_YET;
396+
throw new Exception( self::NOT_IMPLEMENTED_YET );
264397
}
265398

266399
public function next_tag( $query = null ) {

0 commit comments

Comments
 (0)