LibWeb: Follow the specification steps to serialize a DOMTokenList

This ensures that calling `element.classList.toString()` always
produces the correct value.

(cherry picked from commit ec1f7779cb16223dab0ef9f7bf875c3f7b5724a9)
This commit is contained in:
Tim Ledbetter 2024-07-23 13:09:11 +01:00 committed by Nico Weber
parent 66280e96e9
commit a88effd0fe
4 changed files with 17 additions and 3 deletions

View file

@ -1,3 +1,5 @@
element.classList initial value: "" element.classList initial value: ""
element.classList after setting classList to "a": "a" element.classList after setting classList to "a": "a"
element.classList after setting className to "": "" element.classList after setting className to "": ""
element.classList after setting to className to "a a b c": "a a b c"
element.classList after setting to className to " a a b c ": " a a b c "

View file

@ -8,6 +8,10 @@
println(`element.classList after setting classList to "a": "${element.classList.toString()}"`); println(`element.classList after setting classList to "a": "${element.classList.toString()}"`);
element.className = ""; element.className = "";
println(`element.classList after setting className to "": "${element.classList.toString()}"`); println(`element.classList after setting className to "": "${element.classList.toString()}"`);
element.className = "a a b c";
println(`element.classList after setting to className to "a a b c": "${element.classList.toString()}"`);
element.className = " a a b c ";
println(`element.classList after setting to className to " a a b c ": "${element.classList.toString()}"`);
}); });
</script> </script>
</html> </html>

View file

@ -233,14 +233,20 @@ WebIDL::ExceptionOr<bool> DOMTokenList::supports(StringView token)
return false; return false;
} }
// https://dom.spec.whatwg.org/#dom-domtokenlist-value // https://dom.spec.whatwg.org/#concept-ordered-set-serializer
String DOMTokenList::value() const String DOMTokenList::serialize_ordered_set() const
{ {
StringBuilder builder; StringBuilder builder;
builder.join(' ', m_token_set); builder.join(' ', m_token_set);
return MUST(builder.to_string()); return MUST(builder.to_string());
} }
// https://dom.spec.whatwg.org/#dom-domtokenlist-value
String DOMTokenList::value() const
{
return m_associated_element->get_attribute_value(m_associated_attribute);
}
// https://dom.spec.whatwg.org/#ref-for-concept-element-attributes-set-value%E2%91%A2 // https://dom.spec.whatwg.org/#ref-for-concept-element-attributes-set-value%E2%91%A2
void DOMTokenList::set_value(String const& value) void DOMTokenList::set_value(String const& value)
{ {
@ -272,7 +278,7 @@ void DOMTokenList::run_update_steps()
return; return;
// 2. Set an attribute value for the associated element using associated attributes local name and the result of running the ordered set serializer for token set. // 2. Set an attribute value for the associated element using associated attributes local name and the result of running the ordered set serializer for token set.
MUST(associated_element->set_attribute(m_associated_attribute, value())); MUST(associated_element->set_attribute(m_associated_attribute, serialize_ordered_set()));
} }
Optional<JS::Value> DOMTokenList::item_value(size_t index) const Optional<JS::Value> DOMTokenList::item_value(size_t index) const

View file

@ -52,6 +52,8 @@ private:
WebIDL::ExceptionOr<void> validate_token(StringView token) const; WebIDL::ExceptionOr<void> validate_token(StringView token) const;
void run_update_steps(); void run_update_steps();
String serialize_ordered_set() const;
JS::NonnullGCPtr<Element> m_associated_element; JS::NonnullGCPtr<Element> m_associated_element;
FlyString m_associated_attribute; FlyString m_associated_attribute;
Vector<String> m_token_set; Vector<String> m_token_set;