LibWeb: Add support for trees of pseudo-elements

This is needed for CSS view transitions.
This commit is contained in:
Psychpsyo 2025-03-25 18:13:18 +01:00 committed by Sam Atkins
commit 31301ef08b
Notes: github-actions[bot] 2025-05-13 11:39:50 +00:00
5 changed files with 88 additions and 25 deletions

View file

@ -527,15 +527,26 @@ private:
GC::Ptr<CSS::ComputedProperties> m_computed_properties;
HashMap<FlyString, CSS::StyleProperty> m_custom_properties;
struct PseudoElement {
struct PseudoElement : public JS::Cell {
GC_CELL(PseudoElement, JS::Cell);
GC_DECLARE_ALLOCATOR(PseudoElement);
GC::Ptr<Layout::NodeWithStyle> layout_node;
GC::Ptr<CSS::CascadedProperties> cascaded_properties;
GC::Ptr<CSS::ComputedProperties> computed_properties;
HashMap<FlyString, CSS::StyleProperty> custom_properties;
private:
virtual void visit_edges(JS::Cell::Visitor&) override;
};
// TODO: CSS::Selector::PseudoElement includes a lot of pseudo-elements that exist in shadow trees,
// and so we don't want to include data for them here.
using PseudoElementData = Array<PseudoElement, to_underlying(CSS::PseudoElement::KnownPseudoElementCount)>;
// https://drafts.csswg.org/css-view-transitions/#pseudo-element-tree
struct PseudoElementTreeNode
: public PseudoElement
, TreeNode<PseudoElementTreeNode> {
GC_CELL(PseudoElementTreeNode, PseudoElement);
GC_DECLARE_ALLOCATOR(PseudoElementTreeNode);
};
using PseudoElementData = HashMap<CSS::PseudoElement, GC::Ref<PseudoElement>>;
mutable OwnPtr<PseudoElementData> m_pseudo_element_data;
Optional<PseudoElement&> get_pseudo_element(CSS::PseudoElement) const;
PseudoElement& ensure_pseudo_element(CSS::PseudoElement) const;
@ -618,7 +629,10 @@ inline bool Element::has_pseudo_element(CSS::PseudoElement type) const
return false;
if (!CSS::Selector::PseudoElementSelector::is_known_pseudo_element_type(type))
return false;
return m_pseudo_element_data->at(to_underlying(type)).layout_node;
auto pseudo_element = m_pseudo_element_data->get(type);
if (!pseudo_element.has_value())
return false;
return pseudo_element.value()->layout_node;
}
WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm&, Optional<FlyString> namespace_, FlyString const& qualified_name);