Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 3.6k
HTML API: Complete missing tags in the IN BODY insertion mode.#6972
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
dmsnell
wants to merge
28
commits into
WordPress:trunk
from
dmsnell:html-api/finish-in-body-insertion-mode
Uh oh!
There was an error while loading. Please reload this page.
Closed
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
23eae92
HTML API: Complete missing tags in the IN BODY insertion mode.
dmsnell b509d04
Add return type annotations to new methods
sirreal 8eca544
Add argument type annotation to contains method
sirreal 0c8de62
Note behavioral change in BR tag.
dmsnell 2c68eb8
Remove handling for -BR which cannot appear.
dmsnell 0168314
Merge branch 'trunk' into html-api/finish-in-body-insertion-mode
dmsnell 4133ca1
Make up for where WPCS is deficient in understanding.
dmsnell 2da451b
Fix: use updated name for method.
dmsnell 9a9cdc6
Remove empty file.
dmsnell 9ab08ca
Update type annotations which crashed tests.
dmsnell c3b05a8
Fix test issue from merge conflict and un-skip test suites.
dmsnell 29d52fc
Move IN BODY text active format reconstruction after null-only text n…
dmsnell 5ad5cbc
Add clear-active-formatting-elements method from Jon's TABLE PR.
dmsnell d5976ad
Add missing rules in IN BODY
dmsnell 8d3b7b5
Refine get_modifiable_text() to handle null bytes.
dmsnell 2c0ec74
Fix modifiable text.
dmsnell 6aff057
Add new tests for modifiable text transforms.
dmsnell d7da469
Merge branch 'trunk' into html-api/finish-in-body-insertion-mode
dmsnell 0c9c40f
Clarify @since tag for open elements.
dmsnell 8c38159
Test idempotency of `get_modifiable_text()`.
dmsnell 1323448
Use declarative method of tracking ignored newline instead of imperat…
dmsnell 39febe3
Note limitation of newline behavior and add test which currently skips.
dmsnell 47f5303
Rename `compat_mode` to `document_mode`
dmsnell 5141d4c
Merge branch 'trunk' into html-api/finish-in-body-insertion-mode
dmsnell be1c65c
Linter
dmsnell 081fc5e
Update comments
dmsnell 3bcab2a
Update comments.
dmsnell 72d672c
Update comments.
dmsnell File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Jump to file
Failed to load files.
Loading
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
42 changes: 42 additions & 0 deletions
42 src/wp-includes/html-api/class-wp-html-active-formatting-elements.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
181 changes: 157 additions & 24 deletions
181 src/wp-includes/html-api/class-wp-html-open-elements.php
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -101,6 +101,49 @@ public function set_push_handler( Closure $handler ): void { | ||
| $this->push_handler = $handler; | ||
| } | ||
| /** | ||
| * Returns the name of the node at the nth position on the stack | ||
| * of open elements, or `null` if no such position exists. | ||
| * | ||
| * Note that this uses a 1-based index, which represents the | ||
| * "nth item" on the stack, counting from the top, where the | ||
| * top-most element is the 1st, the second is the 2nd, etc... | ||
| * | ||
| * @since 6.7.0 | ||
| * | ||
| * @param int $nth Retrieve the nth item on the stack, with 1 being | ||
| * the top element, 2 being the second, etc... | ||
| * @return string|null Name of the node on the stack at the given location, | ||
| * or `null` if the location isn't on the stack. | ||
| */ | ||
| public function at( int $nth ): ?string { | ||
| foreach ( $this->walk_down() as $item ) { | ||
| if ( 0 === --$nth ) { | ||
| return $item->node_name; | ||
| } | ||
| } | ||
| return null; | ||
| } | ||
| /** | ||
| * Reports if a node of a given name is in the stack of open elements. | ||
| * | ||
| * @since 6.7.0 | ||
| * | ||
| * @param string $node_name Name of node for which to check. | ||
| * @return bool Whether a node of the given name is in the stack of open elements. | ||
| */ | ||
| public function contains( string $node_name ): bool { | ||
| foreach ( $this->walk_up() as $item ) { | ||
| if ( $node_name === $item->node_name ) { | ||
| return true; | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
| /** | ||
| * Reports if a specific node is in the stack of open elements. | ||
| * | ||
| @@ -111,7 +154,7 @@ public function set_push_handler( Closure $handler ): void { | ||
| */ | ||
| public function contains_node( WP_HTML_Token $token ): bool { | ||
| foreach ( $this->walk_up() as $item ) { | ||
| if ( $token->bookmark_name === $item->bookmark_name ) { | ||
| if ( $token === $item ) { | ||
| return true; | ||
| } | ||
| } | ||
| @@ -210,11 +253,6 @@ public function has_element_in_specific_scope( string $tag_name, $termination_li | ||
| return true; | ||
| } | ||
| switch ( $node->node_name ) { | ||
| case 'HTML': | ||
| return false; | ||
| } | ||
| if ( in_array( $node->node_name, $termination_list, true ) ) { | ||
| return false; | ||
| } | ||
| @@ -226,7 +264,31 @@ public function has_element_in_specific_scope( string $tag_name, $termination_li | ||
| /** | ||
| * Returns whether a particular element is in scope. | ||
| * | ||
| * > The stack of open elements is said to have a particular element in | ||
| * > scope when it has that element in the specific scope consisting of | ||
| * > the following element types: | ||
| * > | ||
| * > - applet | ||
| * > - caption | ||
| * > - html | ||
| * > - table | ||
| * > - td | ||
| * > - th | ||
| * > - marquee | ||
| * > - object | ||
| * > - template | ||
| * > - MathML mi | ||
| * > - MathML mo | ||
| * > - MathML mn | ||
| * > - MathML ms | ||
| * > - MathML mtext | ||
| * > - MathML annotation-xml | ||
| * > - SVG foreignObject | ||
| * > - SVG desc | ||
| * > - SVG title | ||
| * | ||
| * @since 6.4.0 | ||
| * @since 6.7.0 Supports all required HTML elements. | ||
| * | ||
| * @see https://html.spec.whatwg.org/#has-an-element-in-scope | ||
| * | ||
| @@ -237,23 +299,34 @@ public function has_element_in_scope( string $tag_name ): bool { | ||
| return $this->has_element_in_specific_scope( | ||
| $tag_name, | ||
| array( | ||
| /* | ||
| * Because it's not currently possible to encounter | ||
| * one of the termination elements, they don't need | ||
| * to be listed here. If they were, they would be | ||
| * unreachable and only waste CPU cycles while | ||
| * scanning through HTML. | ||
| */ | ||
| 'APPLET', | ||
| 'CAPTION', | ||
| 'HTML', | ||
| 'TABLE', | ||
| 'TD', | ||
| 'TH', | ||
| 'MARQUEE', | ||
| 'OBJECT', | ||
| 'TEMPLATE', | ||
| // @todo: Support SVG and MathML nodes when support for foreign content is added. | ||
| ) | ||
| ); | ||
| } | ||
| /** | ||
| * Returns whether a particular element is in list item scope. | ||
| * | ||
| * > The stack of open elements is said to have a particular element | ||
| * > in list item scope when it has that element in the specific scope | ||
| * > consisting of the following element types: | ||
| * > | ||
| * > - All the element types listed above for the has an element in scope algorithm. | ||
| * > - ol in the HTML namespace | ||
| * > - ul in the HTML namespace | ||
| * | ||
| * @since 6.4.0 | ||
| * @since 6.5.0 Implemented: no longer throws on every invocation. | ||
| * @since 6.7.0 Supports all required HTML elements. | ||
| * | ||
| * @see https://html.spec.whatwg.org/#has-an-element-in-list-item-scope | ||
| * | ||
| @@ -264,43 +337,88 @@ public function has_element_in_list_item_scope( string $tag_name ): bool { | ||
| return $this->has_element_in_specific_scope( | ||
| $tag_name, | ||
| array( | ||
| // There are more elements that belong here which aren't currently supported. | ||
| 'APPLET', | ||
| 'BUTTON', | ||
| 'CAPTION', | ||
| 'HTML', | ||
| 'TABLE', | ||
| 'TD', | ||
| 'TH', | ||
| 'MARQUEE', | ||
| 'OBJECT', | ||
| 'OL', | ||
| 'TEMPLATE', | ||
| 'UL', | ||
| // @todo: Support SVG and MathML nodes when support for foreign content is added. | ||
| ) | ||
| ); | ||
| } | ||
| /** | ||
| * Returns whether a particular element is in button scope. | ||
| * | ||
| * > The stack of open elements is said to have a particular element | ||
| * > in button scope when it has that element in the specific scope | ||
| * > consisting of the following element types: | ||
| * > | ||
| * > - All the element types listed above for the has an element in scope algorithm. | ||
| * > - button in the HTML namespace | ||
| * | ||
| * @since 6.4.0 | ||
| * @since 6.7.0 Supports all required HTML elements. | ||
| * | ||
| * @see https://html.spec.whatwg.org/#has-an-element-in-button-scope | ||
| * | ||
| * @param string $tag_name Name of tag to check. | ||
| * @return bool Whether given element is in scope. | ||
| */ | ||
| public function has_element_in_button_scope( string $tag_name ): bool { | ||
| return $this->has_element_in_specific_scope( $tag_name, array( 'BUTTON' ) ); | ||
| return $this->has_element_in_specific_scope( | ||
| $tag_name, | ||
| array( | ||
| 'APPLET', | ||
| 'BUTTON', | ||
| 'CAPTION', | ||
| 'HTML', | ||
| 'TABLE', | ||
| 'TD', | ||
| 'TH', | ||
| 'MARQUEE', | ||
| 'OBJECT', | ||
| 'TEMPLATE', | ||
| // @todo: Support SVG and MathML nodes when support for foreign content is added. | ||
| ) | ||
| ); | ||
| } | ||
| /** | ||
| * Returns whether a particular element is in table scope. | ||
| * | ||
| * > The stack of open elements is said to have a particular element | ||
| * > in table scope when it has that element in the specific scope | ||
| * > consisting of the following element types: | ||
| * > | ||
| * > - html in the HTML namespace | ||
| * > - table in the HTML namespace | ||
| * > - template in the HTML namespace | ||
| * | ||
| * @since 6.4.0 | ||
| * @since 6.7.0 Full implementation. | ||
| * | ||
| * @see https://html.spec.whatwg.org/#has-an-element-in-table-scope | ||
| * | ||
| * @throws WP_HTML_Unsupported_Exception Always until this function is implemented. | ||
| * | ||
| * @param string $tag_name Name of tag to check. | ||
| * @return bool Whether given element is in scope. | ||
| */ | ||
| public function has_element_in_table_scope( string $tag_name ): bool { | ||
| throw new WP_HTML_Unsupported_Exception( 'Cannot process elements depending on table scope.' ); | ||
| return false; // The linter requires this unreachable code until the function is implemented and can return. | ||
| return $this->has_element_in_specific_scope( | ||
| $tag_name, | ||
| array( | ||
| 'HTML', | ||
| 'TABLE', | ||
| 'TEMPLATE', | ||
| ) | ||
| ); | ||
| } | ||
| /** | ||
| @@ -540,7 +658,16 @@ public function after_element_push( WP_HTML_Token $item ): void { | ||
| * cases where the precalculated value needs to change. | ||
| */ | ||
| switch ( $item->node_name ) { | ||
| case 'APPLET': | ||
| case 'BUTTON': | ||
| case 'CAPTION': | ||
| case 'HTML': | ||
| case 'TABLE': | ||
| case 'TD': | ||
| case 'TH': | ||
| case 'MARQUEE': | ||
| case 'OBJECT': | ||
| case 'TEMPLATE': | ||
| $this->has_p_in_button_scope = false; | ||
| break; | ||
| @@ -573,11 +700,17 @@ public function after_element_pop( WP_HTML_Token $item ): void { | ||
| * cases where the precalculated value needs to change. | ||
| */ | ||
| switch ( $item->node_name ) { | ||
dmsnell marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| case 'APPLET': | ||
| case 'BUTTON': | ||
| $this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' ); | ||
| break; | ||
| case 'CAPTION': | ||
| case 'HTML': | ||
| case 'P': | ||
| case 'TABLE': | ||
| case 'TD': | ||
| case 'TH': | ||
| case 'MARQUEE': | ||
| case 'OBJECT': | ||
| case 'TEMPLATE': | ||
| $this->has_p_in_button_scope = $this->has_element_in_button_scope( 'P' ); | ||
| break; | ||
| } | ||
Oops, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.