/* * Copyright (c) 2018-2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include namespace Web::HTML { // https://html.spec.whatwg.org/multipage/dom.html#attr-dir #define ENUMERATE_HTML_ELEMENT_DIR_ATTRIBUTES \ __ENUMERATE_HTML_ELEMENT_DIR_ATTRIBUTE(ltr) \ __ENUMERATE_HTML_ELEMENT_DIR_ATTRIBUTE(rtl) \ __ENUMERATE_HTML_ELEMENT_DIR_ATTRIBUTE(auto) // https://html.spec.whatwg.org/#attr-contenteditable enum class ContentEditableState { True, False, PlaintextOnly, Inherit, }; struct ShowPopoverOptions { GC::Ptr source; }; struct TogglePopoverOptions : public ShowPopoverOptions { Optional force {}; }; using TogglePopoverOptionsOrForceBoolean = Variant; enum class ThrowExceptions { Yes, No, }; enum class FocusPreviousElement { Yes, No, }; enum class FireEvents { Yes, No, }; enum class ExpectedToBeShowing { Yes, No, }; class HTMLElement : public DOM::Element , public HTML::GlobalEventHandlers , public HTML::HTMLOrSVGElement { WEB_PLATFORM_OBJECT(HTMLElement, DOM::Element); GC_DECLARE_ALLOCATOR(HTMLElement); public: virtual ~HTMLElement() override; Optional title() const { return attribute(HTML::AttributeNames::title); } StringView dir() const; void set_dir(String const&); virtual bool is_editable() const final; virtual bool is_focusable() const override; bool is_content_editable() const; StringView content_editable() const; ContentEditableState content_editable_state() const { return m_content_editable_state; } WebIDL::ExceptionOr set_content_editable(StringView); String inner_text(); void set_inner_text(StringView); [[nodiscard]] String outer_text(); WebIDL::ExceptionOr set_outer_text(String const&); int offset_top() const; int offset_left() const; int offset_width() const; int offset_height() const; GC::Ptr offset_parent() const; bool cannot_navigate() const; void click(); [[nodiscard]] String access_key_label() const; bool fire_a_synthetic_pointer_event(FlyString const& type, DOM::Element& target, bool not_trusted); // https://html.spec.whatwg.org/multipage/forms.html#category-label virtual bool is_labelable() const { return false; } GC::Ptr labels(); virtual Optional default_role() const override; String get_an_elements_target() const; TokenizedFeature::NoOpener get_an_elements_noopener(StringView target) const; WebIDL::ExceptionOr> attach_internals(); WebIDL::ExceptionOr set_popover(Optional value); Optional popover() const; enum class PopoverVisibilityState { Hidden, Showing, }; PopoverVisibilityState popover_visibility_state() const { return m_popover_visibility_state; } WebIDL::ExceptionOr show_popover_for_bindings(ShowPopoverOptions const& = {}); WebIDL::ExceptionOr hide_popover_for_bindings(); WebIDL::ExceptionOr toggle_popover(TogglePopoverOptionsOrForceBoolean const&); WebIDL::ExceptionOr show_popover(ThrowExceptions throw_exceptions, GC::Ptr invoker); WebIDL::ExceptionOr hide_popover(FocusPreviousElement focus_previous_element, FireEvents fire_events, ThrowExceptions throw_exceptions); WebIDL::ExceptionOr check_popover_validity(ExpectedToBeShowing expected_to_be_showing, ThrowExceptions throw_exceptions, GC::Ptr); protected: HTMLElement(DOM::Document&, DOM::QualifiedName); virtual void initialize(JS::Realm&) override; virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value, Optional const& namespace_) override; virtual WebIDL::ExceptionOr cloned(DOM::Node&, bool) override; virtual void inserted() override; virtual void visit_edges(Cell::Visitor&) override; private: virtual bool is_html_element() const final { return true; } virtual void adjust_computed_style(CSS::StyleProperties&) override; // ^HTML::GlobalEventHandlers virtual GC::Ptr global_event_handlers_to_event_target(FlyString const&) override { return *this; } virtual void did_receive_focus() override; virtual void did_lose_focus() override; [[nodiscard]] String get_the_text_steps(); GC::Ref rendered_text_fragment(StringView input); GC::Ptr m_labels; // https://html.spec.whatwg.org/multipage/custom-elements.html#attached-internals GC::Ptr m_attached_internals; // https://html.spec.whatwg.org/#attr-contenteditable ContentEditableState m_content_editable_state { ContentEditableState::Inherit }; // https://html.spec.whatwg.org/multipage/interaction.html#click-in-progress-flag bool m_click_in_progress { false }; // Popover API // https://html.spec.whatwg.org/multipage/popover.html#popover-visibility-state PopoverVisibilityState m_popover_visibility_state { PopoverVisibilityState::Hidden }; // https://html.spec.whatwg.org/multipage/popover.html#popover-invoker GC::Ptr m_popover_invoker; // https://html.spec.whatwg.org/multipage/popover.html#popover-showing-or-hiding bool m_popover_showing_or_hiding { false }; }; } namespace Web::DOM { template<> inline bool Node::fast_is() const { return is_html_element(); } }