LibWeb: Introduce the slottable concept for DOM elements and text nodes
A slottable is either a DOM element or a DOM text node. They may be assigned to slots (HTMLSlotElement) either automatically or manually. Automatic assignment occurs by matching a slot's `name` attribute to a slottable's `slot` attribute. Manual assignment occurs by using the slot's (not yet implemented) `assign` API. This commit does not perform the above assignments. It just sets up the slottable concept via IDL and hooks the slottable mixin into the element and text nodes.
This commit is contained in:
parent
b85a252753
commit
45b36bd08a
Notes:
sideshowbarker
2024-07-17 00:25:35 +09:00
Author: https://github.com/trflynn89 Commit: https://github.com/SerenityOS/serenity/commit/45b36bd08a Pull-request: https://github.com/SerenityOS/serenity/pull/20965 Reviewed-by: https://github.com/Lubrsi Reviewed-by: https://github.com/shannonbooth
12 changed files with 116 additions and 1 deletions
|
@ -175,6 +175,7 @@ set(SOURCES
|
|||
DOM/RadioNodeList.cpp
|
||||
DOM/Range.cpp
|
||||
DOM/ShadowRoot.cpp
|
||||
DOM/Slottable.cpp
|
||||
DOM/StaticNodeList.cpp
|
||||
DOM/StaticRange.cpp
|
||||
DOM/StyleElementUtils.cpp
|
||||
|
|
|
@ -86,6 +86,8 @@ void Element::initialize(JS::Realm& realm)
|
|||
void Element::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
SlottableMixin::visit_edges(visitor);
|
||||
|
||||
visitor.visit(m_attributes.ptr());
|
||||
visitor.visit(m_inline_style.ptr());
|
||||
visitor.visit(m_class_list.ptr());
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <LibWeb/DOM/NonDocumentTypeChildNode.h>
|
||||
#include <LibWeb/DOM/ParentNode.h>
|
||||
#include <LibWeb/DOM/QualifiedName.h>
|
||||
#include <LibWeb/DOM/Slottable.h>
|
||||
#include <LibWeb/HTML/AttributeNames.h>
|
||||
#include <LibWeb/HTML/EventLoop/Task.h>
|
||||
#include <LibWeb/HTML/ScrollOptions.h>
|
||||
|
@ -66,6 +67,7 @@ class Element
|
|||
: public ParentNode
|
||||
, public ChildNode<Element>
|
||||
, public NonDocumentTypeChildNode<Element>
|
||||
, public SlottableMixin
|
||||
, public ARIA::ARIAMixin {
|
||||
WEB_PLATFORM_OBJECT(Element, ParentNode);
|
||||
|
||||
|
|
|
@ -8,8 +8,10 @@
|
|||
#import <DOM/NodeList.idl>
|
||||
#import <DOM/ParentNode.idl>
|
||||
#import <DOM/ShadowRoot.idl>
|
||||
#import <DOM/Slottable.idl>
|
||||
#import <Geometry/DOMRect.idl>
|
||||
#import <Geometry/DOMRectList.idl>
|
||||
#import <HTML/HTMLSlotElement.idl>
|
||||
#import <HTML/Window.idl>
|
||||
|
||||
enum ScrollLogicalPosition { "start", "center", "end", "nearest" };
|
||||
|
@ -99,3 +101,4 @@ Element includes ChildNode;
|
|||
Element includes InnerHTML;
|
||||
// https://www.w3.org/TR/wai-aria-1.2/#idl_element
|
||||
Element includes ARIAMixin;
|
||||
Element includes Slottable;
|
||||
|
|
|
@ -930,6 +930,15 @@ Element* Node::parent_or_shadow_host_element()
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
Slottable Node::as_slottable()
|
||||
{
|
||||
VERIFY(is_slottable());
|
||||
|
||||
if (is_element())
|
||||
return JS::NonnullGCPtr { static_cast<Element&>(*this) };
|
||||
return JS::NonnullGCPtr { static_cast<Text&>(*this) };
|
||||
}
|
||||
|
||||
JS::NonnullGCPtr<NodeList> Node::child_nodes()
|
||||
{
|
||||
if (!m_child_nodes) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <AK/Vector.h>
|
||||
#include <LibWeb/DOM/AccessibilityTreeNode.h>
|
||||
#include <LibWeb/DOM/EventTarget.h>
|
||||
#include <LibWeb/DOM/Slottable.h>
|
||||
#include <LibWeb/DOMParsing/XMLSerializer.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
|
@ -266,6 +267,8 @@ public:
|
|||
template<typename Callback>
|
||||
IterationDecision for_each_shadow_including_descendant(Callback);
|
||||
|
||||
Slottable as_slottable();
|
||||
|
||||
Node* parent() { return m_parent.ptr(); }
|
||||
Node const* parent() const { return m_parent.ptr(); }
|
||||
|
||||
|
|
32
Userland/Libraries/LibWeb/DOM/Slottable.cpp
Normal file
32
Userland/Libraries/LibWeb/DOM/Slottable.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
#include <LibWeb/DOM/Element.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/DOM/ShadowRoot.h>
|
||||
#include <LibWeb/DOM/Slottable.h>
|
||||
#include <LibWeb/DOM/Text.h>
|
||||
#include <LibWeb/HTML/HTMLSlotElement.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
SlottableMixin::~SlottableMixin() = default;
|
||||
|
||||
void SlottableMixin::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
visitor.visit(m_assigned_slot);
|
||||
visitor.visit(m_manual_slot_assignment);
|
||||
}
|
||||
|
||||
// https://dom.spec.whatwg.org/#dom-slotable-assignedslot
|
||||
JS::GCPtr<HTML::HTMLSlotElement> SlottableMixin::assigned_slot()
|
||||
{
|
||||
// FIXME: The assignedSlot getter steps are to return the result of find a slot given this and with the open flag set.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
}
|
50
Userland/Libraries/LibWeb/DOM/Slottable.h
Normal file
50
Userland/Libraries/LibWeb/DOM/Slottable.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2023, Tim Flynn <trflynn89@serenityos.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibJS/Heap/Cell.h>
|
||||
#include <LibJS/Heap/GCPtr.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
// https://dom.spec.whatwg.org/#concept-slotable
|
||||
using Slottable = Variant<JS::NonnullGCPtr<Element>, JS::NonnullGCPtr<Text>>;
|
||||
|
||||
// https://dom.spec.whatwg.org/#mixin-slotable
|
||||
class SlottableMixin {
|
||||
public:
|
||||
virtual ~SlottableMixin();
|
||||
|
||||
String const& slottable_name() const { return m_name; } // Not called `name` to distinguish from `Element::name`.
|
||||
void set_slottable_name(String name) { m_name = move(name); }
|
||||
|
||||
JS::GCPtr<HTML::HTMLSlotElement> assigned_slot();
|
||||
|
||||
JS::GCPtr<HTML::HTMLSlotElement> assigned_slot_internal() const { return m_assigned_slot; }
|
||||
void set_assigned_slot(JS::GCPtr<HTML::HTMLSlotElement> assigned_slot) { m_assigned_slot = assigned_slot; }
|
||||
|
||||
JS::GCPtr<HTML::HTMLSlotElement> manual_slot_assignment() { return m_manual_slot_assignment; }
|
||||
void set_manual_slot_assignment(JS::GCPtr<HTML::HTMLSlotElement> manual_slot_assignment) { m_manual_slot_assignment = manual_slot_assignment; }
|
||||
|
||||
protected:
|
||||
void visit_edges(JS::Cell::Visitor&);
|
||||
|
||||
private:
|
||||
// https://dom.spec.whatwg.org/#slotable-name
|
||||
String m_name;
|
||||
|
||||
// https://dom.spec.whatwg.org/#slotable-assigned-slot
|
||||
JS::GCPtr<HTML::HTMLSlotElement> m_assigned_slot;
|
||||
|
||||
// https://dom.spec.whatwg.org/#slottable-manual-slot-assignment
|
||||
JS::GCPtr<HTML::HTMLSlotElement> m_manual_slot_assignment;
|
||||
};
|
||||
|
||||
}
|
4
Userland/Libraries/LibWeb/DOM/Slottable.idl
Normal file
4
Userland/Libraries/LibWeb/DOM/Slottable.idl
Normal file
|
@ -0,0 +1,4 @@
|
|||
// https://dom.spec.whatwg.org/#mixin-slotable
|
||||
interface mixin Slottable {
|
||||
readonly attribute HTMLSlotElement? assignedSlot;
|
||||
};
|
|
@ -32,6 +32,8 @@ void Text::initialize(JS::Realm& realm)
|
|||
void Text::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
SlottableMixin::visit_edges(visitor);
|
||||
|
||||
visitor.visit(dynamic_cast<JS::Cell*>(m_owner.ptr()));
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <AK/DeprecatedFlyString.h>
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <LibWeb/DOM/CharacterData.h>
|
||||
#include <LibWeb/DOM/Slottable.h>
|
||||
|
||||
namespace Web::DOM {
|
||||
|
||||
|
@ -19,7 +20,9 @@ public:
|
|||
virtual void did_edit_text_node(Badge<HTML::BrowsingContext>) = 0;
|
||||
};
|
||||
|
||||
class Text : public CharacterData {
|
||||
class Text
|
||||
: public CharacterData
|
||||
, public SlottableMixin {
|
||||
WEB_PLATFORM_OBJECT(Text, CharacterData);
|
||||
|
||||
public:
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
#import <DOM/CharacterData.idl>
|
||||
#import <DOM/Slottable.idl>
|
||||
#import <HTML/HTMLSlotElement.idl>
|
||||
|
||||
// https://dom.spec.whatwg.org/#text
|
||||
[Exposed=Window]
|
||||
|
@ -8,3 +10,5 @@ interface Text : CharacterData {
|
|||
[NewObject] Text splitText(unsigned long offset);
|
||||
|
||||
};
|
||||
|
||||
Text includes Slottable;
|
||||
|
|
Loading…
Add table
Reference in a new issue