diff options
author | Simon Wanner <skyrising@pvpctutorials.de> | 2022-03-20 21:26:34 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-03-21 10:47:46 +0100 |
commit | e154c2c2cac482df9e390ab606fdd2049968fb69 (patch) | |
tree | 5aaa775cdb2ee93d19081ac8fd0e7fb280edaaa8 /Userland/Libraries/LibWeb/HTML/Parser | |
parent | 1d55437a768967aa04c40a30c7fe21cda62bb8b4 (diff) | |
download | serenity-e154c2c2cac482df9e390ab606fdd2049968fb69.zip |
LibWeb: Implement "has element in select scope" per-spec
The HTML Specification is quite tricky in this case.
Usually "have a particular element in <x> scope" mentions
"consisting of the following element types:", but in this case it's
"consisting of all element types except the following:"
Thanks to @AtkinsSJ for spotting this difference
Diffstat (limited to 'Userland/Libraries/LibWeb/HTML/Parser')
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp b/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp index 60367b9327..f71b35cdaf 100644 --- a/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp +++ b/Userland/Libraries/LibWeb/HTML/Parser/StackOfOpenElements.cpp @@ -68,9 +68,30 @@ bool StackOfOpenElements::has_in_list_item_scope(const FlyString& tag_name) cons return has_in_scope_impl(tag_name, list); } +// https://html.spec.whatwg.org/multipage/parsing.html#has-an-element-in-select-scope +// The stack of open elements is said to have a particular element in select scope +// when it has that element in the specific scope consisting of all element types except the following: +// - optgroup in the HTML namespace +// - option in the HTML namespace +// NOTE: In this case it's "all element types _except_" bool StackOfOpenElements::has_in_select_scope(const FlyString& tag_name) const { - return has_in_scope_impl(tag_name, { "option", "optgroup" }); + // https://html.spec.whatwg.org/multipage/parsing.html#has-an-element-in-the-specific-scope + for (ssize_t i = m_elements.size() - 1; i >= 0; --i) { + // 1. Initialize node to be the current node (the bottommost node of the stack). + auto& node = m_elements.at(i); + // 2. If node is the target node, terminate in a match state. + if (node.local_name() == tag_name) + return true; + // 3. Otherwise, if node is one of the element types in list, terminate in a failure state. + // NOTE: Here "list" refers to all elements except option and optgroup + if (node.local_name() != HTML::TagNames::option && node.local_name() != HTML::TagNames::optgroup) + return false; + // 4. Otherwise, set node to the previous entry in the stack of open elements and return to step 2. + } + // [4.] (This will never fail, since the loop will always terminate in the previous step if the top of the stack + // — an html element — is reached.) + VERIFY_NOT_REACHED(); } bool StackOfOpenElements::contains(const DOM::Element& element) const |