mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-31 13:19:05 +00:00
LibWeb: Implement selectedness algorithm
Implement selectedness setting algorithm in HTMLSelectElement
This commit is contained in:
parent
9cbb3fac12
commit
f4102b1dc9
Notes:
github-actions[bot]
2024-07-26 08:16:49 +00:00
Author: https://github.com/TSultanov
Commit: f4102b1dc9
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/832
Reviewed-by: https://github.com/AtkinsSJ ✅
4 changed files with 65 additions and 15 deletions
|
@ -57,11 +57,16 @@ void HTMLOptionElement::attribute_changed(FlyString const& name, Optional<String
|
||||||
void HTMLOptionElement::set_selected(bool selected)
|
void HTMLOptionElement::set_selected(bool selected)
|
||||||
{
|
{
|
||||||
// On setting, it must set the element's selectedness to the new value, set its dirtiness to true, and then cause the element to ask for a reset.
|
// On setting, it must set the element's selectedness to the new value, set its dirtiness to true, and then cause the element to ask for a reset.
|
||||||
m_selected = selected;
|
set_selected_internal(selected);
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
ask_for_a_reset();
|
ask_for_a_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HTMLOptionElement::set_selected_internal(bool selected)
|
||||||
|
{
|
||||||
|
m_selected = selected;
|
||||||
|
}
|
||||||
|
|
||||||
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-value
|
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-value
|
||||||
String HTMLOptionElement::value() const
|
String HTMLOptionElement::value() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,6 +20,7 @@ public:
|
||||||
|
|
||||||
bool selected() const { return m_selected; }
|
bool selected() const { return m_selected; }
|
||||||
void set_selected(bool);
|
void set_selected(bool);
|
||||||
|
void set_selected_internal(bool);
|
||||||
|
|
||||||
String value() const;
|
String value() const;
|
||||||
WebIDL::ExceptionOr<void> set_value(String const&);
|
WebIDL::ExceptionOr<void> set_value(String const&);
|
||||||
|
|
|
@ -135,12 +135,7 @@ WebIDL::ExceptionOr<void> HTMLSelectElement::add(HTMLOptionOrOptGroupElement ele
|
||||||
// Similarly, the add(element, before) method must act like its namesake method on that same options collection.
|
// Similarly, the add(element, before) method must act like its namesake method on that same options collection.
|
||||||
TRY(const_cast<HTMLOptionsCollection&>(*options()).add(move(element), move(before)));
|
TRY(const_cast<HTMLOptionsCollection&>(*options()).add(move(element), move(before)));
|
||||||
|
|
||||||
// If the inserted element is the first and only element, mark it as selected
|
update_selectedness(); // Not in spec
|
||||||
auto options = list_of_options();
|
|
||||||
if (options.size() == 1) {
|
|
||||||
options.at(0)->set_selected(true);
|
|
||||||
update_inner_text_element();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -481,14 +476,7 @@ void HTMLSelectElement::form_associated_element_was_inserted()
|
||||||
|
|
||||||
// Wait until children are ready
|
// Wait until children are ready
|
||||||
queue_an_element_task(HTML::Task::Source::Microtask, [this] {
|
queue_an_element_task(HTML::Task::Source::Microtask, [this] {
|
||||||
// Select first option when no other option is selected
|
update_selectedness();
|
||||||
if (selected_index() == -1) {
|
|
||||||
auto options = list_of_options();
|
|
||||||
if (options.size() > 0) {
|
|
||||||
options.at(0)->set_selected(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
update_inner_text_element();
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,4 +546,58 @@ void HTMLSelectElement::update_inner_text_element()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://html.spec.whatwg.org/multipage/form-elements.html#selectedness-setting-algorithm
|
||||||
|
void HTMLSelectElement::update_selectedness()
|
||||||
|
{
|
||||||
|
if (has_attribute(AttributeNames::multiple))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If element's multiple attribute is absent, and element's display size is 1,
|
||||||
|
if (size() == 1) {
|
||||||
|
bool has_selected_elements = false;
|
||||||
|
for (auto const& option_element : list_of_options()) {
|
||||||
|
if (option_element->selected()) {
|
||||||
|
has_selected_elements = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// and no option elements in the element's list of options have their selectedness set to true,
|
||||||
|
if (!has_selected_elements) {
|
||||||
|
// then set the selectedness of the first option element in the list of options in tree order
|
||||||
|
// that is not disabled, if any, to true, and return.
|
||||||
|
for (auto const& option_element : list_of_options()) {
|
||||||
|
if (!option_element->disabled()) {
|
||||||
|
option_element->set_selected_internal(true);
|
||||||
|
update_inner_text_element();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If element's multiple attribute is absent,
|
||||||
|
// and two or more option elements in element's list of options have their selectedness set to true,
|
||||||
|
// then set the selectedness of all but the last option element with its selectedness set to true
|
||||||
|
// in the list of options in tree order to false.
|
||||||
|
int number_of_selected = 0;
|
||||||
|
for (auto const& option_element : list_of_options()) {
|
||||||
|
if (option_element->selected())
|
||||||
|
++number_of_selected;
|
||||||
|
}
|
||||||
|
// and two or more option elements in element's list of options have their selectedness set to true,
|
||||||
|
if (number_of_selected >= 2) {
|
||||||
|
// then set the selectedness of all but the last option element with its selectedness set to true
|
||||||
|
// in the list of options in tree order to false.
|
||||||
|
for (auto const& option_element : list_of_options()) {
|
||||||
|
if (number_of_selected == 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
option_element->set_selected_internal(false);
|
||||||
|
--number_of_selected;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
update_inner_text_element();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -92,6 +92,8 @@ public:
|
||||||
|
|
||||||
void did_select_item(Optional<u32> const& id);
|
void did_select_item(Optional<u32> const& id);
|
||||||
|
|
||||||
|
void update_selectedness();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HTMLSelectElement(DOM::Document&, DOM::QualifiedName);
|
HTMLSelectElement(DOM::Document&, DOM::QualifiedName);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue