diff --git a/Userland/Libraries/LibWeb/Layout/Node.cpp b/Userland/Libraries/LibWeb/Layout/Node.cpp index b8f2b12382..4c7b7380ae 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.cpp +++ b/Userland/Libraries/LibWeb/Layout/Node.cpp @@ -915,6 +915,18 @@ DOM::Node* Node::dom_node() return m_dom_node.ptr(); } +DOM::Element const* Node::pseudo_element_generator() const +{ + VERIFY(m_generated_for != GeneratedFor::NotGenerated); + return m_pseudo_element_generator.ptr(); +} + +DOM::Element* Node::pseudo_element_generator() +{ + VERIFY(m_generated_for != GeneratedFor::NotGenerated); + return m_pseudo_element_generator.ptr(); +} + DOM::Document& Node::document() { return m_dom_node->document(); diff --git a/Userland/Libraries/LibWeb/Layout/Node.h b/Userland/Libraries/LibWeb/Layout/Node.h index e600e4f367..6003feb2f8 100644 --- a/Userland/Libraries/LibWeb/Layout/Node.h +++ b/Userland/Libraries/LibWeb/Layout/Node.h @@ -46,8 +46,22 @@ public: DOM::Node const* dom_node() const; DOM::Node* dom_node(); - bool is_generated() const { return m_generated; } - void set_generated(bool b) { m_generated = b; } + DOM::Element const* pseudo_element_generator() const; + DOM::Element* pseudo_element_generator(); + + enum class GeneratedFor { + NotGenerated, + PseudoBefore, + PseudoAfter + }; + bool is_generated() const { return m_generated_for != GeneratedFor::NotGenerated; } + bool is_generated_for_before_pseudo_element() const { return m_generated_for == GeneratedFor::PseudoBefore; } + bool is_generated_for_after_pseudo_element() const { return m_generated_for == GeneratedFor::PseudoAfter; } + void set_generated_for(GeneratedFor type, DOM::Element& element) + { + m_generated_for = type; + m_pseudo_element_generator = &element; + } Painting::Paintable* paintable() { return m_paintable; } Painting::Paintable const* paintable() const { return m_paintable; } @@ -169,6 +183,8 @@ private: JS::NonnullGCPtr m_browsing_context; + JS::GCPtr m_pseudo_element_generator; + bool m_anonymous { false }; bool m_has_style { false }; bool m_visible { true }; @@ -176,7 +192,7 @@ private: SelectionState m_selection_state { SelectionState::None }; bool m_is_flex_item { false }; - bool m_generated { false }; + GeneratedFor m_generated_for { GeneratedFor::NotGenerated }; }; class NodeWithStyle : public Node { diff --git a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp index dd6ec7a093..1590567534 100644 --- a/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp +++ b/Userland/Libraries/LibWeb/Layout/TreeBuilder.cpp @@ -189,12 +189,23 @@ ErrorOr TreeBuilder::create_pseudo_element_if_needed(DOM::Element& element if (!pseudo_element_node) return {}; - pseudo_element_node->set_generated(true); + auto generated_for = Node::GeneratedFor::NotGenerated; + if (pseudo_element == CSS::Selector::PseudoElement::Before) { + generated_for = Node::GeneratedFor::PseudoBefore; + } else if (pseudo_element == CSS::Selector::PseudoElement::After) { + generated_for = Node::GeneratedFor::PseudoAfter; + } else { + VERIFY_NOT_REACHED(); + } + + pseudo_element_node->set_generated_for(generated_for, element); + // FIXME: Handle images, and multiple values if (pseudo_element_content.type == CSS::ContentData::Type::String) { auto text = document.heap().allocate(document.realm(), document, pseudo_element_content.data.to_deprecated_string()).release_allocated_value_but_fixme_should_propagate_errors(); auto text_node = document.heap().allocate_without_realm(document, *text); - text_node->set_generated(true); + text_node->set_generated_for(generated_for, element); + push_parent(verify_cast(*pseudo_element_node)); insert_node_into_inline_or_block_ancestor(*text_node, text_node->display(), AppendOrPrepend::Append); pop_parent();