ladybird/Libraries/LibWeb/HTML/HTMLSelectElement.h
Glenn Skrzypczak 5c578b6057
Some checks are pending
CI / Lagom (x86_64, Fuzzers_CI, false, ubuntu-24.04, Linux, Clang) (push) Waiting to run
CI / Lagom (arm64, Sanitizer_CI, false, macos-15, macOS, Clang) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, false, ubuntu-24.04, Linux, GNU) (push) Waiting to run
CI / Lagom (x86_64, Sanitizer_CI, true, ubuntu-24.04, Linux, Clang) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (arm64, macos-15, macOS, macOS-universal2) (push) Waiting to run
Package the js repl as a binary artifact / build-and-package (x86_64, ubuntu-24.04, Linux, Linux-x86_64) (push) Waiting to run
Run test262 and test-wasm / run_and_update_results (push) Waiting to run
Lint Code / lint (push) Waiting to run
Label PRs with merge conflicts / auto-labeler (push) Waiting to run
Push notes / build (push) Waiting to run
LibWeb/HTML: Implement report_validity
This implements the previously stubbed out `report_validity` method.

The specification is not very clear on how to exactly report the
validity. For now, we bring the first visible invalid control into
view and focus it. In the future, however, it would make sense to
support more complex scenarios and be more aligned with the other
implementations.
2025-05-14 09:39:12 +12:00

156 lines
5.5 KiB
C++

/*
* Copyright (c) 2020, the SerenityOS developers.
* Copyright (c) 2021-2022, Andreas Kling <andreas@ladybird.org>
* Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
* Copyright (c) 2023, Bastiaan van der Plaat <bastiaan.v.d.plaat@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/HTML/AutocompleteElement.h>
#include <LibWeb/HTML/FormAssociatedElement.h>
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/HTML/HTMLOptionsCollection.h>
#include <LibWeb/HTML/SelectItem.h>
#include <LibWeb/WebIDL/Types.h>
namespace Web::HTML {
class HTMLSelectElement final
: public HTMLElement
, public FormAssociatedElement
, public AutocompleteElement {
WEB_PLATFORM_OBJECT(HTMLSelectElement, HTMLElement);
GC_DECLARE_ALLOCATOR(HTMLSelectElement);
FORM_ASSOCIATED_ELEMENT(HTMLElement, HTMLSelectElement);
AUTOCOMPLETE_ELEMENT(HTMLElement, HTMLSelectElement);
public:
virtual ~HTMLSelectElement() override;
virtual void adjust_computed_style(CSS::ComputedProperties&) override;
WebIDL::UnsignedLong size() const;
WebIDL::ExceptionOr<void> set_size(WebIDL::UnsignedLong);
GC::Ptr<HTMLOptionsCollection> const& options();
WebIDL::UnsignedLong length();
WebIDL::ExceptionOr<void> set_length(WebIDL::UnsignedLong);
HTMLOptionElement* item(WebIDL::UnsignedLong index);
HTMLOptionElement* named_item(FlyString const& name);
WebIDL::ExceptionOr<void> add(HTMLOptionOrOptGroupElement element, Optional<HTMLElementOrElementIndex> before = {});
void remove();
void remove(WebIDL::Long);
GC::Ref<DOM::HTMLCollection> selected_options();
GC::Ref<DOM::HTMLCollection> selected_options() const { return const_cast<HTMLSelectElement*>(this)->selected_options(); }
WebIDL::Long selected_index() const;
void set_selected_index(WebIDL::Long);
virtual String value() const override;
WebIDL::ExceptionOr<void> set_value(String const&);
bool is_open() const { return m_is_open; }
void set_is_open(bool);
WebIDL::ExceptionOr<void> show_picker();
Vector<GC::Root<HTMLOptionElement>> list_of_options() const;
bool will_validate();
bool check_validity();
bool report_validity();
// ^EventTarget
// https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute:the-select-element
// https://html.spec.whatwg.org/multipage/interaction.html#focusable-area
// https://html.spec.whatwg.org/multipage/semantics-other.html#concept-element-disabled
virtual bool is_focusable() const override;
// ^FormAssociatedElement
// https://html.spec.whatwg.org/multipage/forms.html#category-listed
virtual bool is_listed() const override { return true; }
// https://html.spec.whatwg.org/multipage/forms.html#category-submit
virtual bool is_submittable() const override { return true; }
// https://html.spec.whatwg.org/multipage/forms.html#category-reset
virtual bool is_resettable() const override { return true; }
// https://html.spec.whatwg.org/multipage/forms.html#category-autocapitalize
virtual bool is_auto_capitalize_inheriting() const override { return true; }
// ^HTMLElement
// https://html.spec.whatwg.org/multipage/forms.html#category-label
virtual bool is_labelable() const override { return true; }
virtual void reset_algorithm() override;
String const& type() const;
virtual Optional<ARIA::Role> default_role() const override;
virtual bool has_activation_behavior() const override;
virtual void activation_behavior(DOM::Event const&) override;
virtual void form_associated_element_was_inserted() override;
void did_select_item(Optional<u32> const& id);
void update_selectedness();
void update_inner_text_element(Badge<HTMLOptionElement>);
bool can_skip_selectedness_update_for_inserted_option(HTMLOptionElement const&) const;
bool user_validity() const { return m_user_validity; }
void set_user_validity(bool flag) { m_user_validity = flag; }
// https://html.spec.whatwg.org/multipage/form-elements.html#placeholder-label-option
HTMLOptionElement* placeholder_label_option() const;
// https://html.spec.whatwg.org/multipage/form-elements.html#the-select-element%3Asuffering-from-being-missing
virtual bool suffering_from_being_missing() const override;
private:
HTMLSelectElement(DOM::Document&, DOM::QualifiedName);
virtual void initialize(JS::Realm&) override;
virtual void visit_edges(Cell::Visitor&) override;
// ^DOM::Element
virtual i32 default_tab_index_value() const override;
virtual void computed_properties_changed() override;
virtual void children_changed(ChildrenChangedMetadata const*) override;
bool can_skip_children_changed_selectedness_update(ChildrenChangedMetadata const& metadata) const;
void update_cached_list_of_options() const;
void show_the_picker_if_applicable();
void create_shadow_tree_if_needed();
void update_inner_text_element();
void queue_input_and_change_events();
u32 display_size() const;
mutable Vector<GC::Ref<HTMLOptionElement>> m_cached_list_of_options;
mutable size_t m_cached_number_of_selected_options { 0 };
GC::Ptr<HTMLOptionsCollection> m_options;
GC::Ptr<DOM::HTMLCollection> m_selected_options;
bool m_is_open { false };
Vector<SelectItem> m_select_items;
GC::Ptr<DOM::Element> m_inner_text_element;
GC::Ptr<DOM::Element> m_chevron_icon_element;
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#user-validity
bool m_user_validity { false };
};
}