Skip to content
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

LibWeb: Implement relaxed parser for <select> #2770

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 0 additions & 10 deletions Libraries/LibWeb/HTML/HTMLOptGroupElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,4 @@ void HTMLOptGroupElement::inserted()
static_cast<HTMLSelectElement&>(*parent()).update_selectedness();
}

void HTMLOptGroupElement::removed_from(Node* old_parent)
{
Base::removed_from(old_parent);

// The optgroup HTML element removing steps, given removedNode and oldParent, are:
// 1. If oldParent is a select element and removedNode has an option child, then run oldParent's selectedness setting algorithm.
if (old_parent && is<HTMLSelectElement>(*old_parent) && first_child_of_type<HTMLOptionElement>())
static_cast<HTMLSelectElement&>(*old_parent).update_selectedness();
}

}
1 change: 0 additions & 1 deletion Libraries/LibWeb/HTML/HTMLOptGroupElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ class HTMLOptGroupElement final : public HTMLElement {
HTMLOptGroupElement(DOM::Document&, DOM::QualifiedName);

virtual void initialize(JS::Realm&) override;
virtual void removed_from(Node*) override;
virtual void inserted() override;
};

Expand Down
33 changes: 17 additions & 16 deletions Libraries/LibWeb/HTML/HTMLOptionElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,28 +205,29 @@ void HTMLOptionElement::inserted()

set_selected_internal(selected());

// 1. The option HTML element insertion steps, given insertedNode, are:
// If insertedNode's parent is a select element,
// or insertedNode's parent is an optgroup element whose parent is a select element,
// then run that select element's selectedness setting algorithm.
if (is<HTMLSelectElement>(*parent()))
static_cast<HTMLSelectElement&>(*parent()).update_selectedness();
else if (is<HTMLOptGroupElement>(parent()) && parent()->parent() && is<HTMLSelectElement>(*parent()->parent()))
static_cast<HTMLSelectElement&>(*parent()->parent()).update_selectedness();
// The option HTML element insertion steps, given insertedOption, are:
// 1. For each ancestor of insertedOption's ancestors in reverse tree order:
for (auto* ancestor = parent_node(); ancestor; ancestor = ancestor->parent_node()) {
// 1. If ancestor is a select element, then run the selectedness setting algorithm given ancestor and return.
if (is<HTMLSelectElement>(*ancestor)) {
static_cast<HTMLSelectElement&>(*ancestor).update_selectedness();
return;
}
}
}

void HTMLOptionElement::removed_from(Node* old_parent)
{
Base::removed_from(old_parent);

// The option HTML element removing steps, given removedNode and oldParent, are:
// 1. If oldParent is a select element, or oldParent is an optgroup element whose parent is a select element,
// then run that select element's selectedness setting algorithm.
if (old_parent) {
if (is<HTMLSelectElement>(*old_parent))
static_cast<HTMLSelectElement&>(*old_parent).update_selectedness();
else if (is<HTMLOptGroupElement>(*old_parent) && old_parent->parent_element() && is<HTMLSelectElement>(old_parent->parent_element()))
static_cast<HTMLSelectElement&>(*old_parent->parent_element()).update_selectedness();
// The option HTML element removing steps, given removedOption and oldParent, are:
// 1. For each ancestor of oldParent's inclusive ancestors in reverse tree order:
for (auto* ancestor = old_parent; ancestor; ancestor = ancestor->parent_node()) {
// 1. If ancestor is a select element, then run the selectedness setting algorithm given ancestor and return.
if (is<HTMLSelectElement>(*ancestor)) {
static_cast<HTMLSelectElement&>(*ancestor).update_selectedness();
return;
}
}
}

Expand Down
30 changes: 13 additions & 17 deletions Libraries/LibWeb/HTML/HTMLSelectElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,24 +199,20 @@ GC::Ref<DOM::HTMLCollection> HTMLSelectElement::selected_options()
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-select-option-list
Vector<GC::Root<HTMLOptionElement>> HTMLSelectElement::list_of_options() const
{
// The list of options for a select element consists of all the option element children of the select element,
// and all the option element children of all the optgroup element children of the select element, in tree order.
Vector<GC::Root<HTMLOptionElement>> list;

for_each_child_of_type<HTMLOptionElement>([&](HTMLOptionElement& option_element) {
list.append(GC::make_root(option_element));
return IterationDecision::Continue;
// 1. Let options be « ».
Vector<GC::Root<HTMLOptionElement>> options;
// 2. For each node of select's descendants in tree order except the descendants which are select elements and their subtrees:
for_each_in_subtree([&](auto& node) {
if (is<HTMLSelectElement>(node))
return TraversalDecision::Break;

// 1. If node is an option element, then append node to options.
if (is<HTMLOptionElement>(node))
options.append(GC::make_root(const_cast<HTMLOptionElement&>(static_cast<HTMLOptionElement const&>(node))));
return TraversalDecision::Continue;
});

for_each_child_of_type<HTMLOptGroupElement>([&](HTMLOptGroupElement const& optgroup_element) {
optgroup_element.for_each_child_of_type<HTMLOptionElement>([&](HTMLOptionElement& option_element) {
list.append(GC::make_root(option_element));
return IterationDecision::Continue;
});
return IterationDecision::Continue;
});

return list;
// 3. Return options.
return options;
}

// https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element:concept-form-reset-control
Expand Down
Loading
Loading