Browse Source

LibWeb: Implement the `HTMLLinkElement.relList` attribute

This returns a DOMTokenList that reflects the `rel` attribute.
Tim Ledbetter 1 năm trước cách đây
mục cha
commit
51fc30a191

+ 6 - 0
Tests/LibWeb/Text/expected/HTML/relList-attribute.txt

@@ -16,3 +16,9 @@ form.relList for after setting rel to "whatever": whatever
 form.relList for after setting rel to "prefetch": prefetch
 form.relList contains "prefetch": true
 form.relList contains "whatever": false
+link.relList initial length: 0
+link.relList always returns the same value: true
+link.relList for after setting rel to "whatever": whatever
+link.relList for after setting rel to "prefetch": prefetch
+link.relList contains "prefetch": true
+link.relList contains "whatever": false

+ 1 - 0
Tests/LibWeb/Text/input/HTML/relList-attribute.html

@@ -19,6 +19,7 @@
             "a",
             "area",
             "form",
+            "link",
         ];
 
         for (const tagName of tagNamesToTest) {

+ 13 - 0
Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp

@@ -13,6 +13,7 @@
 #include <LibURL/URL.h>
 #include <LibWeb/Bindings/HTMLLinkElementPrototype.h>
 #include <LibWeb/CSS/Parser/Parser.h>
+#include <LibWeb/DOM/DOMTokenList.h>
 #include <LibWeb/DOM/Document.h>
 #include <LibWeb/DOM/Event.h>
 #include <LibWeb/DOM/ShadowRoot.h>
@@ -89,6 +90,15 @@ void HTMLLinkElement::inserted()
     }
 }
 
+// https://html.spec.whatwg.org/multipage/semantics.html#dom-link-rellist
+JS::GCPtr<DOM::DOMTokenList> HTMLLinkElement::rel_list()
+{
+    // The relList IDL attribute must reflect the rel content attribute.
+    if (!m_rel_list)
+        m_rel_list = DOM::DOMTokenList::create(*this, HTML::AttributeNames::rel);
+    return m_rel_list;
+}
+
 bool HTMLLinkElement::has_loaded_icon() const
 {
     return m_relationship & Relationship::Icon && resource() && resource()->is_loaded() && resource()->has_encoded_data();
@@ -121,6 +131,9 @@ void HTMLLinkElement::attribute_changed(FlyString const& name, Optional<String>
             else if (part == "icon"sv)
                 m_relationship |= Relationship::Icon;
         }
+
+        if (m_rel_list)
+            m_rel_list->associated_attribute_changed(value.value_or(String {}));
     }
 
     // https://html.spec.whatwg.org/multipage/semantics.html#the-link-element:explicitly-enabled

+ 4 - 1
Userland/Libraries/LibWeb/HTML/HTMLLinkElement.h

@@ -34,6 +34,8 @@ public:
     String type() const { return get_attribute_value(HTML::AttributeNames::type); }
     String href() const { return get_attribute_value(HTML::AttributeNames::href); }
 
+    JS::GCPtr<DOM::DOMTokenList> rel_list();
+
     bool has_loaded_icon() const;
     bool load_favicon_and_use_if_window_is_active();
 
@@ -43,7 +45,7 @@ private:
     HTMLLinkElement(DOM::Document&, DOM::QualifiedName);
 
     virtual void initialize(JS::Realm&) override;
-    void attribute_changed(FlyString const&, Optional<String> const&) override;
+    virtual void attribute_changed(FlyString const&, Optional<String> const&) override;
 
     // ^ResourceClient
     virtual void resource_did_fail() override;
@@ -133,6 +135,7 @@ private:
     JS::GCPtr<CSS::CSSStyleSheet> m_loaded_style_sheet;
 
     Optional<DOM::DocumentLoadEventDelayer> m_document_load_event_delayer;
+    JS::GCPtr<DOM::DOMTokenList> m_rel_list;
     unsigned m_relationship { 0 };
     // https://html.spec.whatwg.org/multipage/semantics.html#explicitly-enabled
     bool m_explicitly_enabled { false };

+ 1 - 1
Userland/Libraries/LibWeb/HTML/HTMLLinkElement.idl

@@ -11,7 +11,7 @@ interface HTMLLinkElement : HTMLElement {
     // FIXME: [CEReactions] attribute DOMString? crossOrigin;
     [CEReactions, Reflect] attribute DOMString rel;
     // FIXME: [CEReactions] attribute DOMString as;
-    // FIXME: [SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
+    [SameObject, PutForwards=value] readonly attribute DOMTokenList relList;
     [CEReactions, Reflect] attribute DOMString media;
     [CEReactions, Reflect] attribute DOMString integrity;
     [CEReactions, Reflect] attribute DOMString hreflang;