|
@@ -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();
|
|
|
+}
|
|
|
}
|