소스 검색

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.
Andreas Kling 2 년 전
부모
커밋
4b9c5635b3
3개의 변경된 파일12개의 추가작업 그리고 8개의 파일을 삭제
  1. 12 1
      Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp
  2. 0 5
      Userland/Libraries/LibWeb/DOM/Node.cpp
  3. 0 2
      Userland/Libraries/LibWeb/DOM/Node.h

+ 12 - 1
Userland/Libraries/LibWeb/CSS/SelectorEngine.cpp

@@ -11,6 +11,8 @@
 #include <LibWeb/DOM/Element.h>
 #include <LibWeb/DOM/Text.h>
 #include <LibWeb/HTML/AttributeNames.h>
+#include <LibWeb/HTML/HTMLAnchorElement.h>
+#include <LibWeb/HTML/HTMLAreaElement.h>
 #include <LibWeb/HTML/HTMLHtmlElement.h>
 #include <LibWeb/HTML/HTMLInputElement.h>
 
@@ -44,6 +46,15 @@ static inline bool matches_lang_pseudo_class(DOM::Element const& element, Vector
     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)
 {
     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) {
     case CSS::Selector::SimpleSelector::PseudoClass::Type::Link:
-        return element.is_link();
+        return matches_link_pseudo_class(element);
     case CSS::Selector::SimpleSelector::PseudoClass::Type::Visited:
         // FIXME: Maybe match this selector sometimes?
         return false;

+ 0 - 5
Userland/Libraries/LibWeb/DOM/Node.cpp

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

+ 0 - 2
Userland/Libraries/LibWeb/DOM/Node.h

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