Bläddra i källkod

LibWeb: Implement the `HTMLOutputElement.htmlFor` attribute

This returns a DOMTokenList that reflects the `for` attribute.
Tim Ledbetter 1 år sedan
förälder
incheckning
3dc86747f0

+ 9 - 0
Tests/LibWeb/Text/expected/HTML/HTMLOutputElement-htmlfor.txt

@@ -0,0 +1,9 @@
+output.htmlFor is initially empty: true
+output.htmlFor always returns the same object: true
+output.htmlFor after setting output.htmlFor to "a": a
+for attribute value after setting output.htmlFor to "a": a
+output.htmlFor after calling output.setAttribute("for", "b"): b
+output.htmlFor after setting output.htmlFor to "c d": c d
+for attribute value after setting output.htmlFor to "c d": c d
+output.htmlFor.contains("c"): true
+output.htmlFor.contains("a"): false

+ 20 - 0
Tests/LibWeb/Text/input/HTML/HTMLOutputElement-htmlfor.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        const outputElement = document.createElement("output");
+        const htmlFor = outputElement.htmlFor;
+        println(`output.htmlFor is initially empty: ${htmlFor.length === 0}`);
+        println(`output.htmlFor always returns the same object: ${outputElement.htmlFor === htmlFor}`);
+        outputElement.htmlFor = "a";
+        println(`output.htmlFor after setting output.htmlFor to "a": ${outputElement.htmlFor}`);
+        println(`for attribute value after setting output.htmlFor to "a": ${outputElement.getAttribute("for")}`);
+        outputElement.setAttribute("for", "b");
+        println(`output.htmlFor after calling output.setAttribute("for", "b"): ${outputElement.htmlFor}`);
+        outputElement.htmlFor = "c d";
+        println(`output.htmlFor after setting output.htmlFor to "c d": ${outputElement.htmlFor}`);
+        println(`for attribute value after setting output.htmlFor to "c d": ${outputElement.getAttribute("for")}`);
+        println(`output.htmlFor.contains("c"): ${outputElement.htmlFor.contains("c")}`);
+        println(`output.htmlFor.contains("a"): ${outputElement.htmlFor.contains("a")}`);        
+    });
+</script>

+ 24 - 0
Userland/Libraries/LibWeb/HTML/HTMLOutputElement.cpp

@@ -6,6 +6,7 @@
 
 #include <LibWeb/Bindings/HTMLOutputElementPrototype.h>
 #include <LibWeb/Bindings/Intrinsics.h>
+#include <LibWeb/DOM/DOMTokenList.h>
 #include <LibWeb/HTML/HTMLOutputElement.h>
 
 namespace Web::HTML {
@@ -25,6 +26,29 @@ void HTMLOutputElement::initialize(JS::Realm& realm)
     WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLOutputElement);
 }
 
+void HTMLOutputElement::visit_edges(Cell::Visitor& visitor)
+{
+    Base::visit_edges(visitor);
+    visitor.visit(m_html_for);
+}
+
+void HTMLOutputElement::form_associated_element_attribute_changed(FlyString const& name, Optional<String> const& value)
+{
+    if (name == HTML::AttributeNames::for_) {
+        if (m_html_for)
+            m_html_for->associated_attribute_changed(value.value_or(String {}));
+    }
+}
+
+// https://html.spec.whatwg.org/multipage/form-elements.html#dom-output-htmlfor
+JS::NonnullGCPtr<DOM::DOMTokenList> HTMLOutputElement::html_for()
+{
+    // The htmlFor IDL attribute must reflect the for content attribute.
+    if (!m_html_for)
+        m_html_for = DOM::DOMTokenList::create(*this, HTML::AttributeNames::for_);
+    return *m_html_for;
+}
+
 // https://html.spec.whatwg.org/multipage/form-elements.html#dom-output-defaultvalue
 String HTMLOutputElement::default_value() const
 {

+ 7 - 0
Userland/Libraries/LibWeb/HTML/HTMLOutputElement.h

@@ -23,6 +23,8 @@ class HTMLOutputElement final
 public:
     virtual ~HTMLOutputElement() override;
 
+    JS::NonnullGCPtr<DOM::DOMTokenList> html_for();
+
     String const& type() const
     {
         static String const output = "output"_string;
@@ -58,6 +60,11 @@ private:
     HTMLOutputElement(DOM::Document&, DOM::QualifiedName);
 
     virtual void initialize(JS::Realm&) override;
+    virtual void visit_edges(Cell::Visitor& visitor) override;
+
+    virtual void form_associated_element_attribute_changed(FlyString const& name, Optional<String> const& value) override;
+
+    JS::GCPtr<DOM::DOMTokenList> m_html_for;
 
     Optional<String> m_default_value_override {};
 };

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

@@ -6,7 +6,7 @@
 interface HTMLOutputElement : HTMLElement {
     [HTMLConstructor] constructor();
 
-    // FIXME: [SameObject, PutForwards=value] readonly attribute DOMTokenList htmlFor;
+    [SameObject, PutForwards=value] readonly attribute DOMTokenList htmlFor;
     readonly attribute HTMLFormElement? form;
     [CEReactions, Reflect] attribute DOMString name;