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: https://github.com/LadybirdBrowser/ladybird/commit/f4102b1dc99 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/832 Reviewed-by: https://github.com/AtkinsSJ ✅
4 changed files with 65 additions and 15 deletions
Userland/Libraries/LibWeb/HTML
|
@ -57,11 +57,16 @@ void HTMLOptionElement::attribute_changed(FlyString const& name, Optional<String
|
|||
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.
|
||||
m_selected = selected;
|
||||
set_selected_internal(selected);
|
||||
m_dirty = true;
|
||||
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
|
||||
String HTMLOptionElement::value() const
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ public:
|
|||
|
||||
bool selected() const { return m_selected; }
|
||||
void set_selected(bool);
|
||||
void set_selected_internal(bool);
|
||||
|
||||
String value() 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.
|
||||
TRY(const_cast<HTMLOptionsCollection&>(*options()).add(move(element), move(before)));
|
||||
|
||||
// If the inserted element is the first and only element, mark it as selected
|
||||
auto options = list_of_options();
|
||||
if (options.size() == 1) {
|
||||
options.at(0)->set_selected(true);
|
||||
update_inner_text_element();
|
||||
}
|
||||
update_selectedness(); // Not in spec
|
||||
|
||||
return {};
|
||||
}
|
||||
|
@ -481,14 +476,7 @@ void HTMLSelectElement::form_associated_element_was_inserted()
|
|||
|
||||
// Wait until children are ready
|
||||
queue_an_element_task(HTML::Task::Source::Microtask, [this] {
|
||||
// Select first option when no other option is selected
|
||||
if (selected_index() == -1) {
|
||||
auto options = list_of_options();
|
||||
if (options.size() > 0) {
|
||||
options.at(0)->set_selected(true);
|
||||
}
|
||||
}
|
||||
update_inner_text_element();
|
||||
update_selectedness();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -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 update_selectedness();
|
||||
|
||||
private:
|
||||
HTMLSelectElement(DOM::Document&, DOM::QualifiedName);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue