/* * Copyright (c) 2018-2021, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace Web::DOM { class Element : public ParentNode , public ChildNode , public NonDocumentTypeChildNode { public: using WrapperType = Bindings::ElementWrapper; Element(Document&, DOM::QualifiedName); virtual ~Element() override; const String& qualified_name() const { return m_qualified_name.as_string(); } const String& html_uppercased_qualified_name() const { return m_html_uppercased_qualified_name; } virtual FlyString node_name() const final { return html_uppercased_qualified_name(); } const FlyString& local_name() const { return m_qualified_name.local_name(); } // NOTE: This is for the JS bindings const String& tag_name() const { return html_uppercased_qualified_name(); } const FlyString& prefix() const { return m_qualified_name.prefix(); } const FlyString& namespace_() const { return m_qualified_name.namespace_(); } // NOTE: This is for the JS bindings const FlyString& namespace_uri() const { return namespace_(); } bool has_attribute(const FlyString& name) const; bool has_attributes() const { return !m_attributes->is_empty(); } String attribute(const FlyString& name) const { return get_attribute(name); } String get_attribute(const FlyString& name) const; ExceptionOr set_attribute(const FlyString& name, const String& value); ExceptionOr set_attribute_ns(FlyString const& namespace_, FlyString const& qualified_name, String const& value); void remove_attribute(const FlyString& name); DOM::ExceptionOr toggle_attribute(FlyString const& name, Optional force); size_t attribute_list_size() const { return m_attributes->length(); } NonnullRefPtr const& attributes() const { return m_attributes; } Vector get_attribute_names() const; RefPtr const& class_list(); DOM::ExceptionOr matches(StringView selectors) const; DOM::ExceptionOr closest(StringView selectors) const; int client_top() const; int client_left() const; int client_width() const; int client_height() const; template void for_each_attribute(Callback callback) const { for (size_t i = 0; i < m_attributes->length(); ++i) { auto const* attribute = m_attributes->item(i); callback(attribute->name(), attribute->value()); } } bool has_class(const FlyString&, CaseSensitivity = CaseSensitivity::CaseSensitive) const; const Vector& class_names() const { return m_classes; } virtual void apply_presentational_hints(CSS::StyleProperties&) const { } virtual void parse_attribute(const FlyString& name, const String& value); virtual void did_remove_attribute(FlyString const&); enum class NeedsRelayout { No = 0, Yes = 1, }; NeedsRelayout recompute_style(); Layout::NodeWithStyle* layout_node() { return static_cast(Node::layout_node()); } const Layout::NodeWithStyle* layout_node() const { return static_cast(Node::layout_node()); } String name() const { return attribute(HTML::AttributeNames::name); } CSS::StyleProperties const* computed_css_values() const { return m_computed_css_values.ptr(); } void set_computed_css_values(RefPtr style) { m_computed_css_values = move(style); } NonnullRefPtr resolved_css_values(); const CSS::CSSStyleDeclaration* inline_style() const { return m_inline_style; } NonnullRefPtr style_for_bindings(); String inner_html() const; ExceptionOr set_inner_html(String const&); bool is_focused() const; bool is_active() const; NonnullRefPtr get_elements_by_class_name(FlyString const&); ShadowRoot* shadow_root() { return m_shadow_root; } const ShadowRoot* shadow_root() const { return m_shadow_root; } void set_shadow_root(RefPtr); void set_custom_properties(HashMap custom_properties) { m_custom_properties = move(custom_properties); } HashMap const& custom_properties() const { return m_custom_properties; } void queue_an_element_task(HTML::Task::Source, Function); bool is_void_element() const; bool serializes_as_void() const; NonnullRefPtr get_bounding_client_rect() const; NonnullRefPtr get_client_rects() const; virtual RefPtr create_layout_node(NonnullRefPtr); virtual void did_receive_focus() { } virtual void did_lose_focus() { } static RefPtr create_layout_node_for_display_type(DOM::Document&, CSS::Display const&, NonnullRefPtr, Element*); void set_pseudo_element_node(Badge, CSS::Selector::PseudoElement, RefPtr); RefPtr get_pseudo_element_node(CSS::Selector::PseudoElement) const; void clear_pseudo_element_nodes(Badge); void serialize_pseudo_elements_as_json(JsonArraySerializer& children_array) const; protected: virtual void children_changed() override; private: void make_html_uppercased_qualified_name(); QualifiedName m_qualified_name; String m_html_uppercased_qualified_name; NonnullRefPtr m_attributes; RefPtr m_inline_style; RefPtr m_computed_css_values; HashMap m_custom_properties; RefPtr m_class_list; Vector m_classes; RefPtr m_shadow_root; Array, CSS::Selector::PseudoElementCount> m_pseudo_element_nodes; }; template<> inline bool Node::fast_is() const { return is_element(); } ExceptionOr validate_and_extract(FlyString namespace_, FlyString qualified_name); }