ShadowRoot.h 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. /*
  2. * Copyright (c) 2020, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <LibWeb/Bindings/ShadowRootPrototype.h>
  8. #include <LibWeb/DOM/DocumentFragment.h>
  9. #include <LibWeb/WebIDL/ObservableArray.h>
  10. namespace Web::DOM {
  11. class ShadowRoot final : public DocumentFragment {
  12. WEB_PLATFORM_OBJECT(ShadowRoot, DocumentFragment);
  13. JS_DECLARE_ALLOCATOR(ShadowRoot);
  14. public:
  15. Bindings::ShadowRootMode mode() const { return m_mode; }
  16. Bindings::SlotAssignmentMode slot_assignment() const { return m_slot_assignment; }
  17. void set_slot_assignment(Bindings::SlotAssignmentMode slot_assignment) { m_slot_assignment = slot_assignment; }
  18. bool delegates_focus() const { return m_delegates_focus; }
  19. void set_delegates_focus(bool delegates_focus) { m_delegates_focus = delegates_focus; }
  20. [[nodiscard]] bool declarative() const { return m_declarative; }
  21. void set_declarative(bool declarative) { m_declarative = declarative; }
  22. [[nodiscard]] bool clonable() const { return m_clonable; }
  23. void set_clonable(bool clonable) { m_clonable = clonable; }
  24. [[nodiscard]] bool serializable() const { return m_serializable; }
  25. void set_serializable(bool serializable) { m_serializable = serializable; }
  26. void set_onslotchange(WebIDL::CallbackType*);
  27. WebIDL::CallbackType* onslotchange();
  28. bool available_to_element_internals() const { return m_available_to_element_internals; }
  29. void set_available_to_element_internals(bool available_to_element_internals) { m_available_to_element_internals = available_to_element_internals; }
  30. // ^EventTarget
  31. virtual EventTarget* get_parent(Event const&) override;
  32. WebIDL::ExceptionOr<String> inner_html() const;
  33. WebIDL::ExceptionOr<void> set_inner_html(StringView);
  34. WebIDL::ExceptionOr<void> set_html_unsafe(StringView);
  35. WebIDL::ExceptionOr<String> get_html(GetHTMLOptions const&) const;
  36. CSS::StyleSheetList& style_sheets();
  37. CSS::StyleSheetList const& style_sheets() const;
  38. CSS::StyleSheetList* style_sheets_for_bindings() { return &style_sheets(); }
  39. JS::NonnullGCPtr<WebIDL::ObservableArray> adopted_style_sheets() const;
  40. WebIDL::ExceptionOr<void> set_adopted_style_sheets(JS::Value);
  41. void for_each_css_style_sheet(Function<void(CSS::CSSStyleSheet&)>&& callback) const;
  42. Vector<JS::NonnullGCPtr<Animations::Animation>> get_animations();
  43. virtual void finalize() override;
  44. protected:
  45. virtual void visit_edges(Cell::Visitor&) override;
  46. private:
  47. ShadowRoot(Document&, Element& host, Bindings::ShadowRootMode);
  48. virtual void initialize(JS::Realm&) override;
  49. // ^Node
  50. virtual FlyString node_name() const override { return "#shadow-root"_fly_string; }
  51. virtual bool is_shadow_root() const final { return true; }
  52. // NOTE: The specification doesn't seem to specify a default value for mode. Assuming closed for now.
  53. Bindings::ShadowRootMode m_mode { Bindings::ShadowRootMode::Closed };
  54. Bindings::SlotAssignmentMode m_slot_assignment { Bindings::SlotAssignmentMode::Named };
  55. bool m_delegates_focus { false };
  56. bool m_available_to_element_internals { false };
  57. // https://dom.spec.whatwg.org/#shadowroot-declarative
  58. bool m_declarative { false };
  59. // https://dom.spec.whatwg.org/#shadowroot-clonable
  60. bool m_clonable { false };
  61. // https://dom.spec.whatwg.org/#shadowroot-serializable
  62. bool m_serializable { false };
  63. JS::GCPtr<CSS::StyleSheetList> m_style_sheets;
  64. mutable JS::GCPtr<WebIDL::ObservableArray> m_adopted_style_sheets;
  65. };
  66. template<>
  67. inline bool Node::fast_is<ShadowRoot>() const { return node_type() == to_underlying(NodeType::DOCUMENT_FRAGMENT_NODE) && is_shadow_root(); }
  68. template<typename Callback>
  69. inline TraversalDecision Node::for_each_shadow_including_inclusive_descendant(Callback callback)
  70. {
  71. if (callback(*this) == TraversalDecision::Break)
  72. return TraversalDecision::Break;
  73. for (auto* child = first_child(); child; child = child->next_sibling()) {
  74. if (child->is_element()) {
  75. if (auto shadow_root = static_cast<Element*>(child)->shadow_root()) {
  76. if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
  77. return TraversalDecision::Break;
  78. }
  79. }
  80. if (child->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
  81. return TraversalDecision::Break;
  82. }
  83. return TraversalDecision::Continue;
  84. }
  85. template<typename Callback>
  86. inline TraversalDecision Node::for_each_shadow_including_descendant(Callback callback)
  87. {
  88. for (auto* child = first_child(); child; child = child->next_sibling()) {
  89. if (child->is_element()) {
  90. if (JS::GCPtr<ShadowRoot> shadow_root = static_cast<Element*>(child)->shadow_root()) {
  91. if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
  92. return TraversalDecision::Break;
  93. }
  94. }
  95. if (child->for_each_shadow_including_inclusive_descendant(callback) == TraversalDecision::Break)
  96. return TraversalDecision::Break;
  97. }
  98. return TraversalDecision::Continue;
  99. }
  100. }