ShadowRoot.h 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  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. namespace Web::DOM {
  10. class ShadowRoot final : public DocumentFragment {
  11. WEB_PLATFORM_OBJECT(ShadowRoot, DocumentFragment);
  12. public:
  13. Bindings::ShadowRootMode mode() const { return m_mode; }
  14. bool delegates_focus() const { return m_delegates_focus; }
  15. void set_delegates_focus(bool delegates_focus) { m_delegates_focus = delegates_focus; }
  16. bool available_to_element_internals() const { return m_available_to_element_internals; }
  17. void set_available_to_element_internals(bool available_to_element_internals) { m_available_to_element_internals = available_to_element_internals; }
  18. // ^EventTarget
  19. virtual EventTarget* get_parent(Event const&) override;
  20. WebIDL::ExceptionOr<DeprecatedString> inner_html() const;
  21. WebIDL::ExceptionOr<void> set_inner_html(DeprecatedString const&);
  22. private:
  23. ShadowRoot(Document&, Element& host, Bindings::ShadowRootMode);
  24. virtual JS::ThrowCompletionOr<void> initialize(JS::Realm&) override;
  25. // ^Node
  26. virtual DeprecatedFlyString node_name() const override { return "#shadow-root"; }
  27. virtual bool is_shadow_root() const final { return true; }
  28. // NOTE: The specification doesn't seem to specify a default value for closed. Assuming closed for now.
  29. Bindings::ShadowRootMode m_mode { Bindings::ShadowRootMode::Closed };
  30. bool m_delegates_focus { false };
  31. bool m_available_to_element_internals { false };
  32. };
  33. template<>
  34. inline bool Node::fast_is<ShadowRoot>() const { return is_shadow_root(); }
  35. template<typename Callback>
  36. inline IterationDecision Node::for_each_shadow_including_inclusive_descendant(Callback callback)
  37. {
  38. if (callback(*this) == IterationDecision::Break)
  39. return IterationDecision::Break;
  40. for (auto* child = first_child(); child; child = child->next_sibling()) {
  41. if (child->is_element()) {
  42. if (JS::GCPtr<ShadowRoot> shadow_root = static_cast<Element*>(child)->shadow_root_internal()) {
  43. if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
  44. return IterationDecision::Break;
  45. }
  46. }
  47. if (child->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
  48. return IterationDecision::Break;
  49. }
  50. return IterationDecision::Continue;
  51. }
  52. template<typename Callback>
  53. inline IterationDecision Node::for_each_shadow_including_descendant(Callback callback)
  54. {
  55. for (auto* child = first_child(); child; child = child->next_sibling()) {
  56. if (child->is_element()) {
  57. if (JS::GCPtr<ShadowRoot> shadow_root = static_cast<Element*>(child)->shadow_root()) {
  58. if (shadow_root->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
  59. return IterationDecision::Break;
  60. }
  61. }
  62. if (child->for_each_shadow_including_inclusive_descendant(callback) == IterationDecision::Break)
  63. return IterationDecision::Break;
  64. }
  65. return IterationDecision::Continue;
  66. }
  67. }