Element.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. /*
  2. * Copyright (c) 2018-2024, Andreas Kling <andreas@ladybird.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Optional.h>
  8. #include <LibWeb/ARIA/ARIAMixin.h>
  9. #include <LibWeb/ARIA/AttributeNames.h>
  10. #include <LibWeb/Animations/Animatable.h>
  11. #include <LibWeb/Bindings/ElementPrototype.h>
  12. #include <LibWeb/Bindings/Intrinsics.h>
  13. #include <LibWeb/Bindings/ShadowRootPrototype.h>
  14. #include <LibWeb/CSS/CascadedProperties.h>
  15. #include <LibWeb/CSS/ComputedProperties.h>
  16. #include <LibWeb/CSS/CountersSet.h>
  17. #include <LibWeb/CSS/Selector.h>
  18. #include <LibWeb/CSS/StyleInvalidation.h>
  19. #include <LibWeb/CSS/StyleProperty.h>
  20. #include <LibWeb/DOM/ChildNode.h>
  21. #include <LibWeb/DOM/NonDocumentTypeChildNode.h>
  22. #include <LibWeb/DOM/ParentNode.h>
  23. #include <LibWeb/DOM/QualifiedName.h>
  24. #include <LibWeb/DOM/Slottable.h>
  25. #include <LibWeb/HTML/AttributeNames.h>
  26. #include <LibWeb/HTML/EventLoop/Task.h>
  27. #include <LibWeb/HTML/LazyLoadingElement.h>
  28. #include <LibWeb/HTML/ScrollOptions.h>
  29. #include <LibWeb/HTML/TagNames.h>
  30. #include <LibWeb/IntersectionObserver/IntersectionObserver.h>
  31. #include <LibWeb/WebIDL/ExceptionOr.h>
  32. namespace Web::DOM {
  33. struct ShadowRootInit {
  34. Bindings::ShadowRootMode mode;
  35. bool delegates_focus = false;
  36. Bindings::SlotAssignmentMode slot_assignment { Bindings::SlotAssignmentMode::Named };
  37. bool clonable = false;
  38. bool serializable = false;
  39. };
  40. struct GetHTMLOptions {
  41. bool serializable_shadow_roots { false };
  42. Vector<GC::Root<ShadowRoot>> shadow_roots {};
  43. };
  44. // https://w3c.github.io/csswg-drafts/cssom-view-1/#dictdef-scrollintoviewoptions
  45. struct ScrollIntoViewOptions : public HTML::ScrollOptions {
  46. Bindings::ScrollLogicalPosition block { Bindings::ScrollLogicalPosition::Start };
  47. Bindings::ScrollLogicalPosition inline_ { Bindings::ScrollLogicalPosition::Nearest };
  48. };
  49. // https://drafts.csswg.org/cssom-view-1/#dictdef-checkvisibilityoptions
  50. struct CheckVisibilityOptions {
  51. bool check_opacity = false;
  52. bool check_visibility_css = false;
  53. bool content_visibility_auto = false;
  54. bool opacity_property = false;
  55. bool visibility_property = false;
  56. };
  57. // https://html.spec.whatwg.org/multipage/custom-elements.html#upgrade-reaction
  58. // An upgrade reaction, which will upgrade the custom element and contains a custom element definition; or
  59. struct CustomElementUpgradeReaction {
  60. GC::Root<HTML::CustomElementDefinition> custom_element_definition;
  61. };
  62. // https://html.spec.whatwg.org/multipage/custom-elements.html#callback-reaction
  63. // A callback reaction, which will call a lifecycle callback, and contains a callback function as well as a list of arguments.
  64. struct CustomElementCallbackReaction {
  65. GC::Root<WebIDL::CallbackType> callback;
  66. GC::MarkedVector<JS::Value> arguments;
  67. };
  68. // https://dom.spec.whatwg.org/#concept-element-custom-element-state
  69. // An element’s custom element state is one of "undefined", "failed", "uncustomized", "precustomized", or "custom".
  70. enum class CustomElementState {
  71. Undefined,
  72. Failed,
  73. Uncustomized,
  74. Precustomized,
  75. Custom,
  76. };
  77. class Element
  78. : public ParentNode
  79. , public ChildNode<Element>
  80. , public NonDocumentTypeChildNode<Element>
  81. , public SlottableMixin
  82. , public ARIA::ARIAMixin
  83. , public Animations::Animatable {
  84. WEB_PLATFORM_OBJECT(Element, ParentNode);
  85. public:
  86. virtual ~Element() override;
  87. FlyString const& qualified_name() const { return m_qualified_name.as_string(); }
  88. FlyString const& html_uppercased_qualified_name() const { return m_html_uppercased_qualified_name; }
  89. virtual FlyString node_name() const final { return html_uppercased_qualified_name(); }
  90. FlyString const& local_name() const { return m_qualified_name.local_name(); }
  91. // NOTE: This is for the JS bindings
  92. FlyString const& tag_name() const { return html_uppercased_qualified_name(); }
  93. Optional<FlyString> const& prefix() const { return m_qualified_name.prefix(); }
  94. void set_prefix(Optional<FlyString> value);
  95. Optional<String> locate_a_namespace_prefix(Optional<String> const& namespace_) const;
  96. // NOTE: This is for the JS bindings
  97. Optional<FlyString> const& namespace_uri() const { return m_qualified_name.namespace_(); }
  98. bool has_attribute(FlyString const& name) const;
  99. bool has_attribute_ns(Optional<FlyString> const& namespace_, FlyString const& name) const;
  100. bool has_attributes() const;
  101. Optional<String> attribute(FlyString const& name) const { return get_attribute(name); }
  102. Optional<String> get_attribute(FlyString const& name) const;
  103. Optional<String> get_attribute_ns(Optional<FlyString> const& namespace_, FlyString const& name) const;
  104. String get_attribute_value(FlyString const& local_name, Optional<FlyString> const& namespace_ = {}) const;
  105. Optional<String> lang() const;
  106. WebIDL::ExceptionOr<void> set_attribute(FlyString const& name, String const& value);
  107. WebIDL::ExceptionOr<void> set_attribute_ns(Optional<FlyString> const& namespace_, FlyString const& qualified_name, String const& value);
  108. void set_attribute_value(FlyString const& local_name, String const& value, Optional<FlyString> const& prefix = {}, Optional<FlyString> const& namespace_ = {});
  109. WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node(Attr&);
  110. WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node_ns(Attr&);
  111. void append_attribute(FlyString const& name, String const& value);
  112. void append_attribute(Attr&);
  113. void remove_attribute(FlyString const& name);
  114. void remove_attribute_ns(Optional<FlyString> const& namespace_, FlyString const& name);
  115. WebIDL::ExceptionOr<GC::Ref<Attr>> remove_attribute_node(GC::Ref<Attr>);
  116. WebIDL::ExceptionOr<bool> toggle_attribute(FlyString const& name, Optional<bool> force);
  117. size_t attribute_list_size() const;
  118. NamedNodeMap const* attributes() const { return m_attributes.ptr(); }
  119. Vector<String> get_attribute_names() const;
  120. GC::Ptr<Attr> get_attribute_node(FlyString const& name) const;
  121. GC::Ptr<Attr> get_attribute_node_ns(Optional<FlyString> const& namespace_, FlyString const& name) const;
  122. DOMTokenList* class_list();
  123. WebIDL::ExceptionOr<GC::Ref<ShadowRoot>> attach_shadow(ShadowRootInit init);
  124. WebIDL::ExceptionOr<void> attach_a_shadow_root(Bindings::ShadowRootMode mode, bool clonable, bool serializable, bool delegates_focus, Bindings::SlotAssignmentMode slot_assignment);
  125. GC::Ptr<ShadowRoot> shadow_root_for_bindings() const;
  126. WebIDL::ExceptionOr<bool> matches(StringView selectors) const;
  127. WebIDL::ExceptionOr<DOM::Element const*> closest(StringView selectors) const;
  128. int client_top() const;
  129. int client_left() const;
  130. int client_width() const;
  131. int client_height() const;
  132. [[nodiscard]] double current_css_zoom() const;
  133. void for_each_attribute(Function<void(Attr const&)>) const;
  134. void for_each_attribute(Function<void(FlyString const&, String const&)>) const;
  135. bool has_class(FlyString const&, CaseSensitivity = CaseSensitivity::CaseSensitive) const;
  136. Vector<FlyString> const& class_names() const { return m_classes; }
  137. // https://html.spec.whatwg.org/multipage/embedded-content-other.html#dimension-attributes
  138. virtual bool supports_dimension_attributes() const { return false; }
  139. virtual void apply_presentational_hints(GC::Ref<CSS::CascadedProperties>) const { }
  140. void run_attribute_change_steps(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_);
  141. CSS::RequiredInvalidationAfterStyleChange recompute_style();
  142. Optional<CSS::Selector::PseudoElement::Type> use_pseudo_element() const { return m_use_pseudo_element; }
  143. void set_use_pseudo_element(Optional<CSS::Selector::PseudoElement::Type> use_pseudo_element) { m_use_pseudo_element = move(use_pseudo_element); }
  144. GC::Ptr<Layout::NodeWithStyle> layout_node();
  145. GC::Ptr<Layout::NodeWithStyle const> layout_node() const;
  146. Optional<CSS::ComputedProperties>& computed_css_values() { return m_computed_css_values; }
  147. Optional<CSS::ComputedProperties> const& computed_css_values() const { return m_computed_css_values; }
  148. void set_computed_css_values(Optional<CSS::ComputedProperties>);
  149. CSS::ComputedProperties resolved_css_values(Optional<CSS::Selector::PseudoElement::Type> = {});
  150. [[nodiscard]] GC::Ptr<CSS::CascadedProperties> cascaded_properties(Optional<CSS::Selector::PseudoElement::Type>) const;
  151. void set_cascaded_properties(Optional<CSS::Selector::PseudoElement::Type>, GC::Ptr<CSS::CascadedProperties>);
  152. void set_pseudo_element_computed_css_values(CSS::Selector::PseudoElement::Type, Optional<CSS::ComputedProperties>);
  153. Optional<CSS::ComputedProperties&> pseudo_element_computed_css_values(CSS::Selector::PseudoElement::Type);
  154. void reset_animated_css_properties();
  155. GC::Ptr<CSS::ElementInlineCSSStyleDeclaration const> inline_style() const { return m_inline_style; }
  156. CSS::CSSStyleDeclaration* style_for_bindings();
  157. CSS::StyleSheetList& document_or_shadow_root_style_sheets();
  158. WebIDL::ExceptionOr<GC::Ref<DOM::DocumentFragment>> parse_fragment(StringView markup);
  159. WebIDL::ExceptionOr<String> inner_html() const;
  160. WebIDL::ExceptionOr<void> set_inner_html(StringView);
  161. WebIDL::ExceptionOr<void> set_html_unsafe(StringView);
  162. WebIDL::ExceptionOr<String> get_html(GetHTMLOptions const&) const;
  163. WebIDL::ExceptionOr<void> insert_adjacent_html(String const& position, String const&);
  164. WebIDL::ExceptionOr<String> outer_html() const;
  165. WebIDL::ExceptionOr<void> set_outer_html(String const&);
  166. bool is_focused() const;
  167. bool is_active() const;
  168. bool is_target() const;
  169. bool is_document_element() const;
  170. bool is_shadow_host() const;
  171. GC::Ptr<ShadowRoot> shadow_root() { return m_shadow_root; }
  172. GC::Ptr<ShadowRoot const> shadow_root() const { return m_shadow_root; }
  173. void set_shadow_root(GC::Ptr<ShadowRoot>);
  174. void set_custom_properties(Optional<CSS::Selector::PseudoElement::Type>, HashMap<FlyString, CSS::StyleProperty> custom_properties);
  175. [[nodiscard]] HashMap<FlyString, CSS::StyleProperty> const& custom_properties(Optional<CSS::Selector::PseudoElement::Type>) const;
  176. // NOTE: The function is wrapped in a GC::HeapFunction immediately.
  177. HTML::TaskID queue_an_element_task(HTML::Task::Source, Function<void()>);
  178. bool is_void_element() const;
  179. bool serializes_as_void() const;
  180. GC::Ref<Geometry::DOMRect> get_bounding_client_rect() const;
  181. GC::Ref<Geometry::DOMRectList> get_client_rects() const;
  182. virtual GC::Ptr<Layout::Node> create_layout_node(CSS::ComputedProperties);
  183. virtual void adjust_computed_style(CSS::ComputedProperties&) { }
  184. virtual void did_receive_focus() { }
  185. virtual void did_lose_focus() { }
  186. static GC::Ptr<Layout::NodeWithStyle> create_layout_node_for_display_type(DOM::Document&, CSS::Display const&, CSS::ComputedProperties, Element*);
  187. void set_pseudo_element_node(Badge<Layout::TreeBuilder>, CSS::Selector::PseudoElement::Type, GC::Ptr<Layout::NodeWithStyle>);
  188. GC::Ptr<Layout::NodeWithStyle> get_pseudo_element_node(CSS::Selector::PseudoElement::Type) const;
  189. bool has_pseudo_elements() const;
  190. void clear_pseudo_element_nodes(Badge<Layout::TreeBuilder>);
  191. void serialize_pseudo_elements_as_json(JsonArraySerializer<StringBuilder>& children_array) const;
  192. i32 tab_index() const;
  193. void set_tab_index(i32 tab_index);
  194. bool is_potentially_scrollable() const;
  195. double scroll_top() const;
  196. double scroll_left() const;
  197. void set_scroll_top(double y);
  198. void set_scroll_left(double x);
  199. int scroll_width() const;
  200. int scroll_height() const;
  201. bool is_actually_disabled() const;
  202. WebIDL::ExceptionOr<GC::Ptr<Element>> insert_adjacent_element(String const& where, GC::Ref<Element> element);
  203. WebIDL::ExceptionOr<void> insert_adjacent_text(String const& where, String const& data);
  204. // https://w3c.github.io/csswg-drafts/cssom-view-1/#dom-element-scrollintoview
  205. ErrorOr<void> scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> = {});
  206. // https://www.w3.org/TR/wai-aria-1.2/#ARIAMixin
  207. #define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \
  208. Optional<String> name() const override \
  209. { \
  210. return get_attribute(ARIA::AttributeNames::name); \
  211. } \
  212. \
  213. WebIDL::ExceptionOr<void> set_##name(Optional<String> const& value) override \
  214. { \
  215. if (value.has_value()) \
  216. TRY(set_attribute(ARIA::AttributeNames::name, *value)); \
  217. else \
  218. remove_attribute(ARIA::AttributeNames::name); \
  219. return {}; \
  220. }
  221. ENUMERATE_ARIA_ATTRIBUTES
  222. #undef __ENUMERATE_ARIA_ATTRIBUTE
  223. virtual bool exclude_from_accessibility_tree() const override;
  224. virtual bool include_in_accessibility_tree() const override;
  225. bool is_hidden() const;
  226. bool has_hidden_ancestor() const;
  227. bool is_referenced() const;
  228. bool has_referenced_and_hidden_ancestor() const;
  229. void enqueue_a_custom_element_upgrade_reaction(HTML::CustomElementDefinition& custom_element_definition);
  230. void enqueue_a_custom_element_callback_reaction(FlyString const& callback_name, GC::MarkedVector<JS::Value> arguments);
  231. using CustomElementReactionQueue = Vector<Variant<CustomElementUpgradeReaction, CustomElementCallbackReaction>>;
  232. CustomElementReactionQueue* custom_element_reaction_queue() { return m_custom_element_reaction_queue; }
  233. CustomElementReactionQueue const* custom_element_reaction_queue() const { return m_custom_element_reaction_queue; }
  234. CustomElementReactionQueue& ensure_custom_element_reaction_queue();
  235. JS::ThrowCompletionOr<void> upgrade_element(GC::Ref<HTML::CustomElementDefinition> custom_element_definition);
  236. void try_to_upgrade();
  237. bool is_defined() const;
  238. bool is_custom() const;
  239. Optional<String> const& is_value() const { return m_is_value; }
  240. void set_is_value(Optional<String> const& is) { m_is_value = is; }
  241. void set_custom_element_state(CustomElementState);
  242. void setup_custom_element_from_constructor(HTML::CustomElementDefinition& custom_element_definition, Optional<String> const& is_value);
  243. void scroll(HTML::ScrollToOptions);
  244. void scroll(double x, double y);
  245. void scroll_by(HTML::ScrollToOptions);
  246. void scroll_by(double x, double y);
  247. bool check_visibility(Optional<CheckVisibilityOptions>);
  248. void register_intersection_observer(Badge<IntersectionObserver::IntersectionObserver>, IntersectionObserver::IntersectionObserverRegistration);
  249. void unregister_intersection_observer(Badge<IntersectionObserver::IntersectionObserver>, GC::Ref<IntersectionObserver::IntersectionObserver>);
  250. IntersectionObserver::IntersectionObserverRegistration& get_intersection_observer_registration(Badge<DOM::Document>, IntersectionObserver::IntersectionObserver const&);
  251. enum class ScrollOffsetFor {
  252. Self,
  253. PseudoBefore,
  254. PseudoAfter
  255. };
  256. CSSPixelPoint scroll_offset(ScrollOffsetFor type) const { return m_scroll_offset[to_underlying(type)]; }
  257. void set_scroll_offset(ScrollOffsetFor type, CSSPixelPoint offset) { m_scroll_offset[to_underlying(type)] = offset; }
  258. enum class Dir {
  259. Ltr,
  260. Rtl,
  261. Auto,
  262. };
  263. Optional<Dir> dir() const { return m_dir; }
  264. enum class Directionality {
  265. Ltr,
  266. Rtl,
  267. };
  268. Directionality directionality() const;
  269. Optional<FlyString> const& id() const { return m_id; }
  270. Optional<FlyString> const& name() const { return m_name; }
  271. virtual GC::Ptr<GC::Function<void()>> take_lazy_load_resumption_steps(Badge<DOM::Document>)
  272. {
  273. return nullptr;
  274. }
  275. void set_in_top_layer(bool in_top_layer) { m_in_top_layer = in_top_layer; }
  276. bool in_top_layer() const { return m_in_top_layer; }
  277. bool has_non_empty_counters_set() const { return m_counters_set; }
  278. Optional<CSS::CountersSet const&> counters_set();
  279. CSS::CountersSet& ensure_counters_set();
  280. void resolve_counters(CSS::ComputedProperties&);
  281. void inherit_counters();
  282. protected:
  283. Element(Document&, DOM::QualifiedName);
  284. virtual void initialize(JS::Realm&) override;
  285. virtual void inserted() override;
  286. virtual void removed_from(Node*) override;
  287. virtual void children_changed() override;
  288. virtual i32 default_tab_index_value() const;
  289. // https://dom.spec.whatwg.org/#concept-element-attributes-change-ext
  290. virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_);
  291. virtual void computed_css_values_changed() { }
  292. virtual void visit_edges(Cell::Visitor&) override;
  293. virtual bool id_reference_exists(String const&) const override;
  294. CustomElementState custom_element_state() const { return m_custom_element_state; }
  295. private:
  296. void make_html_uppercased_qualified_name();
  297. void invalidate_style_after_attribute_change(FlyString const& attribute_name);
  298. WebIDL::ExceptionOr<GC::Ptr<Node>> insert_adjacent(StringView where, GC::Ref<Node> node);
  299. void enqueue_an_element_on_the_appropriate_element_queue();
  300. Optional<Directionality> auto_directionality() const;
  301. Optional<Directionality> contained_text_auto_directionality(bool can_exclude_root) const;
  302. Directionality parent_directionality() const;
  303. bool is_auto_directionality_form_associated_element() const;
  304. QualifiedName m_qualified_name;
  305. FlyString m_html_uppercased_qualified_name;
  306. GC::Ptr<NamedNodeMap> m_attributes;
  307. GC::Ptr<CSS::ElementInlineCSSStyleDeclaration> m_inline_style;
  308. GC::Ptr<DOMTokenList> m_class_list;
  309. GC::Ptr<ShadowRoot> m_shadow_root;
  310. GC::Ptr<CSS::CascadedProperties> m_cascaded_properties;
  311. Optional<CSS::ComputedProperties> m_computed_css_values;
  312. HashMap<FlyString, CSS::StyleProperty> m_custom_properties;
  313. struct PseudoElement {
  314. GC::Ptr<Layout::NodeWithStyle> layout_node;
  315. GC::Ptr<CSS::CascadedProperties> cascaded_properties;
  316. Optional<CSS::ComputedProperties> computed_css_values;
  317. HashMap<FlyString, CSS::StyleProperty> custom_properties;
  318. };
  319. // TODO: CSS::Selector::PseudoElement::Type includes a lot of pseudo-elements that exist in shadow trees,
  320. // and so we don't want to include data for them here.
  321. using PseudoElementData = Array<PseudoElement, to_underlying(CSS::Selector::PseudoElement::Type::KnownPseudoElementCount)>;
  322. mutable OwnPtr<PseudoElementData> m_pseudo_element_data;
  323. Optional<PseudoElement&> get_pseudo_element(CSS::Selector::PseudoElement::Type) const;
  324. PseudoElement& ensure_pseudo_element(CSS::Selector::PseudoElement::Type) const;
  325. Optional<CSS::Selector::PseudoElement::Type> m_use_pseudo_element;
  326. Vector<FlyString> m_classes;
  327. Optional<Dir> m_dir;
  328. Optional<FlyString> m_id;
  329. Optional<FlyString> m_name;
  330. // https://html.spec.whatwg.org/multipage/custom-elements.html#custom-element-reaction-queue
  331. // All elements have an associated custom element reaction queue, initially empty. Each item in the custom element reaction queue is of one of two types:
  332. // NOTE: See the structs at the top of this header.
  333. OwnPtr<CustomElementReactionQueue> m_custom_element_reaction_queue;
  334. // https://dom.spec.whatwg.org/#concept-element-custom-element-state
  335. CustomElementState m_custom_element_state { CustomElementState::Undefined };
  336. // https://dom.spec.whatwg.org/#concept-element-custom-element-definition
  337. GC::Ptr<HTML::CustomElementDefinition> m_custom_element_definition;
  338. // https://dom.spec.whatwg.org/#concept-element-is-value
  339. Optional<String> m_is_value;
  340. // https://www.w3.org/TR/intersection-observer/#dom-element-registeredintersectionobservers-slot
  341. // Element objects have an internal [[RegisteredIntersectionObservers]] slot, which is initialized to an empty list.
  342. OwnPtr<Vector<IntersectionObserver::IntersectionObserverRegistration>> m_registered_intersection_observers;
  343. Array<CSSPixelPoint, 3> m_scroll_offset;
  344. bool m_in_top_layer { false };
  345. OwnPtr<CSS::CountersSet> m_counters_set;
  346. };
  347. template<>
  348. inline bool Node::fast_is<Element>() const { return is_element(); }
  349. inline Element* Node::parent_element()
  350. {
  351. auto* parent = this->parent();
  352. if (!parent || !is<Element>(parent))
  353. return nullptr;
  354. return static_cast<Element*>(parent);
  355. }
  356. inline Element const* Node::parent_element() const
  357. {
  358. auto const* parent = this->parent();
  359. if (!parent || !is<Element>(parent))
  360. return nullptr;
  361. return static_cast<Element const*>(parent);
  362. }
  363. inline bool Element::has_class(FlyString const& class_name, CaseSensitivity case_sensitivity) const
  364. {
  365. if (case_sensitivity == CaseSensitivity::CaseSensitive) {
  366. return any_of(m_classes, [&](auto& it) {
  367. return it == class_name;
  368. });
  369. }
  370. return any_of(m_classes, [&](auto& it) {
  371. return it.equals_ignoring_ascii_case(class_name);
  372. });
  373. }
  374. WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm&, Optional<FlyString> namespace_, FlyString const& qualified_name);
  375. }