mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 18:57:45 +00:00
LibWeb: Make pseudo-elements inspectable
This makes it possible to set a pseudo-element as the inspected node using Document::set_inspected_node(), Document then provides inspected_layout_node() for the painting related functions.
This commit is contained in:
parent
5e3e9b2f61
commit
ee7282cbe4
6 changed files with 28 additions and 15 deletions
|
@ -985,18 +985,29 @@ Layout::Viewport* Document::layout_node()
|
||||||
return static_cast<Layout::Viewport*>(Node::layout_node());
|
return static_cast<Layout::Viewport*>(Node::layout_node());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Document::set_inspected_node(Node* node)
|
void Document::set_inspected_node(Node* node, Optional<CSS::Selector::PseudoElement> pseudo_element)
|
||||||
{
|
{
|
||||||
if (m_inspected_node.ptr() == node)
|
if (m_inspected_node.ptr() == node && m_inspected_pseudo_element == pseudo_element)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_inspected_node && m_inspected_node->layout_node())
|
if (auto layout_node = inspected_layout_node())
|
||||||
m_inspected_node->layout_node()->set_needs_display();
|
layout_node->set_needs_display();
|
||||||
|
|
||||||
m_inspected_node = node;
|
m_inspected_node = node;
|
||||||
|
m_inspected_pseudo_element = pseudo_element;
|
||||||
|
|
||||||
if (m_inspected_node && m_inspected_node->layout_node())
|
if (auto layout_node = inspected_layout_node())
|
||||||
m_inspected_node->layout_node()->set_needs_display();
|
layout_node->set_needs_display();
|
||||||
|
}
|
||||||
|
|
||||||
|
Layout::Node* Document::inspected_layout_node()
|
||||||
|
{
|
||||||
|
if (!m_inspected_node)
|
||||||
|
return nullptr;
|
||||||
|
if (!m_inspected_pseudo_element.has_value() || !m_inspected_node->is_element())
|
||||||
|
return m_inspected_node->layout_node();
|
||||||
|
auto& element = static_cast<Element&>(*m_inspected_node);
|
||||||
|
return element.get_pseudo_element_node(m_inspected_pseudo_element.value());
|
||||||
}
|
}
|
||||||
|
|
||||||
static Node* find_common_ancestor(Node* a, Node* b)
|
static Node* find_common_ancestor(Node* a, Node* b)
|
||||||
|
|
|
@ -136,9 +136,11 @@ public:
|
||||||
Node* hovered_node() { return m_hovered_node.ptr(); }
|
Node* hovered_node() { return m_hovered_node.ptr(); }
|
||||||
Node const* hovered_node() const { return m_hovered_node.ptr(); }
|
Node const* hovered_node() const { return m_hovered_node.ptr(); }
|
||||||
|
|
||||||
void set_inspected_node(Node*);
|
void set_inspected_node(Node*, Optional<CSS::Selector::PseudoElement>);
|
||||||
Node* inspected_node() { return m_inspected_node.ptr(); }
|
Node* inspected_node() { return m_inspected_node.ptr(); }
|
||||||
Node const* inspected_node() const { return m_inspected_node.ptr(); }
|
Node const* inspected_node() const { return m_inspected_node.ptr(); }
|
||||||
|
Layout::Node* inspected_layout_node();
|
||||||
|
Layout::Node const* inspected_layout_node() const { return const_cast<Document*>(this)->inspected_layout_node(); }
|
||||||
|
|
||||||
Element* document_element();
|
Element* document_element();
|
||||||
Element const* document_element() const;
|
Element const* document_element() const;
|
||||||
|
@ -494,6 +496,7 @@ private:
|
||||||
JS::GCPtr<CSS::StyleSheetList> m_style_sheets;
|
JS::GCPtr<CSS::StyleSheetList> m_style_sheets;
|
||||||
JS::GCPtr<Node> m_hovered_node;
|
JS::GCPtr<Node> m_hovered_node;
|
||||||
JS::GCPtr<Node> m_inspected_node;
|
JS::GCPtr<Node> m_inspected_node;
|
||||||
|
Optional<CSS::Selector::PseudoElement> m_inspected_pseudo_element;
|
||||||
JS::GCPtr<Node> m_active_favicon;
|
JS::GCPtr<Node> m_active_favicon;
|
||||||
WeakPtr<HTML::BrowsingContext> m_browsing_context;
|
WeakPtr<HTML::BrowsingContext> m_browsing_context;
|
||||||
AK::URL m_url;
|
AK::URL m_url;
|
||||||
|
|
|
@ -114,9 +114,7 @@ void InlinePaintable::paint(PaintContext& context, PaintPhase phase) const
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: We check for a non-null dom_node(), since pseudo-elements have a null one and were getting
|
if (phase == PaintPhase::Overlay && layout_node().document().inspected_layout_node() == &layout_node()) {
|
||||||
// highlighted incorrectly. A better solution will be needed if we want to inspect them too.
|
|
||||||
if (phase == PaintPhase::Overlay && layout_node().dom_node() && layout_node().document().inspected_node() == layout_node().dom_node()) {
|
|
||||||
// FIXME: This paints a double-thick border between adjacent fragments, where ideally there
|
// FIXME: This paints a double-thick border between adjacent fragments, where ideally there
|
||||||
// would be none. Once we implement non-rectangular outlines for the `outline` CSS
|
// would be none. Once we implement non-rectangular outlines for the `outline` CSS
|
||||||
// property, we can use that here instead.
|
// property, we can use that here instead.
|
||||||
|
|
|
@ -30,6 +30,8 @@ constexpr float sin_60_deg = 0.866025403f;
|
||||||
|
|
||||||
void MarkerPaintable::paint(PaintContext& context, PaintPhase phase) const
|
void MarkerPaintable::paint(PaintContext& context, PaintPhase phase) const
|
||||||
{
|
{
|
||||||
|
if (phase == PaintPhase::Overlay)
|
||||||
|
PaintableBox::paint(context, phase);
|
||||||
if (phase != PaintPhase::Foreground)
|
if (phase != PaintPhase::Foreground)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ void PaintableBox::paint(PaintContext& context, PaintPhase phase) const
|
||||||
if (phase == PaintPhase::Overlay && should_clip_rect)
|
if (phase == PaintPhase::Overlay && should_clip_rect)
|
||||||
context.painter().restore();
|
context.painter().restore();
|
||||||
|
|
||||||
if (phase == PaintPhase::Overlay && layout_box().dom_node() && layout_box().document().inspected_node() == layout_box().dom_node()) {
|
if (phase == PaintPhase::Overlay && layout_box().document().inspected_layout_node() == &layout_box()) {
|
||||||
auto content_rect = absolute_rect();
|
auto content_rect = absolute_rect();
|
||||||
|
|
||||||
auto margin_box = box_model().margin_box();
|
auto margin_box = box_model().margin_box();
|
||||||
|
@ -511,7 +511,7 @@ static void paint_text_fragment(PaintContext& context, Layout::TextNode const& t
|
||||||
auto fragment_absolute_rect = fragment.absolute_rect();
|
auto fragment_absolute_rect = fragment.absolute_rect();
|
||||||
auto fragment_absolute_device_rect = context.enclosing_device_rect(fragment_absolute_rect);
|
auto fragment_absolute_device_rect = context.enclosing_device_rect(fragment_absolute_rect);
|
||||||
|
|
||||||
if (text_node.document().inspected_node() == &text_node.dom_node())
|
if (text_node.document().inspected_layout_node() == &text_node)
|
||||||
context.painter().draw_rect(fragment_absolute_device_rect.to_type<int>(), Color::Magenta);
|
context.painter().draw_rect(fragment_absolute_device_rect.to_type<int>(), Color::Magenta);
|
||||||
|
|
||||||
auto text = text_node.text_for_rendering();
|
auto text = text_node.text_for_rendering();
|
||||||
|
|
|
@ -444,7 +444,7 @@ Messages::WebContentServer::InspectDomNodeResponse ConnectionFromClient::inspect
|
||||||
|
|
||||||
top_context.for_each_in_inclusive_subtree([&](auto& ctx) {
|
top_context.for_each_in_inclusive_subtree([&](auto& ctx) {
|
||||||
if (ctx.active_document() != nullptr) {
|
if (ctx.active_document() != nullptr) {
|
||||||
ctx.active_document()->set_inspected_node(nullptr);
|
ctx.active_document()->set_inspected_node(nullptr, {});
|
||||||
}
|
}
|
||||||
return IterationDecision::Continue;
|
return IterationDecision::Continue;
|
||||||
});
|
});
|
||||||
|
@ -455,8 +455,7 @@ Messages::WebContentServer::InspectDomNodeResponse ConnectionFromClient::inspect
|
||||||
return { false, "", "", "", "" };
|
return { false, "", "", "", "" };
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: Pass the pseudo-element here.
|
node->document().set_inspected_node(node, pseudo_element);
|
||||||
node->document().set_inspected_node(node);
|
|
||||||
|
|
||||||
if (node->is_element()) {
|
if (node->is_element()) {
|
||||||
auto& element = verify_cast<Web::DOM::Element>(*node);
|
auto& element = verify_cast<Web::DOM::Element>(*node);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue