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