1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-17 08:57:35 +00:00

LibWeb: Make :link selector behave according to spec

It should match any `a` or `area` element that has an `href` attribute,
not any element *inside* an enclosing linked element.
This commit is contained in:
Andreas Kling 2022-09-14 13:29:07 +02:00
parent f25203f245
commit 4b9c5635b3
3 changed files with 12 additions and 8 deletions

View file

@ -11,6 +11,8 @@
#include <LibWeb/DOM/Element.h> #include <LibWeb/DOM/Element.h>
#include <LibWeb/DOM/Text.h> #include <LibWeb/DOM/Text.h>
#include <LibWeb/HTML/AttributeNames.h> #include <LibWeb/HTML/AttributeNames.h>
#include <LibWeb/HTML/HTMLAnchorElement.h>
#include <LibWeb/HTML/HTMLAreaElement.h>
#include <LibWeb/HTML/HTMLHtmlElement.h> #include <LibWeb/HTML/HTMLHtmlElement.h>
#include <LibWeb/HTML/HTMLInputElement.h> #include <LibWeb/HTML/HTMLInputElement.h>
@ -44,6 +46,15 @@ static inline bool matches_lang_pseudo_class(DOM::Element const& element, Vector
return false; return false;
} }
// https://html.spec.whatwg.org/multipage/semantics-other.html#selector-link
static inline bool matches_link_pseudo_class(DOM::Element const& element)
{
// All a elements that have an href attribute, and all area elements that have an href attribute, must match one of :link and :visited.
if (!is<HTML::HTMLAnchorElement>(element) && !is<HTML::HTMLAreaElement>(element))
return false;
return element.has_attribute(HTML::AttributeNames::href);
}
static inline bool matches_hover_pseudo_class(DOM::Element const& element) static inline bool matches_hover_pseudo_class(DOM::Element const& element)
{ {
auto* hovered_node = element.document().hovered_node(); auto* hovered_node = element.document().hovered_node();
@ -163,7 +174,7 @@ static inline bool matches_pseudo_class(CSS::Selector::SimpleSelector::PseudoCla
{ {
switch (pseudo_class.type) { switch (pseudo_class.type) {
case CSS::Selector::SimpleSelector::PseudoClass::Type::Link: case CSS::Selector::SimpleSelector::PseudoClass::Type::Link:
return element.is_link(); return matches_link_pseudo_class(element);
case CSS::Selector::SimpleSelector::PseudoClass::Type::Visited: case CSS::Selector::SimpleSelector::PseudoClass::Type::Visited:
// FIXME: Maybe match this selector sometimes? // FIXME: Maybe match this selector sometimes?
return false; return false;

View file

@ -244,11 +244,6 @@ void Node::invalidate_style()
document().schedule_style_update(); document().schedule_style_update();
} }
bool Node::is_link() const
{
return enclosing_link_element();
}
String Node::child_text_content() const String Node::child_text_content() const
{ {
if (!is<ParentNode>(*this)) if (!is<ParentNode>(*this))

View file

@ -170,8 +170,6 @@ public:
void invalidate_style(); void invalidate_style();
bool is_link() const;
void set_document(Badge<Document>, Document&); void set_document(Badge<Document>, Document&);
virtual EventTarget* get_parent(Event const&) override; virtual EventTarget* get_parent(Event const&) override;