From 7870f10aa88ce6c32a5e01ca9a0cbe6d217b304e Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Tue, 5 Sep 2023 14:49:30 -0400 Subject: [PATCH] LibWeb: Introduce the slot concept for HTML slot elements A slot is an HTMLSlotElement. It may have any number of slottable nodes assigned to it. --- Userland/Libraries/LibWeb/CMakeLists.txt | 1 + Userland/Libraries/LibWeb/DOM/Slot.cpp | 21 +++++++++++ Userland/Libraries/LibWeb/DOM/Slot.h | 36 +++++++++++++++++++ .../Libraries/LibWeb/HTML/HTMLSlotElement.cpp | 7 ++++ .../Libraries/LibWeb/HTML/HTMLSlotElement.h | 7 +++- 5 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 Userland/Libraries/LibWeb/DOM/Slot.cpp create mode 100644 Userland/Libraries/LibWeb/DOM/Slot.h diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index e4356918abe..abcb55d72b5 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -175,6 +175,7 @@ set(SOURCES DOM/RadioNodeList.cpp DOM/Range.cpp DOM/ShadowRoot.cpp + DOM/Slot.cpp DOM/Slottable.cpp DOM/StaticNodeList.cpp DOM/StaticRange.cpp diff --git a/Userland/Libraries/LibWeb/DOM/Slot.cpp b/Userland/Libraries/LibWeb/DOM/Slot.cpp new file mode 100644 index 00000000000..4acbda3f74f --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/Slot.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2023, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Web::DOM { + +Slot::~Slot() = default; + +void Slot::visit_edges(JS::Cell::Visitor& visitor) +{ + for (auto const& node : m_assigned_nodes) + node.visit([&](auto const& slottable) { visitor.visit(slottable); }); +} + +} diff --git a/Userland/Libraries/LibWeb/DOM/Slot.h b/Userland/Libraries/LibWeb/DOM/Slot.h new file mode 100644 index 00000000000..7d9a11d250b --- /dev/null +++ b/Userland/Libraries/LibWeb/DOM/Slot.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2023, Tim Flynn + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace Web::DOM { + +// https://dom.spec.whatwg.org/#concept-slot +class Slot { +public: + virtual ~Slot(); + + String const& slot_name() const { return m_name; } // Not called `name` to distinguish from `Element::name`. + void set_slot_name(String name) { m_name = move(name); } + + ReadonlySpan assigned_nodes_internal() const { return m_assigned_nodes; } + void set_assigned_nodes(Vector assigned_nodes) { m_assigned_nodes = move(assigned_nodes); } + +protected: + void visit_edges(JS::Cell::Visitor&); + +private: + // https://dom.spec.whatwg.org/#slot-name + String m_name; + + // https://dom.spec.whatwg.org/#slot-assigned-nodes + Vector m_assigned_nodes; +}; + +} diff --git a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp index 7a43cb4ee19..8891332c97d 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.cpp @@ -1,5 +1,6 @@ /* * Copyright (c) 2020, the SerenityOS developers. + * Copyright (c) 2023, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ @@ -22,4 +23,10 @@ void HTMLSlotElement::initialize(JS::Realm& realm) set_prototype(&Bindings::ensure_web_prototype(realm, "HTMLSlotElement")); } +void HTMLSlotElement::visit_edges(JS::Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + Slot::visit_edges(visitor); +} + } diff --git a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h index 9f7cc04950b..f0c0d22cc67 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h +++ b/Userland/Libraries/LibWeb/HTML/HTMLSlotElement.h @@ -1,16 +1,20 @@ /* * Copyright (c) 2020, the SerenityOS developers. + * Copyright (c) 2023, Tim Flynn * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once +#include #include namespace Web::HTML { -class HTMLSlotElement final : public HTMLElement { +class HTMLSlotElement final + : public HTMLElement + , public DOM::Slot { WEB_PLATFORM_OBJECT(HTMLSlotElement, HTMLElement); public: @@ -20,6 +24,7 @@ private: HTMLSlotElement(DOM::Document&, DOM::QualifiedName); virtual void initialize(JS::Realm&) override; + virtual void visit_edges(JS::Cell::Visitor&) override; }; }