/* * 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 namespace Web::DOM { class Element : public ParentNode , public ChildNode , public NonDocumentTypeChildNode { public: using WrapperType = Bindings::ElementWrapper; Element(Document&, 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); void remove_attribute(const FlyString& name); 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; 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); void 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); } const CSS::StyleProperties* specified_css_values() const { return m_specified_css_values.ptr(); } NonnullRefPtr computed_style(); 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; virtual bool is_focusable() const { return false; } 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); Optional resolve_custom_property(const String& custom_property_name) const { return m_custom_properties.get(custom_property_name); } void add_custom_property(const String& custom_property_name, CSS::StyleComputer::CustomPropertyResolutionTuple style_property) { m_custom_properties.set(custom_property_name, style_property); } 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; protected: RefPtr create_layout_node() override; 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_specified_css_values; HashMap m_custom_properties; RefPtr m_class_list; Vector m_classes; RefPtr m_shadow_root; }; template<> inline bool Node::fast_is() const { return is_element(); } }