LibWeb: Avoid invoking Trusted Types where avoidable

Prevents observably calling Trusted Types, which can run arbitrary JS,
cause crashes due to use of MUST and allow arbitrary JS to modify
internal elements.
This commit is contained in:
Luke Wilde 2025-10-31 12:30:47 +00:00 committed by Tim Flynn
parent fb9406ddcd
commit 82bd3d3891
Notes: github-actions[bot] 2025-11-06 16:46:00 +00:00
83 changed files with 407 additions and 366 deletions

View file

@ -34,7 +34,7 @@ public:
#define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \ #define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \
virtual Optional<String> name() const = 0; \ virtual Optional<String> name() const = 0; \
virtual WebIDL::ExceptionOr<void> set_##name(Optional<String> const&) = 0; virtual void set_##name(Optional<String> const&) = 0;
ENUMERATE_ARIA_ATTRIBUTES ENUMERATE_ARIA_ATTRIBUTES
#undef __ENUMERATE_ARIA_ATTRIBUTE #undef __ENUMERATE_ARIA_ATTRIBUTE

View file

@ -49,7 +49,7 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> AudioConstructor::construct(FunctionO
auto audio = TRY(Bindings::throw_dom_exception_if_needed(vm, [&]() { return DOM::create_element(document, HTML::TagNames::audio, Namespace::HTML); })); auto audio = TRY(Bindings::throw_dom_exception_if_needed(vm, [&]() { return DOM::create_element(document, HTML::TagNames::audio, Namespace::HTML); }));
// 3. Set an attribute value for audio using "preload" and "auto". // 3. Set an attribute value for audio using "preload" and "auto".
MUST(audio->set_attribute(HTML::AttributeNames::preload, "auto"_string)); audio->set_attribute_value(HTML::AttributeNames::preload, "auto"_string);
auto src_value = vm.argument(0); auto src_value = vm.argument(0);
@ -57,7 +57,7 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> AudioConstructor::construct(FunctionO
// (This will cause the user agent to invoke the object's resource selection algorithm before returning.) // (This will cause the user agent to invoke the object's resource selection algorithm before returning.)
if (!src_value.is_undefined()) { if (!src_value.is_undefined()) {
auto src = TRY(src_value.to_string(vm)); auto src = TRY(src_value.to_string(vm));
MUST(audio->set_attribute(HTML::AttributeNames::src, move(src))); audio->set_attribute_value(HTML::AttributeNames::src, move(src));
} }
// 5. Return audio. // 5. Return audio.

View file

@ -53,13 +53,13 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> ImageConstructor::construct(FunctionO
// 3. If width is given, then set an attribute value for img using "width" and width. // 3. If width is given, then set an attribute value for img using "width" and width.
if (vm.argument_count() > 0) { if (vm.argument_count() > 0) {
u32 width = TRY(vm.argument(0).to_u32(vm)); u32 width = TRY(vm.argument(0).to_u32(vm));
MUST(image_element->set_attribute(HTML::AttributeNames::width, MUST(String::formatted("{}", width)))); image_element->set_attribute_value(HTML::AttributeNames::width, MUST(String::formatted("{}", width)));
} }
// 4. If height is given, then set an attribute value for img using "height" and height. // 4. If height is given, then set an attribute value for img using "height" and height.
if (vm.argument_count() > 1) { if (vm.argument_count() > 1) {
u32 height = TRY(vm.argument(1).to_u32(vm)); u32 height = TRY(vm.argument(1).to_u32(vm));
MUST(image_element->set_attribute(HTML::AttributeNames::height, MUST(String::formatted("{}", height)))); image_element->set_attribute_value(HTML::AttributeNames::height, MUST(String::formatted("{}", height)));
} }
// 5. Return img. // 5. Return img.

View file

@ -69,14 +69,14 @@ JS::ThrowCompletionOr<GC::Ref<JS::Object>> OptionConstructor::construct(Function
// 4. If value is given, then set an attribute value for option using "value" and value. // 4. If value is given, then set an attribute value for option using "value" and value.
if (!vm.argument(1).is_undefined()) { if (!vm.argument(1).is_undefined()) {
auto value = TRY(vm.argument(1).to_string(vm)); auto value = TRY(vm.argument(1).to_string(vm));
MUST(option_element->set_attribute(HTML::AttributeNames::value, value)); option_element->set_attribute_value(HTML::AttributeNames::value, value);
} }
// 5. If defaultSelected is true, then set an attribute value for option using "selected" and the empty string. // 5. If defaultSelected is true, then set an attribute value for option using "selected" and the empty string.
if (vm.argument_count() > 2) { if (vm.argument_count() > 2) {
auto default_selected = vm.argument(2).to_boolean(); auto default_selected = vm.argument(2).to_boolean();
if (default_selected) { if (default_selected) {
MUST(option_element->set_attribute(HTML::AttributeNames::selected, String {})); option_element->set_attribute_value(HTML::AttributeNames::selected, String {});
} }
} }

View file

@ -48,7 +48,7 @@ void CSSStyleDeclaration::update_style_attribute()
set_is_updating(true); set_is_updating(true);
// 5. Set an attribute value for owner node using "style" and the result of serializing declaration block. // 5. Set an attribute value for owner node using "style" and the result of serializing declaration block.
MUST(owner_node()->element().set_attribute(HTML::AttributeNames::style, serialized())); owner_node()->element().set_attribute_value(HTML::AttributeNames::style, serialized());
// 6. Unset declaration blocks updating flag. // 6. Unset declaration blocks updating flag.
set_is_updating(false); set_is_updating(false);

View file

@ -258,7 +258,7 @@ void DOMTokenList::set_value(String const& value)
if (!associated_element) if (!associated_element)
return; return;
MUST(associated_element->set_attribute(m_associated_attribute, value)); associated_element->set_attribute_value(m_associated_attribute, value);
} }
WebIDL::ExceptionOr<void> DOMTokenList::validate_token(StringView token) const WebIDL::ExceptionOr<void> DOMTokenList::validate_token(StringView token) const
@ -294,7 +294,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, serialize_ordered_set())); associated_element->set_attribute_value(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

@ -3189,7 +3189,7 @@ String Document::fg_color() const
void Document::set_fg_color(String const& value) void Document::set_fg_color(String const& value)
{ {
if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element)) if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element))
MUST(body_element->set_attribute(HTML::AttributeNames::text, value)); body_element->set_attribute_value(HTML::AttributeNames::text, value);
} }
String Document::link_color() const String Document::link_color() const
@ -3202,7 +3202,7 @@ String Document::link_color() const
void Document::set_link_color(String const& value) void Document::set_link_color(String const& value)
{ {
if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element)) if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element))
MUST(body_element->set_attribute(HTML::AttributeNames::link, value)); body_element->set_attribute_value(HTML::AttributeNames::link, value);
} }
String Document::vlink_color() const String Document::vlink_color() const
@ -3215,7 +3215,7 @@ String Document::vlink_color() const
void Document::set_vlink_color(String const& value) void Document::set_vlink_color(String const& value)
{ {
if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element)) if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element))
MUST(body_element->set_attribute(HTML::AttributeNames::vlink, value)); body_element->set_attribute_value(HTML::AttributeNames::vlink, value);
} }
String Document::alink_color() const String Document::alink_color() const
@ -3228,7 +3228,7 @@ String Document::alink_color() const
void Document::set_alink_color(String const& value) void Document::set_alink_color(String const& value)
{ {
if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element)) if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element))
MUST(body_element->set_attribute(HTML::AttributeNames::alink, value)); body_element->set_attribute_value(HTML::AttributeNames::alink, value);
} }
String Document::bg_color() const String Document::bg_color() const
@ -3241,7 +3241,7 @@ String Document::bg_color() const
void Document::set_bg_color(String const& value) void Document::set_bg_color(String const& value)
{ {
if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element)) if (auto* body_element = body(); body_element && !is<HTML::HTMLFrameSetElement>(*body_element))
MUST(body_element->set_attribute(HTML::AttributeNames::bgcolor, value)); body_element->set_attribute_value(HTML::AttributeNames::bgcolor, value);
} }
String Document::dump_dom_tree_as_json() const String Document::dump_dom_tree_as_json() const

View file

@ -296,7 +296,7 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_media_document(HTML::Nav
}; };
auto style_element = TRY(DOM::create_element(document, HTML::TagNames::style, Namespace::HTML)); auto style_element = TRY(DOM::create_element(document, HTML::TagNames::style, Namespace::HTML));
MUST(style_element->set_text_content(R"~~~( style_element->string_replace_all(R"~~~(
:root { :root {
background-color: #222; background-color: #222;
} }
@ -310,29 +310,29 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_media_document(HTML::Nav
img { img {
background-color: #fff; background-color: #fff;
} }
)~~~"_utf16)); )~~~"_utf16);
TRY(document->head()->append_child(style_element)); TRY(document->head()->append_child(style_element));
auto url_string = document->url_string(); auto url_string = document->url_string();
if (type.is_image()) { if (type.is_image()) {
auto img_element = TRY(DOM::create_element(document, HTML::TagNames::img, Namespace::HTML)); auto img_element = TRY(DOM::create_element(document, HTML::TagNames::img, Namespace::HTML));
TRY(img_element->set_attribute(HTML::AttributeNames::src, url_string)); img_element->set_attribute_value(HTML::AttributeNames::src, url_string);
TRY(document->body()->append_child(img_element)); TRY(document->body()->append_child(img_element));
TRY(insert_title(document, url_string)); TRY(insert_title(document, url_string));
} else if (type.type() == "video"sv) { } else if (type.type() == "video"sv) {
auto video_element = TRY(DOM::create_element(document, HTML::TagNames::video, Namespace::HTML)); auto video_element = TRY(DOM::create_element(document, HTML::TagNames::video, Namespace::HTML));
TRY(video_element->set_attribute(HTML::AttributeNames::src, url_string)); video_element->set_attribute_value(HTML::AttributeNames::src, url_string);
TRY(video_element->set_attribute(HTML::AttributeNames::autoplay, String {})); video_element->set_attribute_value(HTML::AttributeNames::autoplay, String {});
TRY(video_element->set_attribute(HTML::AttributeNames::controls, String {})); video_element->set_attribute_value(HTML::AttributeNames::controls, String {});
TRY(document->body()->append_child(video_element)); TRY(document->body()->append_child(video_element));
TRY(insert_title(document, url_string)); TRY(insert_title(document, url_string));
} else if (type.type() == "audio"sv) { } else if (type.type() == "audio"sv) {
auto audio_element = TRY(DOM::create_element(document, HTML::TagNames::audio, Namespace::HTML)); auto audio_element = TRY(DOM::create_element(document, HTML::TagNames::audio, Namespace::HTML));
TRY(audio_element->set_attribute(HTML::AttributeNames::src, url_string)); audio_element->set_attribute_value(HTML::AttributeNames::src, url_string);
TRY(audio_element->set_attribute(HTML::AttributeNames::autoplay, String {})); audio_element->set_attribute_value(HTML::AttributeNames::autoplay, String {});
TRY(audio_element->set_attribute(HTML::AttributeNames::controls, String {})); audio_element->set_attribute_value(HTML::AttributeNames::controls, String {});
TRY(document->body()->append_child(audio_element)); TRY(document->body()->append_child(audio_element));
TRY(insert_title(document, url_string)); TRY(insert_title(document, url_string));

View file

@ -210,7 +210,7 @@ GC::Ptr<Attr> Element::get_attribute_node_ns(Optional<FlyString> const& namespac
// FIXME: Trusted Types integration with DOM is still under review https://github.com/whatwg/dom/pull/1268 // FIXME: Trusted Types integration with DOM is still under review https://github.com/whatwg/dom/pull/1268
// https://whatpr.org/dom/1268.html#dom-element-setattribute // https://whatpr.org/dom/1268.html#dom-element-setattribute
WebIDL::ExceptionOr<void> Element::set_attribute(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value) WebIDL::ExceptionOr<void> Element::set_attribute_for_bindings(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value)
{ {
// 1. If qualifiedName is not a valid attribute local name, then throw an "InvalidCharacterError" DOMException. // 1. If qualifiedName is not a valid attribute local name, then throw an "InvalidCharacterError" DOMException.
if (!is_valid_attribute_local_name(qualified_name)) if (!is_valid_attribute_local_name(qualified_name))
@ -245,9 +245,9 @@ WebIDL::ExceptionOr<void> Element::set_attribute(FlyString qualified_name, Varia
// FIXME: Trusted Types integration with DOM is still under review https://github.com/whatwg/dom/pull/1268 // FIXME: Trusted Types integration with DOM is still under review https://github.com/whatwg/dom/pull/1268
// https://whatpr.org/dom/1268.html#dom-element-setattribute // https://whatpr.org/dom/1268.html#dom-element-setattribute
WebIDL::ExceptionOr<void> Element::set_attribute(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, String> const& value) WebIDL::ExceptionOr<void> Element::set_attribute_for_bindings(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, String> const& value)
{ {
return set_attribute(move(qualified_name), return set_attribute_for_bindings(move(qualified_name),
value.visit( value.visit(
[](auto const& trusted_type) -> Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> { return trusted_type; }, [](auto const& trusted_type) -> Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> { return trusted_type; },
[](String const& string) -> Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> { return Utf16String::from_utf8(string); })); [](String const& string) -> Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> { return Utf16String::from_utf8(string); }));
@ -365,7 +365,7 @@ WebIDL::ExceptionOr<QualifiedName> validate_and_extract(JS::Realm& realm, Option
// FIXME: Trusted Types integration with DOM is still under review https://github.com/whatwg/dom/pull/1268 // FIXME: Trusted Types integration with DOM is still under review https://github.com/whatwg/dom/pull/1268
// https://whatpr.org/dom/1268.html#dom-element-setattributens // https://whatpr.org/dom/1268.html#dom-element-setattributens
WebIDL::ExceptionOr<void> Element::set_attribute_ns(Optional<FlyString> const& namespace_, FlyString const& qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value) WebIDL::ExceptionOr<void> Element::set_attribute_ns_for_bindings(Optional<FlyString> const& namespace_, FlyString const& qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value)
{ {
// 1. Let (namespace, prefix, localName) be the result of validating and extracting namespace and qualifiedName given "element". // 1. Let (namespace, prefix, localName) be the result of validating and extracting namespace and qualifiedName given "element".
auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_, qualified_name, ValidationContext::Element)); auto extracted_qualified_name = TRY(validate_and_extract(realm(), namespace_, qualified_name, ValidationContext::Element));
@ -421,14 +421,14 @@ void Element::set_attribute_value(FlyString const& local_name, String const& val
} }
// https://dom.spec.whatwg.org/#dom-element-setattributenode // https://dom.spec.whatwg.org/#dom-element-setattributenode
WebIDL::ExceptionOr<GC::Ptr<Attr>> Element::set_attribute_node(Attr& attr) WebIDL::ExceptionOr<GC::Ptr<Attr>> Element::set_attribute_node_for_bindings(Attr& attr)
{ {
// The setAttributeNode(attr) and setAttributeNodeNS(attr) methods steps are to return the result of setting an attribute given attr and this. // The setAttributeNode(attr) and setAttributeNodeNS(attr) methods steps are to return the result of setting an attribute given attr and this.
return attributes()->set_attribute(attr); return attributes()->set_attribute(attr);
} }
// https://dom.spec.whatwg.org/#dom-element-setattributenodens // https://dom.spec.whatwg.org/#dom-element-setattributenodens
WebIDL::ExceptionOr<GC::Ptr<Attr>> Element::set_attribute_node_ns(Attr& attr) WebIDL::ExceptionOr<GC::Ptr<Attr>> Element::set_attribute_node_ns_for_bindings(Attr& attr)
{ {
// The setAttributeNode(attr) and setAttributeNodeNS(attr) methods steps are to return the result of setting an attribute given attr and this. // The setAttributeNode(attr) and setAttributeNodeNS(attr) methods steps are to return the result of setting an attribute given attr and this.
return attributes()->set_attribute(attr); return attributes()->set_attribute(attr);
@ -1746,7 +1746,7 @@ i32 Element::tab_index() const
// https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex // https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex
void Element::set_tab_index(i32 tab_index) void Element::set_tab_index(i32 tab_index)
{ {
MUST(set_attribute(HTML::AttributeNames::tabindex, String::number(tab_index))); set_attribute_value(HTML::AttributeNames::tabindex, String::number(tab_index));
} }
// https://drafts.csswg.org/cssom-view/#potentially-scrollable // https://drafts.csswg.org/cssom-view/#potentially-scrollable
@ -2544,6 +2544,22 @@ ErrorOr<void> Element::scroll_into_view(Optional<Variant<bool, ScrollIntoViewOpt
return {}; return {};
} }
#define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \
Optional<String> Element::name() const \
{ \
return get_attribute(ARIA::AttributeNames::name); \
} \
\
void Element::set_##name(Optional<String> const& value) \
{ \
if (value.has_value()) \
set_attribute_value(ARIA::AttributeNames::name, *value); \
else \
remove_attribute(ARIA::AttributeNames::name); \
}
ENUMERATE_ARIA_ATTRIBUTES
#undef __ENUMERATE_ARIA_ATTRIBUTE
void Element::invalidate_style_after_attribute_change(FlyString const& attribute_name, Optional<String> const& old_value, Optional<String> const& new_value) void Element::invalidate_style_after_attribute_change(FlyString const& attribute_name, Optional<String> const& old_value, Optional<String> const& new_value)
{ {
Vector<CSS::InvalidationSet::Property, 1> changed_properties; Vector<CSS::InvalidationSet::Property, 1> changed_properties;

View file

@ -149,13 +149,13 @@ public:
Optional<String> lang() const; Optional<String> lang() const;
WebIDL::ExceptionOr<void> set_attribute(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, String> const& value); WebIDL::ExceptionOr<void> set_attribute_for_bindings(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value);
WebIDL::ExceptionOr<void> set_attribute(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value); WebIDL::ExceptionOr<void> set_attribute_for_bindings(FlyString qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, String> const& value);
WebIDL::ExceptionOr<void> set_attribute_ns(Optional<FlyString> const& namespace_, FlyString const& qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value); WebIDL::ExceptionOr<void> set_attribute_ns_for_bindings(Optional<FlyString> const& namespace_, FlyString const& qualified_name, Variant<GC::Root<TrustedTypes::TrustedHTML>, GC::Root<TrustedTypes::TrustedScript>, GC::Root<TrustedTypes::TrustedScriptURL>, Utf16String> const& value);
void set_attribute_value(FlyString const& local_name, String const& value, Optional<FlyString> const& prefix = {}, Optional<FlyString> const& namespace_ = {}); void set_attribute_value(FlyString const& local_name, String const& value, Optional<FlyString> const& prefix = {}, Optional<FlyString> const& namespace_ = {});
WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node(Attr&); WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node_for_bindings(Attr&);
WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node_ns(Attr&); WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node_ns_for_bindings(Attr&);
void append_attribute(FlyString const& name, String const& value); void append_attribute(FlyString const& name, String const& value);
void append_attribute(Attr&); void append_attribute(Attr&);
@ -337,19 +337,8 @@ public:
// https://www.w3.org/TR/wai-aria-1.2/#ARIAMixin // https://www.w3.org/TR/wai-aria-1.2/#ARIAMixin
#define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \ #define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \
Optional<String> name() const override \ virtual Optional<String> name() const override; \
{ \ virtual void set_##name(Optional<String> const& value) override;
return get_attribute(ARIA::AttributeNames::name); \
} \
\
WebIDL::ExceptionOr<void> set_##name(Optional<String> const& value) override \
{ \
if (value.has_value()) \
TRY(set_attribute(ARIA::AttributeNames::name, *value)); \
else \
remove_attribute(ARIA::AttributeNames::name); \
return {}; \
}
ENUMERATE_ARIA_ATTRIBUTES ENUMERATE_ARIA_ATTRIBUTES
#undef __ENUMERATE_ARIA_ATTRIBUTE #undef __ENUMERATE_ARIA_ATTRIBUTE

View file

@ -54,8 +54,8 @@ interface Element : Node {
sequence<DOMString> getAttributeNames(); sequence<DOMString> getAttributeNames();
DOMString? getAttribute(DOMString qualifiedName); DOMString? getAttribute(DOMString qualifiedName);
DOMString? getAttributeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName); DOMString? getAttributeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName);
[CEReactions] undefined setAttribute(DOMString qualifiedName, (TrustedType or Utf16DOMString) value); [CEReactions, ImplementedAs=set_attribute_for_bindings] undefined setAttribute(DOMString qualifiedName, (TrustedType or Utf16DOMString) value);
[CEReactions] undefined setAttributeNS([FlyString] DOMString? namespace , [FlyString] DOMString qualifiedName , (TrustedType or Utf16DOMString) value); [CEReactions, ImplementedAs=set_attribute_ns_for_bindings] undefined setAttributeNS([FlyString] DOMString? namespace, [FlyString] DOMString qualifiedName, (TrustedType or Utf16DOMString) value);
[CEReactions] undefined removeAttribute([FlyString] DOMString qualifiedName); [CEReactions] undefined removeAttribute([FlyString] DOMString qualifiedName);
[CEReactions] undefined removeAttributeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName); [CEReactions] undefined removeAttributeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName);
[CEReactions] boolean toggleAttribute(DOMString qualifiedName, optional boolean force); [CEReactions] boolean toggleAttribute(DOMString qualifiedName, optional boolean force);
@ -64,8 +64,8 @@ interface Element : Node {
Attr? getAttributeNode([FlyString] DOMString qualifiedName); Attr? getAttributeNode([FlyString] DOMString qualifiedName);
Attr? getAttributeNodeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName); Attr? getAttributeNodeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName);
[CEReactions] Attr? setAttributeNode(Attr attr); [CEReactions, ImplementedAs=set_attribute_node_for_bindings] Attr? setAttributeNode(Attr attr);
[CEReactions] Attr? setAttributeNodeNS(Attr attr); [CEReactions, ImplementedAs=set_attribute_node_ns_for_bindings] Attr? setAttributeNodeNS(Attr attr);
[CEReactions] Attr removeAttributeNode(Attr attr); [CEReactions] Attr removeAttributeNode(Attr attr);
ShadowRoot attachShadow(ShadowRootInit init); ShadowRoot attachShadow(ShadowRootInit init);

View file

@ -86,7 +86,7 @@ bool command_create_link_action(DOM::Document& document, Utf16String const& valu
return IterationDecision::Break; return IterationDecision::Break;
if (auto* anchor = as_if<HTML::HTMLAnchorElement>(*ancestor); anchor && anchor->is_editable() if (auto* anchor = as_if<HTML::HTMLAnchorElement>(*ancestor); anchor && anchor->is_editable()
&& anchor->has_attribute(HTML::AttributeNames::href)) && anchor->has_attribute(HTML::AttributeNames::href))
MUST(anchor->set_href(value.to_utf8_but_should_be_ported_to_utf16())); anchor->set_href(value.to_utf8_but_should_be_ported_to_utf16());
visited_ancestors.set(ancestor.ptr()); visited_ancestors.set(ancestor.ptr());
return IterationDecision::Continue; return IterationDecision::Continue;
}); });
@ -1324,7 +1324,7 @@ bool command_insert_image_action(DOM::Document& document, Utf16String const& val
auto img = MUST(DOM::create_element(document, HTML::TagNames::img, Namespace::HTML)); auto img = MUST(DOM::create_element(document, HTML::TagNames::img, Namespace::HTML));
// 7. Run setAttribute("src", value) on img. // 7. Run setAttribute("src", value) on img.
MUST(img->set_attribute(HTML::AttributeNames::src, value)); img->set_attribute_value(HTML::AttributeNames::src, value.to_utf8_but_should_be_ported_to_utf16());
// 8. Run insertNode(img) on range. // 8. Run insertNode(img) on range.
MUST(range->insert_node(img)); MUST(range->insert_node(img));
@ -1690,7 +1690,7 @@ bool command_insert_paragraph_action(DOM::Document& document, Utf16String const&
// 23. Copy all attributes of container to new container. // 23. Copy all attributes of container to new container.
container_element.for_each_attribute([&new_container](FlyString const& name, String const& value) { container_element.for_each_attribute([&new_container](FlyString const& name, String const& value) {
MUST(new_container->set_attribute(name, value)); new_container->set_attribute_value(name, value);
}); });
// 24. If new container has an id attribute, unset it. // 24. If new container has an id attribute, unset it.

View file

@ -1465,7 +1465,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
// 2. Set the color attribute of new parent to the result of applying the rules for serializing simple color // 2. Set the color attribute of new parent to the result of applying the rules for serializing simple color
// values to new value (interpreted as a simple color). // values to new value (interpreted as a simple color).
MUST(new_parent->set_attribute(HTML::AttributeNames::color, new_value_color->to_string_without_alpha())); new_parent->set_attribute_value(HTML::AttributeNames::color, new_value_color->to_string_without_alpha());
} }
} }
@ -1473,7 +1473,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
// ownerDocument of node, then set the face attribute of new parent to new value. // ownerDocument of node, then set the face attribute of new parent to new value.
if (command == CommandNames::fontName) { if (command == CommandNames::fontName) {
new_parent = MUST(DOM::create_element(document, HTML::TagNames::font, Namespace::HTML)); new_parent = MUST(DOM::create_element(document, HTML::TagNames::font, Namespace::HTML));
MUST(new_parent->set_attribute(HTML::AttributeNames::face, *new_value)); new_parent->set_attribute_value(HTML::AttributeNames::face, new_value.value().to_utf8_but_should_be_ported_to_utf16());
} }
} }
@ -1483,7 +1483,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
new_parent = MUST(DOM::create_element(document, HTML::TagNames::a, Namespace::HTML)); new_parent = MUST(DOM::create_element(document, HTML::TagNames::a, Namespace::HTML));
// 2. Set the href attribute of new parent to new value. // 2. Set the href attribute of new parent to new value.
MUST(new_parent->set_attribute(HTML::AttributeNames::href, *new_value)); new_parent->set_attribute_value(HTML::AttributeNames::href, new_value.value().to_utf8_but_should_be_ported_to_utf16());
// 3. Let ancestor be node's parent. // 3. Let ancestor be node's parent.
GC::Ptr<DOM::Node> ancestor = node->parent(); GC::Ptr<DOM::Node> ancestor = node->parent();
@ -1516,7 +1516,7 @@ void force_the_value(GC::Ref<DOM::Node> node, FlyString const& command, Optional
// * xx-large: 6 // * xx-large: 6
// * xxx-large: 7 // * xxx-large: 7
auto size = font_sizes.first_index_of(new_value.value()).value() + 1; auto size = font_sizes.first_index_of(new_value.value()).value() + 1;
MUST(new_parent->set_attribute(HTML::AttributeNames::size, String::number(size))); new_parent->set_attribute_value(HTML::AttributeNames::size, String::number(size));
} }
// 13. If command is "subscript" or "superscript" and new value is "subscript", let new parent be the result of // 13. If command is "subscript" or "superscript" and new value is "subscript", let new parent be the result of
@ -3793,7 +3793,7 @@ GC::Ref<DOM::Element> set_the_tag_name(GC::Ref<DOM::Element> element, FlyString
// 5. Copy all attributes of element to replacement element, in order. // 5. Copy all attributes of element to replacement element, in order.
element->for_each_attribute([&replacement_element](FlyString const& name, String const& value) { element->for_each_attribute([&replacement_element](FlyString const& name, String const& value) {
MUST(replacement_element->set_attribute(name, value)); replacement_element->set_attribute_value(name, value);
}); });
// 6. While element has children, append the first child of element as the last child of replacement element, preserving ranges. // 6. While element has children, append the first child of element as the last child of replacement element, preserving ranges.

View file

@ -48,11 +48,10 @@ String AutocompleteElement::autocomplete() const
return details.value; return details.value;
} }
WebIDL::ExceptionOr<void> AutocompleteElement::set_autocomplete(String const& value) void AutocompleteElement::set_autocomplete(String const& value)
{ {
// The autocomplete IDL attribute [...] on setting, must reflect the content attribute of the same name. // The autocomplete IDL attribute [...] on setting, must reflect the content attribute of the same name.
TRY(autocomplete_element_to_html_element().set_attribute(AttributeNames::autocomplete, value)); autocomplete_element_to_html_element().set_attribute_value(AttributeNames::autocomplete, value);
return {};
} }
enum class Category { enum class Category {

View file

@ -30,7 +30,7 @@ public:
Vector<String> autocomplete_tokens() const; Vector<String> autocomplete_tokens() const;
String autocomplete() const; String autocomplete() const;
WebIDL::ExceptionOr<void> set_autocomplete(String const&); void set_autocomplete(String const&);
// Each input element to which the autocomplete attribute applies [...] has // Each input element to which the autocomplete attribute applies [...] has
// an autofill hint set, an autofill scope, an autofill field name, // an autofill hint set, an autofill scope, an autofill field name,

View file

@ -167,7 +167,7 @@ WebIDL::ExceptionOr<void> DOMStringMap::set_value_of_new_named_property(String c
return WebIDL::InvalidCharacterError::create(realm(), "Name is not a valid attribute local name."_utf16); return WebIDL::InvalidCharacterError::create(realm(), "Name is not a valid attribute local name."_utf16);
// 5. Set an attribute value for the DOMStringMap's associated element using name and value. // 5. Set an attribute value for the DOMStringMap's associated element using name and value.
TRY(m_associated_element->set_attribute(data_name, value)); m_associated_element->set_attribute_value(data_name, value);
return {}; return {};
} }

View file

@ -230,10 +230,10 @@ String FormAssociatedElement::form_action() const
return {}; return {};
} }
WebIDL::ExceptionOr<void> FormAssociatedElement::set_form_action(String const& value) void FormAssociatedElement::set_form_action(String const& value)
{ {
auto& html_element = form_associated_element_to_html_element(); auto& html_element = form_associated_element_to_html_element();
return html_element.set_attribute(HTML::AttributeNames::formaction, value); html_element.set_attribute_value(HTML::AttributeNames::formaction, value);
} }
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity

View file

@ -138,7 +138,7 @@ public:
virtual void clear_algorithm(); virtual void clear_algorithm();
String form_action() const; String form_action() const;
WebIDL::ExceptionOr<void> set_form_action(String const&); void set_form_action(String const&);
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-cva-reportvalidity
bool report_validity(); bool report_validity();

View file

@ -57,9 +57,9 @@ Optional<String> HTMLAnchorElement::hyperlink_element_utils_href() const
return attribute(HTML::AttributeNames::href); return attribute(HTML::AttributeNames::href);
} }
WebIDL::ExceptionOr<void> HTMLAnchorElement::set_hyperlink_element_utils_href(String href) void HTMLAnchorElement::set_hyperlink_element_utils_href(String href)
{ {
return set_attribute(HTML::AttributeNames::href, move(href)); set_attribute_value(HTML::AttributeNames::href, move(href));
} }
Optional<String> HTMLAnchorElement::hyperlink_element_utils_referrerpolicy() const Optional<String> HTMLAnchorElement::hyperlink_element_utils_referrerpolicy() const

View file

@ -55,7 +55,7 @@ private:
virtual DOM::Document& hyperlink_element_utils_document() override { return document(); } virtual DOM::Document& hyperlink_element_utils_document() override { return document(); }
virtual DOM::Element& hyperlink_element_utils_element() override { return *this; } virtual DOM::Element& hyperlink_element_utils_element() override { return *this; }
virtual Optional<String> hyperlink_element_utils_href() const override; virtual Optional<String> hyperlink_element_utils_href() const override;
virtual WebIDL::ExceptionOr<void> set_hyperlink_element_utils_href(String) override; virtual void set_hyperlink_element_utils_href(String) override;
virtual Optional<String> hyperlink_element_utils_referrerpolicy() const override; virtual Optional<String> hyperlink_element_utils_referrerpolicy() const override;
virtual bool hyperlink_element_utils_is_html_anchor_element() const final { return true; } virtual bool hyperlink_element_utils_is_html_anchor_element() const final { return true; }
virtual bool hyperlink_element_utils_is_connected() const final { return is_connected(); } virtual bool hyperlink_element_utils_is_connected() const final { return is_connected(); }

View file

@ -59,9 +59,9 @@ Optional<String> HTMLAreaElement::hyperlink_element_utils_href() const
return attribute(HTML::AttributeNames::href); return attribute(HTML::AttributeNames::href);
} }
WebIDL::ExceptionOr<void> HTMLAreaElement::set_hyperlink_element_utils_href(String href) void HTMLAreaElement::set_hyperlink_element_utils_href(String href)
{ {
return set_attribute(HTML::AttributeNames::href, move(href)); set_attribute_value(HTML::AttributeNames::href, move(href));
} }
Optional<String> HTMLAreaElement::hyperlink_element_utils_referrerpolicy() const Optional<String> HTMLAreaElement::hyperlink_element_utils_referrerpolicy() const

View file

@ -38,7 +38,7 @@ private:
virtual DOM::Document& hyperlink_element_utils_document() override { return document(); } virtual DOM::Document& hyperlink_element_utils_document() override { return document(); }
virtual DOM::Element& hyperlink_element_utils_element() override { return *this; } virtual DOM::Element& hyperlink_element_utils_element() override { return *this; }
virtual Optional<String> hyperlink_element_utils_href() const override; virtual Optional<String> hyperlink_element_utils_href() const override;
virtual WebIDL::ExceptionOr<void> set_hyperlink_element_utils_href(String) override; virtual void set_hyperlink_element_utils_href(String) override;
virtual Optional<String> hyperlink_element_utils_referrerpolicy() const override; virtual Optional<String> hyperlink_element_utils_referrerpolicy() const override;
virtual bool hyperlink_element_utils_is_html_anchor_element() const override { return false; } virtual bool hyperlink_element_utils_is_html_anchor_element() const override { return false; }
virtual bool hyperlink_element_utils_is_connected() const override { return is_connected(); } virtual bool hyperlink_element_utils_is_connected() const override { return is_connected(); }

View file

@ -122,10 +122,10 @@ String HTMLBaseElement::href() const
} }
// https://html.spec.whatwg.org/multipage/semantics.html#dom-base-href // https://html.spec.whatwg.org/multipage/semantics.html#dom-base-href
WebIDL::ExceptionOr<void> HTMLBaseElement::set_href(String const& href) void HTMLBaseElement::set_href(String const& href)
{ {
// The href IDL attribute, on setting, must set the href content attribute to the given new value. // The href IDL attribute, on setting, must set the href content attribute to the given new value.
return set_attribute(AttributeNames::href, href); set_attribute_value(AttributeNames::href, href);
} }
} }

View file

@ -18,7 +18,7 @@ public:
virtual ~HTMLBaseElement() override; virtual ~HTMLBaseElement() override;
String href() const; String href() const;
WebIDL::ExceptionOr<void> set_href(String const& href); void set_href(String const& href);
URL::URL const& frozen_base_url() const { return m_frozen_base_url; } URL::URL const& frozen_base_url() const { return m_frozen_base_url; }

View file

@ -93,10 +93,10 @@ String HTMLButtonElement::type_for_bindings() const
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-button-type // https://html.spec.whatwg.org/multipage/form-elements.html#dom-button-type
WebIDL::ExceptionOr<void> HTMLButtonElement::set_type_for_bindings(String const& type) void HTMLButtonElement::set_type_for_bindings(String const& type)
{ {
// The type setter steps are to set the type content attribute to the given value. // The type setter steps are to set the type content attribute to the given value.
return set_attribute(HTML::AttributeNames::type, type); set_attribute_value(HTML::AttributeNames::type, type);
} }
void HTMLButtonElement::form_associated_element_attribute_changed(FlyString const& name, Optional<String> const&, Optional<String> const& value, Optional<FlyString> const& namespace_) void HTMLButtonElement::form_associated_element_attribute_changed(FlyString const& name, Optional<String> const&, Optional<String> const& value, Optional<FlyString> const& namespace_)
@ -339,9 +339,9 @@ String HTMLButtonElement::command() const
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:dom-button-command-2 // https://html.spec.whatwg.org/multipage/form-elements.html#the-button-element:dom-button-command-2
WebIDL::ExceptionOr<void> HTMLButtonElement::set_command(String const& value) void HTMLButtonElement::set_command(String const& value)
{ {
return set_attribute(AttributeNames::command, value); set_attribute_value(AttributeNames::command, value);
} }
} }

View file

@ -41,7 +41,7 @@ public:
TypeAttributeState type_state() const; TypeAttributeState type_state() const;
String type_for_bindings() const; String type_for_bindings() const;
WebIDL::ExceptionOr<void> set_type_for_bindings(String const&); void set_type_for_bindings(String const&);
virtual void form_associated_element_attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override; virtual void form_associated_element_attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
@ -81,7 +81,7 @@ public:
virtual void activation_behavior(DOM::Event const&) override; virtual void activation_behavior(DOM::Event const&) override;
String command() const; String command() const;
WebIDL::ExceptionOr<void> set_command(String const&); void set_command(String const&);
GC::Ptr<DOM::Element> command_for_element() { return m_command_for_element; } GC::Ptr<DOM::Element> command_for_element() { return m_command_for_element; }
void set_command_for_element(GC::Ptr<DOM::Element> value) { m_command_for_element = value; } void set_command_for_element(GC::Ptr<DOM::Element> value) { m_command_for_element = value; }

View file

@ -26,7 +26,7 @@ interface HTMLButtonElement : HTMLElement {
[CEReactions, Reflect=formtarget] attribute DOMString formTarget; [CEReactions, Reflect=formtarget] attribute DOMString formTarget;
[CEReactions, Reflect] attribute DOMString name; [CEReactions, Reflect] attribute DOMString name;
[CEReactions, ImplementedAs=type_for_bindings, Enumerated=ButtonTypeState] attribute DOMString type; [CEReactions, ImplementedAs=type_for_bindings, Enumerated=ButtonTypeState] attribute DOMString type;
[CEReactions, Reflect] attribute Utf16DOMString value; [CEReactions, Reflect] attribute DOMString value;
readonly attribute boolean willValidate; readonly attribute boolean willValidate;
readonly attribute ValidityState validity; readonly attribute ValidityState validity;

View file

@ -162,26 +162,24 @@ void HTMLCanvasElement::notify_context_about_canvas_size_change()
}); });
} }
WebIDL::ExceptionOr<void> HTMLCanvasElement::set_width(unsigned value) void HTMLCanvasElement::set_width(unsigned value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 300; value = 300;
TRY(set_attribute(HTML::AttributeNames::width, String::number(value))); set_attribute_value(HTML::AttributeNames::width, String::number(value));
notify_context_about_canvas_size_change(); notify_context_about_canvas_size_change();
reset_context_to_default_state(); reset_context_to_default_state();
return {};
} }
WebIDL::ExceptionOr<void> HTMLCanvasElement::set_height(WebIDL::UnsignedLong value) void HTMLCanvasElement::set_height(WebIDL::UnsignedLong value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 150; value = 150;
TRY(set_attribute(HTML::AttributeNames::height, String::number(value))); set_attribute_value(HTML::AttributeNames::height, String::number(value));
notify_context_about_canvas_size_change(); notify_context_about_canvas_size_change();
reset_context_to_default_state(); reset_context_to_default_state();
return {};
} }
void HTMLCanvasElement::attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) void HTMLCanvasElement::attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_)

View file

@ -34,8 +34,8 @@ public:
WebIDL::UnsignedLong width() const; WebIDL::UnsignedLong width() const;
WebIDL::UnsignedLong height() const; WebIDL::UnsignedLong height() const;
WebIDL::ExceptionOr<void> set_width(WebIDL::UnsignedLong); void set_width(WebIDL::UnsignedLong);
WebIDL::ExceptionOr<void> set_height(WebIDL::UnsignedLong); void set_height(WebIDL::UnsignedLong);
virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override; virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;

View file

@ -243,7 +243,7 @@ WebIDL::ExceptionOr<void> HTMLDetailsElement::create_shadow_tree_if_needed()
// The third child element is either a link or style element with the following styles for the default summary: // The third child element is either a link or style element with the following styles for the default summary:
auto style = TRY(DOM::create_element(document(), HTML::TagNames::style, Namespace::HTML)); auto style = TRY(DOM::create_element(document(), HTML::TagNames::style, Namespace::HTML));
MUST(style->set_text_content(R"~~~( auto style_text = realm.create<DOM::Text>(document(), R"~~~(
:host summary { :host summary {
display: list-item; display: list-item;
counter-increment: list-item 0; counter-increment: list-item 0;
@ -252,7 +252,8 @@ WebIDL::ExceptionOr<void> HTMLDetailsElement::create_shadow_tree_if_needed()
:host([open]) summary { :host([open]) summary {
list-style-type: disclosure-open; list-style-type: disclosure-open;
} }
)~~~"_utf16)); )~~~"_utf16);
MUST(style->append_child(style_text));
MUST(shadow_root->append_child(style)); MUST(shadow_root->append_child(style));
m_summary_slot = static_cast<HTML::HTMLSlotElement&>(*summary_slot); m_summary_slot = static_cast<HTML::HTMLSlotElement&>(*summary_slot);
@ -300,14 +301,14 @@ void HTMLDetailsElement::update_shadow_tree_style()
return; return;
if (has_attribute(HTML::AttributeNames::open)) { if (has_attribute(HTML::AttributeNames::open)) {
MUST(m_descendants_slot->set_attribute(HTML::AttributeNames::style, R"~~~( m_descendants_slot->set_attribute_value(HTML::AttributeNames::style, R"~~~(
display: block; display: block;
)~~~"_string)); )~~~"_string);
} else { } else {
MUST(m_descendants_slot->set_attribute(HTML::AttributeNames::style, R"~~~( m_descendants_slot->set_attribute_value(HTML::AttributeNames::style, R"~~~(
display: block; display: block;
content-visibility: hidden; content-visibility: hidden;
)~~~"_string)); )~~~"_string);
} }
shadow_root()->set_needs_layout_tree_update(true, DOM::SetNeedsLayoutTreeUpdateReason::DetailsElementOpenedOrClosed); shadow_root()->set_needs_layout_tree_update(true, DOM::SetNeedsLayoutTreeUpdateReason::DetailsElementOpenedOrClosed);

View file

@ -133,7 +133,7 @@ WebIDL::ExceptionOr<void> HTMLDialogElement::show()
queue_a_dialog_toggle_event_task("closed"_string, "open"_string, nullptr); queue_a_dialog_toggle_event_task("closed"_string, "open"_string, nullptr);
// 6. Add an open attribute to this, whose value is the empty string. // 6. Add an open attribute to this, whose value is the empty string.
TRY(set_attribute(AttributeNames::open, String {})); set_attribute_value(AttributeNames::open, String {});
// 7. Assert: this's node document's open dialogs list does not contain this. // 7. Assert: this's node document's open dialogs list does not contain this.
VERIFY(!m_document->open_dialogs_list().contains_slow(GC::Ref(*this))); VERIFY(!m_document->open_dialogs_list().contains_slow(GC::Ref(*this)));
@ -230,7 +230,7 @@ WebIDL::ExceptionOr<void> HTMLDialogElement::show_a_modal_dialog(HTMLDialogEleme
subject.queue_a_dialog_toggle_event_task("closed"_string, "open"_string, source); subject.queue_a_dialog_toggle_event_task("closed"_string, "open"_string, source);
// 11. Add an open attribute to subject, whose value is the empty string. // 11. Add an open attribute to subject, whose value is the empty string.
TRY(subject.set_attribute(AttributeNames::open, String {})); subject.set_attribute_value(AttributeNames::open, String {});
// 12. Set is modal of subject to true. // 12. Set is modal of subject to true.
subject.set_is_modal(true); subject.set_is_modal(true);

View file

@ -122,9 +122,9 @@ void HTMLElement::set_translate(bool new_value)
// On setting, it must set the content attribute's value to "yes" if the new value is true, and set the content // On setting, it must set the content attribute's value to "yes" if the new value is true, and set the content
// attribute's value to "no" otherwise. // attribute's value to "no" otherwise.
if (new_value) if (new_value)
MUST(set_attribute(HTML::AttributeNames::translate, "yes"_string)); set_attribute_value(HTML::AttributeNames::translate, "yes"_string);
else else
MUST(set_attribute(HTML::AttributeNames::translate, "no"_string)); set_attribute_value(HTML::AttributeNames::translate, "no"_string);
} }
// https://html.spec.whatwg.org/multipage/dom.html#dom-dir // https://html.spec.whatwg.org/multipage/dom.html#dom-dir
@ -144,7 +144,7 @@ StringView HTMLElement::dir() const
void HTMLElement::set_dir(String const& dir) void HTMLElement::set_dir(String const& dir)
{ {
MUST(set_attribute(HTML::AttributeNames::dir, dir)); set_attribute_value(HTML::AttributeNames::dir, dir);
} }
bool HTMLElement::is_focusable() const bool HTMLElement::is_focusable() const
@ -183,15 +183,15 @@ WebIDL::ExceptionOr<void> HTMLElement::set_content_editable(StringView content_e
return {}; return {};
} }
if (content_editable.equals_ignoring_ascii_case("true"sv)) { if (content_editable.equals_ignoring_ascii_case("true"sv)) {
MUST(set_attribute(HTML::AttributeNames::contenteditable, "true"_string)); set_attribute_value(HTML::AttributeNames::contenteditable, "true"_string);
return {}; return {};
} }
if (content_editable.equals_ignoring_ascii_case("plaintext-only"sv)) { if (content_editable.equals_ignoring_ascii_case("plaintext-only"sv)) {
MUST(set_attribute(HTML::AttributeNames::contenteditable, "plaintext-only"_string)); set_attribute_value(HTML::AttributeNames::contenteditable, "plaintext-only"_string);
return {}; return {};
} }
if (content_editable.equals_ignoring_ascii_case("false"sv)) { if (content_editable.equals_ignoring_ascii_case("false"sv)) {
MUST(set_attribute(HTML::AttributeNames::contenteditable, "false"_string)); set_attribute_value(HTML::AttributeNames::contenteditable, "false"_string);
return {}; return {};
} }
return WebIDL::SyntaxError::create(realm(), "Invalid contentEditable value, must be 'true', 'false', 'plaintext-only' or 'inherit'"_utf16); return WebIDL::SyntaxError::create(realm(), "Invalid contentEditable value, must be 'true', 'false', 'plaintext-only' or 'inherit'"_utf16);
@ -879,7 +879,7 @@ void HTMLElement::set_hidden(Variant<bool, double, String> const& given_value)
if (given_value.has<String>()) { if (given_value.has<String>()) {
auto const& string = given_value.get<String>(); auto const& string = given_value.get<String>();
if (string.equals_ignoring_ascii_case("until-found"sv)) { if (string.equals_ignoring_ascii_case("until-found"sv)) {
MUST(set_attribute(HTML::AttributeNames::hidden, "until-found"_string)); set_attribute_value(HTML::AttributeNames::hidden, "until-found"_string);
return; return;
} }
// 3. Otherwise, if the given value is the empty string, then remove the hidden attribute. // 3. Otherwise, if the given value is the empty string, then remove the hidden attribute.
@ -910,7 +910,7 @@ void HTMLElement::set_hidden(Variant<bool, double, String> const& given_value)
} }
} }
// 7. Otherwise, set the hidden attribute to the empty string. // 7. Otherwise, set the hidden attribute to the empty string.
MUST(set_attribute(HTML::AttributeNames::hidden, ""_string)); set_attribute_value(HTML::AttributeNames::hidden, ""_string);
} }
// https://html.spec.whatwg.org/multipage/interaction.html#dom-click // https://html.spec.whatwg.org/multipage/interaction.html#dom-click
@ -1189,15 +1189,14 @@ Optional<String> HTMLElement::popover() const
} }
// https://html.spec.whatwg.org/multipage/popover.html#dom-popover // https://html.spec.whatwg.org/multipage/popover.html#dom-popover
WebIDL::ExceptionOr<void> HTMLElement::set_popover(Optional<String> value) void HTMLElement::set_popover(Optional<String> value)
{ {
// FIXME: This should probably be `Reflect` in the IDL. // FIXME: This should probably be `Reflect` in the IDL.
// The popover IDL attribute must reflect the popover attribute, limited to only known values. // The popover IDL attribute must reflect the popover attribute, limited to only known values.
if (value.has_value()) if (value.has_value())
return set_attribute(HTML::AttributeNames::popover, value.release_value()); set_attribute_value(HTML::AttributeNames::popover, value.release_value());
else
remove_attribute(HTML::AttributeNames::popover); remove_attribute(HTML::AttributeNames::popover);
return {};
} }
void HTMLElement::adjust_computed_style(CSS::ComputedProperties& style) void HTMLElement::adjust_computed_style(CSS::ComputedProperties& style)
@ -2143,6 +2142,11 @@ bool HTMLElement::draggable() const
return false; return false;
} }
void HTMLElement::set_draggable(bool draggable)
{
set_attribute_value(HTML::AttributeNames::draggable, draggable ? "true"_string : "false"_string);
}
// https://html.spec.whatwg.org/multipage/interaction.html#dom-spellcheck // https://html.spec.whatwg.org/multipage/interaction.html#dom-spellcheck
bool HTMLElement::spellcheck() const bool HTMLElement::spellcheck() const
{ {
@ -2200,9 +2204,9 @@ void HTMLElement::set_spellcheck(bool spellcheck)
{ {
// On setting, if the new value is true, then the element's spellcheck content attribute must be set to "true", otherwise it must be set to "false". // On setting, if the new value is true, then the element's spellcheck content attribute must be set to "true", otherwise it must be set to "false".
if (spellcheck) if (spellcheck)
MUST(set_attribute(HTML::AttributeNames::spellcheck, "true"_string)); set_attribute_value(HTML::AttributeNames::spellcheck, "true"_string);
else else
MUST(set_attribute(HTML::AttributeNames::spellcheck, "false"_string)); set_attribute_value(HTML::AttributeNames::spellcheck, "false"_string);
} }
// https://html.spec.whatwg.org/multipage/interaction.html#dom-writingsuggestions // https://html.spec.whatwg.org/multipage/interaction.html#dom-writingsuggestions
@ -2239,7 +2243,7 @@ String HTMLElement::writing_suggestions() const
void HTMLElement::set_writing_suggestions(String const& given_value) void HTMLElement::set_writing_suggestions(String const& given_value)
{ {
// 1. Set this's writingsuggestions content attribute to the given value. // 1. Set this's writingsuggestions content attribute to the given value.
MUST(set_attribute(HTML::AttributeNames::writingsuggestions, given_value)); set_attribute_value(HTML::AttributeNames::writingsuggestions, given_value);
} }
// https://html.spec.whatwg.org/multipage/interaction.html#own-autocapitalization-hint // https://html.spec.whatwg.org/multipage/interaction.html#own-autocapitalization-hint
@ -2332,7 +2336,7 @@ String HTMLElement::autocapitalize() const
void HTMLElement::set_autocapitalize(String const& given_value) void HTMLElement::set_autocapitalize(String const& given_value)
{ {
// The autocapitalize setter steps are to set the autocapitalize content attribute to the given value. // The autocapitalize setter steps are to set the autocapitalize content attribute to the given value.
MUST(set_attribute(HTML::AttributeNames::autocapitalize, given_value)); set_attribute_value(HTML::AttributeNames::autocapitalize, given_value);
} }
// https://html.spec.whatwg.org/multipage/interaction.html#used-autocorrection-state // https://html.spec.whatwg.org/multipage/interaction.html#used-autocorrection-state
@ -2390,9 +2394,9 @@ void HTMLElement::set_autocorrect(bool given_value)
{ {
// The setter steps are: if the given value is true, then the element's autocorrect attribute must be set to "on"; otherwise it must be set to "off". // The setter steps are: if the given value is true, then the element's autocorrect attribute must be set to "on"; otherwise it must be set to "off".
if (given_value) if (given_value)
MUST(set_attribute(HTML::AttributeNames::autocorrect, "on"_string)); set_attribute_value(HTML::AttributeNames::autocorrect, "on"_string);
else else
MUST(set_attribute(HTML::AttributeNames::autocorrect, "off"_string)); set_attribute_value(HTML::AttributeNames::autocorrect, "off"_string);
} }
} }

View file

@ -158,7 +158,7 @@ public:
WebIDL::ExceptionOr<GC::Ref<ElementInternals>> attach_internals(); WebIDL::ExceptionOr<GC::Ref<ElementInternals>> attach_internals();
WebIDL::ExceptionOr<void> set_popover(Optional<String> value); void set_popover(Optional<String> value);
Optional<String> popover() const; Optional<String> popover() const;
Optional<String> opened_in_popover_mode() const { return m_opened_in_popover_mode; } Optional<String> opened_in_popover_mode() const { return m_opened_in_popover_mode; }
@ -186,7 +186,7 @@ public:
bool is_inert() const { return m_inert; } bool is_inert() const { return m_inert; }
bool draggable() const; bool draggable() const;
void set_draggable(bool draggable) { MUST(set_attribute(HTML::AttributeNames::draggable, draggable ? "true"_string : "false"_string)); } void set_draggable(bool draggable);
virtual bool is_valid_invoker_command(String&) { return false; } virtual bool is_valid_invoker_command(String&) { return false; }
virtual void invoker_command_steps(DOM::Element&, String&) { } virtual void invoker_command_steps(DOM::Element&, String&) { }

View file

@ -692,10 +692,10 @@ GC::Ref<DOM::DOMTokenList> HTMLFormElement::rel_list()
} }
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-method // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-method
WebIDL::ExceptionOr<void> HTMLFormElement::set_method(String const& method) void HTMLFormElement::set_method(String const& method)
{ {
// The method and enctype IDL attributes must reflect the respective content attributes of the same name, limited to only known values. // The method and enctype IDL attributes must reflect the respective content attributes of the same name, limited to only known values.
return set_attribute(AttributeNames::method, method); set_attribute_value(AttributeNames::method, method);
} }
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-action // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-action
@ -715,9 +715,9 @@ String HTMLFormElement::action() const
} }
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-action // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-action
WebIDL::ExceptionOr<void> HTMLFormElement::set_action(String const& value) void HTMLFormElement::set_action(String const& value)
{ {
return set_attribute(AttributeNames::action, value); set_attribute_value(AttributeNames::action, value);
} }
void HTMLFormElement::attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) void HTMLFormElement::attribute_changed(FlyString const& name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_)

View file

@ -96,12 +96,12 @@ public:
bool constructing_entry_list() const { return m_constructing_entry_list; } bool constructing_entry_list() const { return m_constructing_entry_list; }
void set_constructing_entry_list(bool value) { m_constructing_entry_list = value; } void set_constructing_entry_list(bool value) { m_constructing_entry_list = value; }
WebIDL::ExceptionOr<void> set_method(String const&); void set_method(String const&);
GC::Ref<DOM::DOMTokenList> rel_list(); GC::Ref<DOM::DOMTokenList> rel_list();
String action() const; String action() const;
WebIDL::ExceptionOr<void> set_action(String const&); void set_action(String const&);
FormAssociatedElement* default_button() const; FormAssociatedElement* default_button() const;

View file

@ -446,17 +446,17 @@ String HTMLHyperlinkElementUtils::href() const
} }
// https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-href // https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-href
WebIDL::ExceptionOr<void> HTMLHyperlinkElementUtils::set_href(String href) void HTMLHyperlinkElementUtils::set_href(String href)
{ {
// The href attribute's setter must set this element's href content attribute's value to the given value. // The href attribute's setter must set this element's href content attribute's value to the given value.
return set_hyperlink_element_utils_href(move(href)); set_hyperlink_element_utils_href(move(href));
} }
// https://html.spec.whatwg.org/multipage/links.html#update-href // https://html.spec.whatwg.org/multipage/links.html#update-href
void HTMLHyperlinkElementUtils::update_href() void HTMLHyperlinkElementUtils::update_href()
{ {
// To update href, set the element's href content attribute's value to the element's url, serialized. // To update href, set the element's href content attribute's value to the element's url, serialized.
MUST(set_hyperlink_element_utils_href(m_url->serialize())); set_hyperlink_element_utils_href(m_url->serialize());
} }
bool HTMLHyperlinkElementUtils::cannot_navigate() const bool HTMLHyperlinkElementUtils::cannot_navigate() const

View file

@ -21,7 +21,7 @@ public:
String origin() const; String origin() const;
String href() const; String href() const;
WebIDL::ExceptionOr<void> set_href(String); void set_href(String);
String protocol() const; String protocol() const;
void set_protocol(StringView); void set_protocol(StringView);
@ -54,7 +54,7 @@ protected:
virtual DOM::Document& hyperlink_element_utils_document() = 0; virtual DOM::Document& hyperlink_element_utils_document() = 0;
virtual DOM::Element& hyperlink_element_utils_element() = 0; virtual DOM::Element& hyperlink_element_utils_element() = 0;
virtual Optional<String> hyperlink_element_utils_href() const = 0; virtual Optional<String> hyperlink_element_utils_href() const = 0;
virtual WebIDL::ExceptionOr<void> set_hyperlink_element_utils_href(String) = 0; virtual void set_hyperlink_element_utils_href(String) = 0;
virtual Optional<String> hyperlink_element_utils_referrerpolicy() const = 0; virtual Optional<String> hyperlink_element_utils_referrerpolicy() const = 0;
virtual bool hyperlink_element_utils_is_html_anchor_element() const = 0; virtual bool hyperlink_element_utils_is_html_anchor_element() const = 0;
virtual bool hyperlink_element_utils_is_connected() const = 0; virtual bool hyperlink_element_utils_is_connected() const = 0;

View file

@ -19,8 +19,8 @@
#include <LibWeb/HTML/Parser/HTMLParser.h> #include <LibWeb/HTML/Parser/HTMLParser.h>
#include <LibWeb/HTML/TraversableNavigable.h> #include <LibWeb/HTML/TraversableNavigable.h>
#include <LibWeb/Layout/NavigableContainerViewport.h> #include <LibWeb/Layout/NavigableContainerViewport.h>
#include <LibWeb/TrustedTypes/TrustedTypePolicy.h>
#include <LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h> #include <LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h>
#include <LibWeb/TrustedTypes/TrustedTypePolicy.h>
namespace Web::HTML { namespace Web::HTML {

View file

@ -242,11 +242,11 @@ WebIDL::UnsignedLong HTMLImageElement::width() const
return 0; return 0;
} }
WebIDL::ExceptionOr<void> HTMLImageElement::set_width(WebIDL::UnsignedLong width) void HTMLImageElement::set_width(WebIDL::UnsignedLong width)
{ {
if (width > 2147483647) if (width > 2147483647)
width = 0; width = 0;
return set_attribute(HTML::AttributeNames::width, String::number(width)); set_attribute_value(HTML::AttributeNames::width, String::number(width));
} }
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-height // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-height
@ -273,11 +273,11 @@ WebIDL::UnsignedLong HTMLImageElement::height() const
return 0; return 0;
} }
WebIDL::ExceptionOr<void> HTMLImageElement::set_height(WebIDL::UnsignedLong height) void HTMLImageElement::set_height(WebIDL::UnsignedLong height)
{ {
if (height > 2147483647) if (height > 2147483647)
height = 0; height = 0;
return set_attribute(HTML::AttributeNames::height, String::number(height)); set_attribute_value(HTML::AttributeNames::height, String::number(height));
} }
// https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-naturalwidth // https://html.spec.whatwg.org/multipage/embedded-content.html#dom-img-naturalwidth

View file

@ -53,10 +53,10 @@ public:
virtual RefPtr<Gfx::ImmutableBitmap> default_image_bitmap_sized(Gfx::IntSize) const override; virtual RefPtr<Gfx::ImmutableBitmap> default_image_bitmap_sized(Gfx::IntSize) const override;
WebIDL::UnsignedLong width() const; WebIDL::UnsignedLong width() const;
WebIDL::ExceptionOr<void> set_width(WebIDL::UnsignedLong); void set_width(WebIDL::UnsignedLong);
WebIDL::UnsignedLong height() const; WebIDL::UnsignedLong height() const;
WebIDL::ExceptionOr<void> set_height(WebIDL::UnsignedLong); void set_height(WebIDL::UnsignedLong);
unsigned natural_width() const; unsigned natural_width() const;
unsigned natural_height() const; unsigned natural_height() const;

View file

@ -719,7 +719,7 @@ WebIDL::ExceptionOr<void> HTMLInputElement::set_value(Utf16String const& value)
case ValueAttributeMode::Default: case ValueAttributeMode::Default:
case ValueAttributeMode::DefaultOn: case ValueAttributeMode::DefaultOn:
// On setting, set the value of the element's value content attribute to the new value. // On setting, set the value of the element's value content attribute to the new value.
TRY(set_attribute(HTML::AttributeNames::value, value)); set_attribute_value(HTML::AttributeNames::value, value.to_utf8_but_should_be_ported_to_utf16());
break; break;
// https://html.spec.whatwg.org/multipage/input.html#dom-input-value-filename // https://html.spec.whatwg.org/multipage/input.html#dom-input-value-filename
@ -1031,7 +1031,7 @@ void HTMLInputElement::create_button_input_shadow_tree()
auto shadow_root = realm().create<DOM::ShadowRoot>(document(), *this, Bindings::ShadowRootMode::Closed); auto shadow_root = realm().create<DOM::ShadowRoot>(document(), *this, Bindings::ShadowRootMode::Closed);
set_shadow_root(shadow_root); set_shadow_root(shadow_root);
auto text_container = MUST(DOM::create_element(document(), HTML::TagNames::span, Namespace::HTML)); auto text_container = MUST(DOM::create_element(document(), HTML::TagNames::span, Namespace::HTML));
MUST(text_container->set_attribute(HTML::AttributeNames::style, "display: inline-block; pointer-events: none;"_string)); text_container->set_attribute_value(HTML::AttributeNames::style, "display: inline-block; pointer-events: none;"_string);
m_text_node = realm().create<DOM::Text>(document(), button_label()); m_text_node = realm().create<DOM::Text>(document(), button_label());
MUST(text_container->append_child(*m_text_node)); MUST(text_container->append_child(*m_text_node));
@ -1079,10 +1079,9 @@ void HTMLInputElement::create_text_input_shadow_tree()
} }
MUST(element->append_child(*m_inner_text_element)); MUST(element->append_child(*m_inner_text_element));
m_text_node = realm().create<DOM::Text>(document(), Utf16String {}); m_text_node = realm().create<DOM::Text>(document(), m_value);
if (type_state() == TypeAttributeState::Password) if (type_state() == TypeAttributeState::Password)
m_text_node->set_is_password_input({}, true); m_text_node->set_is_password_input({}, true);
MUST(m_text_node->set_text_content(m_value));
handle_maxlength_attribute(); handle_maxlength_attribute();
MUST(m_inner_text_element->append_child(*m_text_node)); MUST(m_inner_text_element->append_child(*m_text_node));
@ -1099,11 +1098,22 @@ void HTMLInputElement::create_text_input_shadow_tree()
// Up button // Up button
auto up_button = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML)); auto up_button = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML));
// FIXME: This cursor property doesn't work // FIXME: This cursor property doesn't work
MUST(up_button->set_attribute(HTML::AttributeNames::style, R"~~~( up_button->set_attribute_value(HTML::AttributeNames::style, R"~~~(
padding: 0; padding: 0;
cursor: default; cursor: default;
)~~~"_string)); )~~~"_string);
MUST(up_button->set_inner_html("<svg style=\"width: 1em; height: 1em;\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z\" /></svg>"_utf16));
auto up_button_svg = MUST(DOM::create_element(document(), SVG::TagNames::svg, Namespace::SVG));
up_button_svg->set_attribute_value(HTML::AttributeNames::style, "width: 1em; height: 1em;"_string);
up_button_svg->set_attribute_value(SVG::AttributeNames::xmlns, Namespace::SVG.to_string());
up_button_svg->set_attribute_value(SVG::AttributeNames::viewBox, "0 0 24 24"_string);
MUST(up_button->append_child(up_button_svg));
auto up_button_svg_path = MUST(DOM::create_element(document(), SVG::TagNames::path, Namespace::SVG));
up_button_svg_path->set_attribute_value(SVG::AttributeNames::fill, "currentColor"_string);
up_button_svg_path->set_attribute_value(SVG::AttributeNames::d, "M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z"_string);
MUST(up_button_svg->append_child(up_button_svg_path));
MUST(element->append_child(up_button)); MUST(element->append_child(up_button));
auto mouseup_callback_function = JS::NativeFunction::create( auto mouseup_callback_function = JS::NativeFunction::create(
@ -1131,11 +1141,22 @@ void HTMLInputElement::create_text_input_shadow_tree()
// Down button // Down button
auto down_button = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML)); auto down_button = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML));
MUST(down_button->set_attribute(HTML::AttributeNames::style, R"~~~( down_button->set_attribute_value(HTML::AttributeNames::style, R"~~~(
padding: 0; padding: 0;
cursor: default; cursor: default;
)~~~"_string)); )~~~"_string);
MUST(down_button->set_inner_html("<svg style=\"width: 1em; height: 1em;\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"currentColor\" d=\"M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z\" /></svg>"_utf16));
auto down_button_svg = MUST(DOM::create_element(document(), SVG::TagNames::svg, Namespace::SVG));
down_button_svg->set_attribute_value(HTML::AttributeNames::style, "width: 1em; height: 1em;"_string);
down_button_svg->set_attribute_value(SVG::AttributeNames::xmlns, Namespace::SVG.to_string());
down_button_svg->set_attribute_value(SVG::AttributeNames::viewBox, "0 0 24 24"_string);
MUST(down_button->append_child(down_button_svg));
auto down_button_svg_path = MUST(DOM::create_element(document(), SVG::TagNames::path, Namespace::SVG));
down_button_svg_path->set_attribute_value(SVG::AttributeNames::fill, "currentColor"_string);
down_button_svg_path->set_attribute_value(SVG::AttributeNames::d, "M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"_string);
MUST(down_button_svg->append_child(down_button_svg_path));
MUST(element->append_child(down_button)); MUST(element->append_child(down_button));
auto down_callback_function = JS::NativeFunction::create( auto down_callback_function = JS::NativeFunction::create(
@ -1160,21 +1181,21 @@ void HTMLInputElement::create_color_input_shadow_tree()
auto color = value_sanitization_algorithm(m_value); auto color = value_sanitization_algorithm(m_value);
auto border = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors(); auto border = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
MUST(border->set_attribute(HTML::AttributeNames::style, R"~~~( border->set_attribute_value(HTML::AttributeNames::style, R"~~~(
width: fit-content; width: fit-content;
height: fit-content; height: fit-content;
padding: 4px; padding: 4px;
border: 1px solid ButtonBorder; border: 1px solid ButtonBorder;
background-color: ButtonFace; background-color: ButtonFace;
)~~~"_string)); )~~~"_string);
m_color_well_element = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors(); m_color_well_element = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
MUST(m_color_well_element->set_attribute(HTML::AttributeNames::style, R"~~~( m_color_well_element->set_attribute_value(HTML::AttributeNames::style, R"~~~(
width: 32px; width: 32px;
height: 16px; height: 16px;
border: 1px solid ButtonBorder; border: 1px solid ButtonBorder;
box-sizing: border-box; box-sizing: border-box;
)~~~"_string)); )~~~"_string);
MUST(m_color_well_element->style_for_bindings()->set_property(CSS::PropertyID::BackgroundColor, color.to_utf8_but_should_be_ported_to_utf16())); MUST(m_color_well_element->style_for_bindings()->set_property(CSS::PropertyID::BackgroundColor, color.to_utf8_but_should_be_ported_to_utf16()));
MUST(border->append_child(*m_color_well_element)); MUST(border->append_child(*m_color_well_element));
@ -1200,7 +1221,7 @@ void HTMLInputElement::create_file_input_shadow_tree()
m_file_button->set_use_pseudo_element(CSS::PseudoElement::FileSelectorButton); m_file_button->set_use_pseudo_element(CSS::PseudoElement::FileSelectorButton);
m_file_label = DOM::create_element(document(), HTML::TagNames::label, Namespace::HTML).release_value_but_fixme_should_propagate_errors(); m_file_label = DOM::create_element(document(), HTML::TagNames::label, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
MUST(m_file_label->set_attribute(HTML::AttributeNames::style, "padding-left: 4px;"_string)); m_file_label->set_attribute_value(HTML::AttributeNames::style, "padding-left: 4px;"_string);
auto on_button_click = [this](JS::VM&) { auto on_button_click = [this](JS::VM&) {
show_the_picker_if_applicable(*this); show_the_picker_if_applicable(*this);
@ -1225,15 +1246,15 @@ void HTMLInputElement::update_file_input_shadow_tree()
return; return;
auto files_label = has_attribute(HTML::AttributeNames::multiple) ? "files"sv : "file"sv; auto files_label = has_attribute(HTML::AttributeNames::multiple) ? "files"sv : "file"sv;
MUST(m_file_button->set_text_content(Utf16String::formatted("Select {}...", files_label))); m_file_button->string_replace_all(Utf16String::formatted("Select {}...", files_label));
if (m_selected_files && m_selected_files->length() > 0) { if (m_selected_files && m_selected_files->length() > 0) {
if (m_selected_files->length() == 1) if (m_selected_files->length() == 1)
MUST(m_file_label->set_text_content(Utf16String::from_utf8(m_selected_files->item(0)->name()))); m_file_label->string_replace_all(Utf16String::from_utf8(m_selected_files->item(0)->name()));
else else
MUST(m_file_label->set_text_content(Utf16String::formatted("{} files selected.", m_selected_files->length()))); m_file_label->string_replace_all(Utf16String::formatted("{} files selected.", m_selected_files->length()));
} else { } else {
MUST(m_file_label->set_text_content(Utf16String::formatted("No {} selected.", files_label))); m_file_label->string_replace_all(Utf16String::formatted("No {} selected.", files_label));
} }
} }
@ -1465,7 +1486,7 @@ void HTMLInputElement::type_attribute_changed(TypeAttributeState old_state, Type
// value is not the empty string, and the new state of the element's type attribute puts the value IDL attribute in either // value is not the empty string, and the new state of the element's type attribute puts the value IDL attribute in either
// the default mode or the default/on mode, then set the element's value content attribute to the element's value. // the default mode or the default/on mode, then set the element's value content attribute to the element's value.
if (old_value_attribute_mode == ValueAttributeMode::Value && !m_value.is_empty() && (first_is_one_of(new_value_attribute_mode, ValueAttributeMode::Default, ValueAttributeMode::DefaultOn))) { if (old_value_attribute_mode == ValueAttributeMode::Value && !m_value.is_empty() && (first_is_one_of(new_value_attribute_mode, ValueAttributeMode::Default, ValueAttributeMode::DefaultOn))) {
MUST(set_attribute(HTML::AttributeNames::value, m_value)); set_attribute_value(HTML::AttributeNames::value, m_value.to_utf8_but_should_be_ported_to_utf16());
} }
// 2. Otherwise, if the previous state of the element's type attribute put the value IDL attribute in any mode other // 2. Otherwise, if the previous state of the element's type attribute put the value IDL attribute in any mode other
@ -1619,9 +1640,9 @@ StringView HTMLInputElement::type() const
VERIFY_NOT_REACHED(); VERIFY_NOT_REACHED();
} }
WebIDL::ExceptionOr<void> HTMLInputElement::set_type(String const& type) void HTMLInputElement::set_type(String const& type)
{ {
return set_attribute(HTML::AttributeNames::type, type); set_attribute_value(HTML::AttributeNames::type, type);
} }
bool HTMLInputElement::can_have_text_editing_cursor() const bool HTMLInputElement::can_have_text_editing_cursor() const
@ -2172,7 +2193,8 @@ WebIDL::Long HTMLInputElement::max_length() const
WebIDL::ExceptionOr<void> HTMLInputElement::set_max_length(WebIDL::Long value) WebIDL::ExceptionOr<void> HTMLInputElement::set_max_length(WebIDL::Long value)
{ {
// The maxLength IDL attribute must reflect the maxlength content attribute, limited to only non-negative numbers. // The maxLength IDL attribute must reflect the maxlength content attribute, limited to only non-negative numbers.
return set_attribute(HTML::AttributeNames::maxlength, TRY(convert_non_negative_integer_to_string(realm(), value))); set_attribute_value(HTML::AttributeNames::maxlength, TRY(convert_non_negative_integer_to_string(realm(), value)));
return {};
} }
// https://html.spec.whatwg.org/multipage/input.html#dom-input-minlength // https://html.spec.whatwg.org/multipage/input.html#dom-input-minlength
@ -2189,7 +2211,8 @@ WebIDL::Long HTMLInputElement::min_length() const
WebIDL::ExceptionOr<void> HTMLInputElement::set_min_length(WebIDL::Long value) WebIDL::ExceptionOr<void> HTMLInputElement::set_min_length(WebIDL::Long value)
{ {
// The minLength IDL attribute must reflect the minlength content attribute, limited to only non-negative numbers. // The minLength IDL attribute must reflect the minlength content attribute, limited to only non-negative numbers.
return set_attribute(HTML::AttributeNames::minlength, TRY(convert_non_negative_integer_to_string(realm(), value))); set_attribute_value(HTML::AttributeNames::minlength, TRY(convert_non_negative_integer_to_string(realm(), value)));
return {};
} }
// https://html.spec.whatwg.org/multipage/input.html#the-size-attribute // https://html.spec.whatwg.org/multipage/input.html#the-size-attribute
@ -2210,7 +2233,8 @@ WebIDL::ExceptionOr<void> HTMLInputElement::set_size(WebIDL::UnsignedLong value)
return WebIDL::IndexSizeError::create(realm(), "Size must be greater than zero"_utf16); return WebIDL::IndexSizeError::create(realm(), "Size must be greater than zero"_utf16);
if (value > 2147483647) if (value > 2147483647)
value = 20; value = 20;
return set_attribute(HTML::AttributeNames::size, String::number(value)); set_attribute_value(HTML::AttributeNames::size, String::number(value));
return {};
} }
// https://html.spec.whatwg.org/multipage/input.html#dom-input-height // https://html.spec.whatwg.org/multipage/input.html#dom-input-height
@ -2240,12 +2264,12 @@ WebIDL::UnsignedLong HTMLInputElement::height() const
return 0; return 0;
} }
WebIDL::ExceptionOr<void> HTMLInputElement::set_height(WebIDL::UnsignedLong value) void HTMLInputElement::set_height(WebIDL::UnsignedLong value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 0; value = 0;
return set_attribute(HTML::AttributeNames::height, String::number(value)); set_attribute_value(HTML::AttributeNames::height, String::number(value));
} }
// https://html.spec.whatwg.org/multipage/input.html#dom-input-width // https://html.spec.whatwg.org/multipage/input.html#dom-input-width
@ -2275,12 +2299,12 @@ WebIDL::UnsignedLong HTMLInputElement::width() const
return 0; return 0;
} }
WebIDL::ExceptionOr<void> HTMLInputElement::set_width(WebIDL::UnsignedLong value) void HTMLInputElement::set_width(WebIDL::UnsignedLong value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 0; value = 0;
return set_attribute(HTML::AttributeNames::width, String::number(value)); set_attribute_value(HTML::AttributeNames::width, String::number(value));
} }
// https://html.spec.whatwg.org/multipage/input.html#month-state-(type=month):concept-input-value-string-number // https://html.spec.whatwg.org/multipage/input.html#month-state-(type=month):concept-input-value-string-number

View file

@ -76,7 +76,7 @@ public:
StringView type() const; StringView type() const;
TypeAttributeState type_state() const { return m_type; } TypeAttributeState type_state() const { return m_type; }
WebIDL::ExceptionOr<void> set_type(String const&); void set_type(String const&);
String default_value() const { return get_attribute_value(HTML::AttributeNames::value); } String default_value() const { return get_attribute_value(HTML::AttributeNames::value); }
@ -139,10 +139,10 @@ public:
WebIDL::ExceptionOr<void> set_size(WebIDL::UnsignedLong value); WebIDL::ExceptionOr<void> set_size(WebIDL::UnsignedLong value);
WebIDL::UnsignedLong height() const; WebIDL::UnsignedLong height() const;
WebIDL::ExceptionOr<void> set_height(WebIDL::UnsignedLong value); void set_height(WebIDL::UnsignedLong value);
WebIDL::UnsignedLong width() const; WebIDL::UnsignedLong width() const;
WebIDL::ExceptionOr<void> set_width(WebIDL::UnsignedLong value); void set_width(WebIDL::UnsignedLong value);
struct SelectedCoordinate { struct SelectedCoordinate {
int x { 0 }; int x { 0 };

View file

@ -52,6 +52,11 @@ WebIDL::Long HTMLLIElement::value()
return 0; return 0;
} }
void HTMLLIElement::set_value(WebIDL::Long value)
{
set_attribute_value(AttributeNames::value, String::number(value));
}
bool HTMLLIElement::is_presentational_hint(FlyString const& name) const bool HTMLLIElement::is_presentational_hint(FlyString const& name) const
{ {
if (Base::is_presentational_hint(name)) if (Base::is_presentational_hint(name))

View file

@ -36,10 +36,7 @@ public:
} }
WebIDL::Long value(); WebIDL::Long value();
void set_value(WebIDL::Long value) void set_value(WebIDL::Long value);
{
MUST(set_attribute(AttributeNames::value, String::number(value)));
}
virtual bool is_html_li_element() const override { return true; } virtual bool is_html_li_element() const override { return true; }

View file

@ -111,8 +111,7 @@ GC::Ref<DOM::DOMTokenList> HTMLLinkElement::sizes()
void HTMLLinkElement::set_media(String media) void HTMLLinkElement::set_media(String media)
{ {
(void)set_attribute(HTML::AttributeNames::media, media); set_attribute_value(HTML::AttributeNames::media, media);
if (auto sheet = m_loaded_style_sheet) if (auto sheet = m_loaded_style_sheet)
sheet->set_media(move(media)); sheet->set_media(move(media));
} }

View file

@ -87,11 +87,11 @@ WebIDL::UnsignedLong HTMLMarqueeElement::scroll_amount()
} }
// https://html.spec.whatwg.org/multipage/obsolete.html#dom-marquee-scrollamount // https://html.spec.whatwg.org/multipage/obsolete.html#dom-marquee-scrollamount
WebIDL::ExceptionOr<void> HTMLMarqueeElement::set_scroll_amount(WebIDL::UnsignedLong value) void HTMLMarqueeElement::set_scroll_amount(WebIDL::UnsignedLong value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 6; value = 6;
return set_attribute(HTML::AttributeNames::scrollamount, String::number(value)); set_attribute_value(HTML::AttributeNames::scrollamount, String::number(value));
} }
// https://html.spec.whatwg.org/multipage/obsolete.html#dom-marquee-scrolldelay // https://html.spec.whatwg.org/multipage/obsolete.html#dom-marquee-scrolldelay
@ -106,11 +106,11 @@ WebIDL::UnsignedLong HTMLMarqueeElement::scroll_delay()
} }
// https://html.spec.whatwg.org/multipage/obsolete.html#dom-marquee-scrolldelay // https://html.spec.whatwg.org/multipage/obsolete.html#dom-marquee-scrolldelay
WebIDL::ExceptionOr<void> HTMLMarqueeElement::set_scroll_delay(WebIDL::UnsignedLong value) void HTMLMarqueeElement::set_scroll_delay(WebIDL::UnsignedLong value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 85; value = 85;
return set_attribute(HTML::AttributeNames::scrolldelay, String::number(value)); set_attribute_value(HTML::AttributeNames::scrolldelay, String::number(value));
} }
} }

View file

@ -21,10 +21,10 @@ public:
virtual ~HTMLMarqueeElement() override; virtual ~HTMLMarqueeElement() override;
WebIDL::UnsignedLong scroll_amount(); WebIDL::UnsignedLong scroll_amount();
WebIDL::ExceptionOr<void> set_scroll_amount(WebIDL::UnsignedLong); void set_scroll_amount(WebIDL::UnsignedLong);
WebIDL::UnsignedLong scroll_delay(); WebIDL::UnsignedLong scroll_delay();
WebIDL::ExceptionOr<void> set_scroll_delay(WebIDL::UnsignedLong); void set_scroll_delay(WebIDL::UnsignedLong);
private: private:
HTMLMarqueeElement(DOM::Document&, DOM::QualifiedName); HTMLMarqueeElement(DOM::Document&, DOM::QualifiedName);

View file

@ -68,7 +68,7 @@ void HTMLMediaElement::initialize(JS::Realm& realm)
m_document_observer->set_document_became_inactive([this]() { m_document_observer->set_document_became_inactive([this]() {
// If the media element's node document stops being a fully active document, then the playback will stop until // If the media element's node document stops being a fully active document, then the playback will stop until
// the document is active again. // the document is active again.
pause_element().release_value_but_fixme_should_propagate_errors(); pause_element();
}); });
document().page().register_media_element({}, unique_id()); document().page().register_media_element({}, unique_id());
@ -136,7 +136,7 @@ void HTMLMediaElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
return; return;
// 3. ⌛ Run the internal pause steps for the media element. // 3. ⌛ Run the internal pause steps for the media element.
pause_element().release_value_but_fixme_should_propagate_errors(); pause_element();
} }
// https://html.spec.whatwg.org/multipage/media.html#fatal-decode-error // https://html.spec.whatwg.org/multipage/media.html#fatal-decode-error
@ -369,7 +369,7 @@ void HTMLMediaElement::set_duration(double duration)
paintable->set_needs_display(); paintable->set_needs_display();
} }
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> HTMLMediaElement::play() GC::Ref<WebIDL::Promise> HTMLMediaElement::play()
{ {
auto& realm = this->realm(); auto& realm = this->realm();
@ -387,37 +387,33 @@ WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> HTMLMediaElement::play()
m_pending_play_promises.append(promise); m_pending_play_promises.append(promise);
// 4. Run the internal play steps for the media element. // 4. Run the internal play steps for the media element.
TRY(play_element()); play_element();
// 5. Return promise. // 5. Return promise.
return promise; return promise;
} }
// https://html.spec.whatwg.org/multipage/media.html#dom-media-pause // https://html.spec.whatwg.org/multipage/media.html#dom-media-pause
WebIDL::ExceptionOr<void> HTMLMediaElement::pause() void HTMLMediaElement::pause()
{ {
// 1. If the media element's networkState attribute has the value NETWORK_EMPTY, invoke the media element's resource // 1. If the media element's networkState attribute has the value NETWORK_EMPTY, invoke the media element's resource
// selection algorithm. // selection algorithm.
if (m_network_state == NetworkState::Empty) if (m_network_state == NetworkState::Empty)
TRY(select_resource()); select_resource();
// 2. Run the internal pause steps for the media element. // 2. Run the internal pause steps for the media element.
TRY(pause_element()); pause_element();
return {};
} }
WebIDL::ExceptionOr<void> HTMLMediaElement::toggle_playback() void HTMLMediaElement::toggle_playback()
{ {
// AD-HOC: An execution context is required for Promise creation hooks. // AD-HOC: An execution context is required for Promise creation hooks.
TemporaryExecutionContext execution_context { realm() }; TemporaryExecutionContext execution_context { realm() };
if (potentially_playing()) if (potentially_playing())
TRY(pause()); pause();
else else
TRY(play()); play();
return {};
} }
// https://html.spec.whatwg.org/multipage/media.html#dom-media-volume // https://html.spec.whatwg.org/multipage/media.html#dom-media-volume
@ -628,7 +624,7 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::load_element()
m_can_autoplay = true; m_can_autoplay = true;
// 9. Invoke the media element's resource selection algorithm. // 9. Invoke the media element's resource selection algorithm.
TRY(select_resource()); select_resource();
// 10. NOTE: Playback of any previously playing media resource for this element stops. // 10. NOTE: Playback of any previously playing media resource for this element stops.
return {}; return {};
@ -825,7 +821,7 @@ void HTMLMediaElement::children_changed(ChildrenChangedMetadata const* metadata)
} }
// https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm // https://html.spec.whatwg.org/multipage/media.html#concept-media-load-algorithm
WebIDL::ExceptionOr<void> HTMLMediaElement::select_resource() void HTMLMediaElement::select_resource()
{ {
auto& realm = this->realm(); auto& realm = this->realm();
@ -972,8 +968,6 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::select_resource()
break; break;
} }
}); });
return {};
} }
enum class FetchMode { enum class FetchMode {
@ -1592,12 +1586,12 @@ void HTMLMediaElement::on_playback_manager_state_change()
} }
// https://html.spec.whatwg.org/multipage/media.html#internal-play-steps // https://html.spec.whatwg.org/multipage/media.html#internal-play-steps
WebIDL::ExceptionOr<void> HTMLMediaElement::play_element() void HTMLMediaElement::play_element()
{ {
// 1. If the media element's networkState attribute has the value NETWORK_EMPTY, invoke the media element's resource // 1. If the media element's networkState attribute has the value NETWORK_EMPTY, invoke the media element's resource
// selection algorithm. // selection algorithm.
if (m_network_state == NetworkState::Empty) if (m_network_state == NetworkState::Empty)
TRY(select_resource()); select_resource();
// 2. If the playback has ended and the direction of playback is forwards, seek to the earliest possible position // 2. If the playback has ended and the direction of playback is forwards, seek to the earliest possible position
// of the media resource. // of the media resource.
@ -1654,12 +1648,10 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::play_element()
// 5. Set the media element's can autoplay flag to false. // 5. Set the media element's can autoplay flag to false.
m_can_autoplay = false; m_can_autoplay = false;
return {};
} }
// https://html.spec.whatwg.org/multipage/media.html#internal-pause-steps // https://html.spec.whatwg.org/multipage/media.html#internal-pause-steps
WebIDL::ExceptionOr<void> HTMLMediaElement::pause_element() void HTMLMediaElement::pause_element()
{ {
// 1. Set the media element's can autoplay flag to false. // 1. Set the media element's can autoplay flag to false.
m_can_autoplay = false; m_can_autoplay = false;
@ -1689,8 +1681,6 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::pause_element()
// 4. Set the official playback position to the current playback position. // 4. Set the official playback position to the current playback position.
m_official_playback_position = m_current_playback_position; m_official_playback_position = m_current_playback_position;
} }
return {};
} }
// https://html.spec.whatwg.org/multipage/media.html#dom-media-seek // https://html.spec.whatwg.org/multipage/media.html#dom-media-seek
@ -2217,14 +2207,14 @@ void HTMLMediaElement::reject_pending_play_promises(ReadonlySpan<GC::Ref<WebIDL:
WebIDL::reject_promise(realm, promise, error); WebIDL::reject_promise(realm, promise, error);
} }
WebIDL::ExceptionOr<bool> HTMLMediaElement::handle_keydown(Badge<Web::EventHandler>, UIEvents::KeyCode key, u32 modifiers) bool HTMLMediaElement::handle_keydown(Badge<Web::EventHandler>, UIEvents::KeyCode key, u32 modifiers)
{ {
if (modifiers != UIEvents::KeyModifier::Mod_None) if (modifiers != UIEvents::KeyModifier::Mod_None)
return false; return false;
switch (key) { switch (key) {
case UIEvents::KeyCode::Key_Space: case UIEvents::KeyCode::Key_Space:
TRY(toggle_playback()); toggle_playback();
break; break;
case UIEvents::KeyCode::Key_Home: case UIEvents::KeyCode::Key_Home:
@ -2258,7 +2248,8 @@ WebIDL::ExceptionOr<bool> HTMLMediaElement::handle_keydown(Badge<Web::EventHandl
else else
volume = max(0.0, volume - volume_change_per_key_press); volume = max(0.0, volume - volume_change_per_key_press);
TRY(set_volume(volume)); // This should never fail since volume is clamped to 0.0..1.0 above.
MUST(set_volume(volume));
break; break;
} }

View file

@ -48,7 +48,7 @@ public:
void set_decoder_error(String error_message); void set_decoder_error(String error_message);
String const& current_src() const { return m_current_src; } String const& current_src() const { return m_current_src; }
WebIDL::ExceptionOr<void> select_resource(); void select_resource();
enum class NetworkState : u16 { enum class NetworkState : u16 {
Empty, Empty,
@ -106,9 +106,9 @@ public:
bool paused() const { return m_paused; } bool paused() const { return m_paused; }
bool ended() const; bool ended() const;
bool potentially_playing() const; bool potentially_playing() const;
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> play(); GC::Ref<WebIDL::Promise> play();
WebIDL::ExceptionOr<void> pause(); void pause();
WebIDL::ExceptionOr<void> toggle_playback(); void toggle_playback();
double volume() const { return m_volume; } double volume() const { return m_volume; }
WebIDL::ExceptionOr<void> set_volume(double); WebIDL::ExceptionOr<void> set_volume(double);
@ -138,7 +138,7 @@ public:
GC::Ref<TextTrack> add_text_track(Bindings::TextTrackKind kind, String const& label, String const& language); GC::Ref<TextTrack> add_text_track(Bindings::TextTrackKind kind, String const& label, String const& language);
WebIDL::ExceptionOr<bool> handle_keydown(Badge<Web::EventHandler>, UIEvents::KeyCode, u32 modifiers); bool handle_keydown(Badge<Web::EventHandler>, UIEvents::KeyCode, u32 modifiers);
enum class MediaComponent { enum class MediaComponent {
PlaybackButton, PlaybackButton,
@ -203,8 +203,8 @@ private:
void set_ready_state(ReadyState); void set_ready_state(ReadyState);
void on_playback_manager_state_change(); void on_playback_manager_state_change();
WebIDL::ExceptionOr<void> play_element(); void play_element();
WebIDL::ExceptionOr<void> pause_element(); void pause_element();
void seek_element(double playback_position, MediaSeekMode = MediaSeekMode::Accurate); void seek_element(double playback_position, MediaSeekMode = MediaSeekMode::Accurate);
void finish_seeking_element(); void finish_seeking_element();
void notify_about_playing(); void notify_about_playing();

View file

@ -54,11 +54,10 @@ double HTMLMeterElement::value() const
return clamp(candidate_value, min(), max()); return clamp(candidate_value, min(), max());
} }
WebIDL::ExceptionOr<void> HTMLMeterElement::set_value(double value) void HTMLMeterElement::set_value(double value)
{ {
TRY(set_attribute(HTML::AttributeNames::value, String::number(value))); set_attribute_value(HTML::AttributeNames::value, String::number(value));
update_meter_value_element(); update_meter_value_element();
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-minimum // https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-minimum
@ -72,11 +71,10 @@ double HTMLMeterElement::min() const
return 0; return 0;
} }
WebIDL::ExceptionOr<void> HTMLMeterElement::set_min(double value) void HTMLMeterElement::set_min(double value)
{ {
TRY(set_attribute(HTML::AttributeNames::min, String::number(value))); set_attribute_value(HTML::AttributeNames::min, String::number(value));
update_meter_value_element(); update_meter_value_element();
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-maximum // https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-maximum
@ -93,11 +91,10 @@ double HTMLMeterElement::max() const
return AK::max(candidate_max, min()); return AK::max(candidate_max, min());
} }
WebIDL::ExceptionOr<void> HTMLMeterElement::set_max(double value) void HTMLMeterElement::set_max(double value)
{ {
TRY(set_attribute(HTML::AttributeNames::max, String::number(value))); set_attribute_value(HTML::AttributeNames::max, String::number(value));
update_meter_value_element(); update_meter_value_element();
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-low // https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-low
@ -116,11 +113,10 @@ double HTMLMeterElement::low() const
return clamp(candidate_low, min(), max()); return clamp(candidate_low, min(), max());
} }
WebIDL::ExceptionOr<void> HTMLMeterElement::set_low(double value) void HTMLMeterElement::set_low(double value)
{ {
TRY(set_attribute(HTML::AttributeNames::low, String::number(value))); set_attribute_value(HTML::AttributeNames::low, String::number(value));
update_meter_value_element(); update_meter_value_element();
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-high // https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-high
@ -139,11 +135,10 @@ double HTMLMeterElement::high() const
return clamp(candidate_high, low(), max()); return clamp(candidate_high, low(), max());
} }
WebIDL::ExceptionOr<void> HTMLMeterElement::set_high(double value) void HTMLMeterElement::set_high(double value)
{ {
TRY(set_attribute(HTML::AttributeNames::high, String::number(value))); set_attribute_value(HTML::AttributeNames::high, String::number(value));
update_meter_value_element(); update_meter_value_element();
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-optimum // https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-optimum
@ -162,11 +157,10 @@ double HTMLMeterElement::optimum() const
return clamp(candidate_optimum, min(), max()); return clamp(candidate_optimum, min(), max());
} }
WebIDL::ExceptionOr<void> HTMLMeterElement::set_optimum(double value) void HTMLMeterElement::set_optimum(double value)
{ {
TRY(set_attribute(HTML::AttributeNames::optimum, String::number(value))); set_attribute_value(HTML::AttributeNames::optimum, String::number(value));
update_meter_value_element(); update_meter_value_element();
return {};
} }
void HTMLMeterElement::inserted() void HTMLMeterElement::inserted()

View file

@ -21,17 +21,17 @@ public:
virtual ~HTMLMeterElement() override; virtual ~HTMLMeterElement() override;
double value() const; double value() const;
WebIDL::ExceptionOr<void> set_value(double); void set_value(double);
double min() const; double min() const;
WebIDL::ExceptionOr<void> set_min(double value); void set_min(double value);
double max() const; double max() const;
WebIDL::ExceptionOr<void> set_max(double value); void set_max(double value);
double low() const; double low() const;
WebIDL::ExceptionOr<void> set_low(double value); void set_low(double value);
double high() const; double high() const;
WebIDL::ExceptionOr<void> set_high(double value); void set_high(double value);
double optimum() const; double optimum() const;
WebIDL::ExceptionOr<void> set_optimum(double value); void set_optimum(double value);
// ^HTMLElement // ^HTMLElement
virtual void inserted() override; virtual void inserted() override;

View file

@ -52,6 +52,11 @@ WebIDL::Long HTMLOListElement::start()
return 1; return 1;
} }
void HTMLOListElement::set_start(WebIDL::Long start)
{
set_attribute_value(AttributeNames::start, String::number(start));
}
// https://html.spec.whatwg.org/multipage/grouping-content.html#concept-ol-start // https://html.spec.whatwg.org/multipage/grouping-content.html#concept-ol-start
AK::Checked<i32> HTMLOListElement::starting_value() const AK::Checked<i32> HTMLOListElement::starting_value() const
{ {

View file

@ -24,10 +24,7 @@ public:
virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::list; } virtual Optional<ARIA::Role> default_role() const override { return ARIA::Role::list; }
WebIDL::Long start(); WebIDL::Long start();
void set_start(WebIDL::Long start) void set_start(WebIDL::Long start);
{
MUST(set_attribute(AttributeNames::start, String::number(start)));
}
AK::Checked<i32> starting_value() const; AK::Checked<i32> starting_value() const;

View file

@ -180,6 +180,11 @@ String HTMLObjectElement::data() const
return maybe_url->to_string(); return maybe_url->to_string();
} }
void HTMLObjectElement::set_data(String const& data)
{
set_attribute_value(HTML::AttributeNames::data, data);
}
GC::Ptr<Layout::Node> HTMLObjectElement::create_layout_node(GC::Ref<CSS::ComputedProperties> style) GC::Ptr<Layout::Node> HTMLObjectElement::create_layout_node(GC::Ref<CSS::ComputedProperties> style)
{ {
switch (m_representation) { switch (m_representation) {

View file

@ -37,7 +37,7 @@ public:
virtual void form_associated_element_was_removed(DOM::Node*) override; virtual void form_associated_element_was_removed(DOM::Node*) override;
String data() const; String data() const;
void set_data(String const& data) { MUST(set_attribute(HTML::AttributeNames::data, data)); } void set_data(String const& data);
String type() const { return get_attribute_value(HTML::AttributeNames::type); } String type() const { return get_attribute_value(HTML::AttributeNames::type); }

View file

@ -99,9 +99,9 @@ Utf16String HTMLOptionElement::value() const
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-value // https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-value
WebIDL::ExceptionOr<void> HTMLOptionElement::set_value(Utf16String const& value) void HTMLOptionElement::set_value(Utf16String const& value)
{ {
return set_attribute(HTML::AttributeNames::value, value); set_attribute_value(HTML::AttributeNames::value, value.to_utf8_but_should_be_ported_to_utf16());
} }
static void concatenate_descendants_text_content(DOM::Node const* node, StringBuilder& builder) static void concatenate_descendants_text_content(DOM::Node const* node, StringBuilder& builder)
@ -129,7 +129,7 @@ String HTMLOptionElement::label() const
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-label // https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-label
void HTMLOptionElement::set_label(String const& label) void HTMLOptionElement::set_label(String const& label)
{ {
MUST(set_attribute(HTML::AttributeNames::label, label)); set_attribute_value(HTML::AttributeNames::label, label);
// Note: this causes attribute_changed() to be called, which will update the <select>'s label // Note: this causes attribute_changed() to be called, which will update the <select>'s label
} }

View file

@ -25,7 +25,7 @@ public:
[[nodiscard]] u64 selectedness_update_index() const { return m_selectedness_update_index; } [[nodiscard]] u64 selectedness_update_index() const { return m_selectedness_update_index; }
Utf16String value() const; Utf16String value() const;
WebIDL::ExceptionOr<void> set_value(Utf16String const&); void set_value(Utf16String const&);
Utf16String text() const; Utf16String text() const;
void set_text(Utf16String const&); void set_text(Utf16String const&);

View file

@ -51,14 +51,13 @@ double HTMLProgressElement::value() const
return 0; return 0;
} }
WebIDL::ExceptionOr<void> HTMLProgressElement::set_value(double value) void HTMLProgressElement::set_value(double value)
{ {
if (value < 0) if (value < 0)
value = 0; value = 0;
TRY(set_attribute(HTML::AttributeNames::value, String::number(value))); set_attribute_value(HTML::AttributeNames::value, String::number(value));
update_progress_value_element(); update_progress_value_element();
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-progress-max // https://html.spec.whatwg.org/multipage/form-elements.html#dom-progress-max
@ -72,14 +71,13 @@ WebIDL::Double HTMLProgressElement::max() const
return 1; return 1;
} }
WebIDL::ExceptionOr<void> HTMLProgressElement::set_max(double value) void HTMLProgressElement::set_max(double value)
{ {
if (value <= 0) if (value <= 0)
return {}; return;
TRY(set_attribute(HTML::AttributeNames::max, String::number(value))); set_attribute_value(HTML::AttributeNames::max, String::number(value));
update_progress_value_element(); update_progress_value_element();
return {};
} }
double HTMLProgressElement::position() const double HTMLProgressElement::position() const

View file

@ -20,10 +20,10 @@ public:
virtual ~HTMLProgressElement() override; virtual ~HTMLProgressElement() override;
double value() const; double value() const;
WebIDL::ExceptionOr<void> set_value(double); void set_value(double);
WebIDL::Double max() const; WebIDL::Double max() const;
WebIDL::ExceptionOr<void> set_max(WebIDL::Double value); void set_max(WebIDL::Double value);
double position() const; double position() const;

View file

@ -787,7 +787,7 @@ void HTMLScriptElement::set_async(bool async)
// 2. If the given value is true, then set this's async content attribute to the empty string. // 2. If the given value is true, then set this's async content attribute to the empty string.
if (async) { if (async) {
MUST(set_attribute(HTML::AttributeNames::async, ""_string)); set_attribute_value(HTML::AttributeNames::async, ""_string);
} }
// 3. Otherwise, remove this's async content attribute. // 3. Otherwise, remove this's async content attribute.
else { else {

View file

@ -110,11 +110,11 @@ WebIDL::UnsignedLong HTMLSelectElement::size() const
return 0; return 0;
} }
WebIDL::ExceptionOr<void> HTMLSelectElement::set_size(WebIDL::UnsignedLong size) void HTMLSelectElement::set_size(WebIDL::UnsignedLong size)
{ {
if (size > 2147483647) if (size > 2147483647)
size = 0; size = 0;
return set_attribute(HTML::AttributeNames::size, String::number(size)); set_attribute_value(HTML::AttributeNames::size, String::number(size));
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-select-options // https://html.spec.whatwg.org/multipage/form-elements.html#dom-select-options
@ -590,29 +590,36 @@ void HTMLSelectElement::create_shadow_tree_if_needed()
set_shadow_root(shadow_root); set_shadow_root(shadow_root);
auto border = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors(); auto border = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
MUST(border->set_attribute(HTML::AttributeNames::style, R"~~~( border->set_attribute_value(HTML::AttributeNames::style, R"~~~(
display: flex; display: flex;
align-items: center; align-items: center;
height: 100%; height: 100%;
)~~~"_string)); )~~~"_string);
MUST(shadow_root->append_child(border)); MUST(shadow_root->append_child(border));
m_inner_text_element = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors(); m_inner_text_element = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
MUST(m_inner_text_element->set_attribute(HTML::AttributeNames::style, R"~~~( m_inner_text_element->set_attribute_value(HTML::AttributeNames::style, R"~~~(
flex: 1; flex: 1;
)~~~"_string)); )~~~"_string);
MUST(border->append_child(*m_inner_text_element)); MUST(border->append_child(*m_inner_text_element));
// FIXME: Find better way to add chevron icon
static constexpr auto chevron_svg = "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\"><path fill=\"currentcolor\" d=\"M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z\"/></svg>"sv;
m_chevron_icon_element = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors(); m_chevron_icon_element = DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML).release_value_but_fixme_should_propagate_errors();
MUST(m_chevron_icon_element->set_attribute(HTML::AttributeNames::style, R"~~~( m_chevron_icon_element->set_attribute_value(HTML::AttributeNames::style, R"~~~(
width: 16px; width: 16px;
height: 16px; height: 16px;
margin-left: 4px; margin-left: 4px;
)~~~"_string)); )~~~"_string);
MUST(m_chevron_icon_element->set_inner_html(Utf16String::from_utf8(chevron_svg)));
auto chevron_svg_element = DOM::create_element(document(), SVG::TagNames::svg, Namespace::SVG).release_value_but_fixme_should_propagate_errors();
chevron_svg_element->set_attribute_value(SVG::AttributeNames::xmlns, Namespace::SVG.to_string());
chevron_svg_element->set_attribute_value(SVG::AttributeNames::viewBox, "0 0 24 24"_string);
MUST(m_chevron_icon_element->append_child(chevron_svg_element));
auto chevron_path_element = DOM::create_element(document(), SVG::TagNames::path, Namespace::SVG).release_value_but_fixme_should_propagate_errors();
chevron_path_element->set_attribute_value(SVG::AttributeNames::fill, "currentcolor"_string);
chevron_path_element->set_attribute_value(SVG::AttributeNames::d, "M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"_string);
MUST(chevron_svg_element->append_child(chevron_path_element));
MUST(border->append_child(*m_chevron_icon_element)); MUST(border->append_child(*m_chevron_icon_element));
update_inner_text_element(); update_inner_text_element();
@ -633,7 +640,7 @@ void HTMLSelectElement::update_inner_text_element()
// Update inner text element to the label of the selected option // Update inner text element to the label of the selected option
for (auto const& option_element : m_cached_list_of_options) { for (auto const& option_element : m_cached_list_of_options) {
if (option_element->selected()) { if (option_element->selected()) {
MUST(m_inner_text_element->set_text_content(Infra::strip_and_collapse_whitespace(Utf16String::from_utf8(option_element->label())))); m_inner_text_element->string_replace_all(Infra::strip_and_collapse_whitespace(Utf16String::from_utf8(option_element->label())));
return; return;
} }
} }

View file

@ -34,7 +34,7 @@ public:
virtual void adjust_computed_style(CSS::ComputedProperties&) override; virtual void adjust_computed_style(CSS::ComputedProperties&) override;
WebIDL::UnsignedLong size() const; WebIDL::UnsignedLong size() const;
WebIDL::ExceptionOr<void> set_size(WebIDL::UnsignedLong); void set_size(WebIDL::UnsignedLong);
GC::Ptr<HTMLOptionsCollection> const& options(); GC::Ptr<HTMLOptionsCollection> const& options();

View file

@ -41,7 +41,7 @@ void HTMLSourceElement::inserted()
if (auto* media_element = as_if<HTMLMediaElement>(parent); media_element if (auto* media_element = as_if<HTMLMediaElement>(parent); media_element
&& !media_element->has_attribute(HTML::AttributeNames::src) && !media_element->has_attribute(HTML::AttributeNames::src)
&& media_element->network_state() == HTMLMediaElement::NetworkState::Empty) { && media_element->network_state() == HTMLMediaElement::NetworkState::Empty) {
media_element->select_resource().release_value_but_fixme_should_propagate_errors(); media_element->select_resource();
} }
// FIXME: 3. If parent is a picture element, then for each child of parent's children, if child is an img element, then // FIXME: 3. If parent is a picture element, then for each child of parent's children, if child is an img element, then

View file

@ -37,7 +37,7 @@ void HTMLSummaryElement::activation_behavior(DOM::Event const&)
if (parent->has_attribute(HTML::AttributeNames::open)) if (parent->has_attribute(HTML::AttributeNames::open))
parent->remove_attribute(HTML::AttributeNames::open); parent->remove_attribute(HTML::AttributeNames::open);
else else
MUST(parent->set_attribute(HTML::AttributeNames::open, String {})); parent->set_attribute_value(HTML::AttributeNames::open, String {});
} }
// https://html.spec.whatwg.org/multipage/interactive-elements.html#summary-for-its-parent-details // https://html.spec.whatwg.org/multipage/interactive-elements.html#summary-for-its-parent-details

View file

@ -157,11 +157,11 @@ WebIDL::UnsignedLong HTMLTableCellElement::col_span() const
return value; return value;
} }
WebIDL::ExceptionOr<void> HTMLTableCellElement::set_col_span(WebIDL::UnsignedLong value) void HTMLTableCellElement::set_col_span(WebIDL::UnsignedLong value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 1; value = 1;
return set_attribute(HTML::AttributeNames::colspan, String::number(value)); set_attribute_value(HTML::AttributeNames::colspan, String::number(value));
} }
// This implements step 9 in the spec here: // This implements step 9 in the spec here:
@ -187,11 +187,11 @@ WebIDL::UnsignedLong HTMLTableCellElement::row_span() const
return *optional_value; return *optional_value;
} }
WebIDL::ExceptionOr<void> HTMLTableCellElement::set_row_span(WebIDL::UnsignedLong value) void HTMLTableCellElement::set_row_span(WebIDL::UnsignedLong value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 1; value = 1;
return set_attribute(HTML::AttributeNames::rowspan, String::number(value)); set_attribute_value(HTML::AttributeNames::rowspan, String::number(value));
} }
// https://html.spec.whatwg.org/multipage/tables.html#dom-tdth-cellindex // https://html.spec.whatwg.org/multipage/tables.html#dom-tdth-cellindex

View file

@ -21,8 +21,8 @@ public:
WebIDL::UnsignedLong col_span() const; WebIDL::UnsignedLong col_span() const;
WebIDL::UnsignedLong row_span() const; WebIDL::UnsignedLong row_span() const;
WebIDL::ExceptionOr<void> set_col_span(WebIDL::UnsignedLong); void set_col_span(WebIDL::UnsignedLong);
WebIDL::ExceptionOr<void> set_row_span(WebIDL::UnsignedLong); void set_row_span(WebIDL::UnsignedLong);
WebIDL::Long cell_index() const; WebIDL::Long cell_index() const;

View file

@ -44,11 +44,11 @@ WebIDL::UnsignedLong HTMLTableColElement::span() const
return 1; return 1;
} }
WebIDL::ExceptionOr<void> HTMLTableColElement::set_span(unsigned int value) void HTMLTableColElement::set_span(unsigned int value)
{ {
if (value > 2147483647) if (value > 2147483647)
value = 1; value = 1;
return set_attribute(HTML::AttributeNames::span, String::number(value)); set_attribute_value(HTML::AttributeNames::span, String::number(value));
} }
bool HTMLTableColElement::is_presentational_hint(FlyString const& name) const bool HTMLTableColElement::is_presentational_hint(FlyString const& name) const

View file

@ -19,7 +19,7 @@ public:
virtual ~HTMLTableColElement() override; virtual ~HTMLTableColElement() override;
WebIDL::UnsignedLong span() const; WebIDL::UnsignedLong span() const;
WebIDL::ExceptionOr<void> set_span(WebIDL::UnsignedLong); void set_span(WebIDL::UnsignedLong);
private: private:
HTMLTableColElement(DOM::Document&, DOM::QualifiedName); HTMLTableColElement(DOM::Document&, DOM::QualifiedName);

View file

@ -117,7 +117,7 @@ void HTMLTextAreaElement::reset_algorithm()
set_raw_value(child_text_content()); set_raw_value(child_text_content());
if (m_text_node) { if (m_text_node) {
MUST(m_text_node->set_text_content(m_raw_value)); MUST(m_text_node->replace_data(0, m_text_node->length_in_utf16_code_units(), m_raw_value));
update_placeholder_visibility(); update_placeholder_visibility();
} }
} }
@ -191,7 +191,7 @@ void HTMLTextAreaElement::set_value(Utf16String const& value)
// the text control, unselecting any selected text and resetting the selection direction to "none". // the text control, unselecting any selected text and resetting the selection direction to "none".
if (api_value() != old_api_value) { if (api_value() != old_api_value) {
if (m_text_node) { if (m_text_node) {
m_text_node->set_data(m_raw_value); MUST(m_text_node->replace_data(0, m_text_node->length_in_utf16_code_units(), m_raw_value));
update_placeholder_visibility(); update_placeholder_visibility();
set_the_selection_range(m_text_node->length(), m_text_node->length()); set_the_selection_range(m_text_node->length(), m_text_node->length());
@ -244,7 +244,8 @@ WebIDL::Long HTMLTextAreaElement::max_length() const
WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_max_length(WebIDL::Long value) WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_max_length(WebIDL::Long value)
{ {
// The maxLength IDL attribute must reflect the maxlength content attribute, limited to only non-negative numbers. // The maxLength IDL attribute must reflect the maxlength content attribute, limited to only non-negative numbers.
return set_attribute(HTML::AttributeNames::maxlength, TRY(convert_non_negative_integer_to_string(realm(), value))); set_attribute_value(HTML::AttributeNames::maxlength, TRY(convert_non_negative_integer_to_string(realm(), value)));
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-minlength // https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-minlength
@ -261,7 +262,8 @@ WebIDL::Long HTMLTextAreaElement::min_length() const
WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_min_length(WebIDL::Long value) WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_min_length(WebIDL::Long value)
{ {
// The minLength IDL attribute must reflect the minlength content attribute, limited to only non-negative numbers. // The minLength IDL attribute must reflect the minlength content attribute, limited to only non-negative numbers.
return set_attribute(HTML::AttributeNames::minlength, TRY(convert_non_negative_integer_to_string(realm(), value))); set_attribute_value(HTML::AttributeNames::minlength, TRY(convert_non_negative_integer_to_string(realm(), value)));
return {};
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-cols // https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-cols
@ -275,12 +277,12 @@ unsigned HTMLTextAreaElement::cols() const
return 20; return 20;
} }
WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_cols(WebIDL::UnsignedLong cols) void HTMLTextAreaElement::set_cols(WebIDL::UnsignedLong cols)
{ {
if (cols == 0 || cols > 2147483647) if (cols == 0 || cols > 2147483647)
cols = 20; cols = 20;
return set_attribute(HTML::AttributeNames::cols, String::number(cols)); set_attribute_value(HTML::AttributeNames::cols, String::number(cols));
} }
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-rows // https://html.spec.whatwg.org/multipage/form-elements.html#dom-textarea-rows
@ -294,12 +296,12 @@ WebIDL::UnsignedLong HTMLTextAreaElement::rows() const
return 2; return 2;
} }
WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_rows(WebIDL::UnsignedLong rows) void HTMLTextAreaElement::set_rows(WebIDL::UnsignedLong rows)
{ {
if (rows == 0 || rows > 2147483647) if (rows == 0 || rows > 2147483647)
rows = 2; rows = 2;
return set_attribute(HTML::AttributeNames::rows, String::number(rows)); set_attribute_value(HTML::AttributeNames::rows, String::number(rows));
} }
WebIDL::UnsignedLong HTMLTextAreaElement::selection_start_binding() const WebIDL::UnsignedLong HTMLTextAreaElement::selection_start_binding() const
@ -347,10 +349,9 @@ void HTMLTextAreaElement::create_shadow_tree_if_needed()
m_inner_text_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML)); m_inner_text_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
MUST(element->append_child(*m_inner_text_element)); MUST(element->append_child(*m_inner_text_element));
m_text_node = realm().create<DOM::Text>(document(), Utf16String {});
// NOTE: If `children_changed()` was called before now, `m_raw_value` will hold the text content. // NOTE: If `children_changed()` was called before now, `m_raw_value` will hold the text content.
// Otherwise, it will get filled in whenever that does get called. // Otherwise, it will get filled in whenever that does get called.
MUST(m_text_node->set_text_content(m_raw_value)); m_text_node = realm().create<DOM::Text>(document(), m_raw_value);
handle_maxlength_attribute(); handle_maxlength_attribute();
MUST(m_inner_text_element->append_child(*m_text_node)); MUST(m_inner_text_element->append_child(*m_text_node));
@ -403,7 +404,7 @@ void HTMLTextAreaElement::children_changed(ChildrenChangedMetadata const* metada
if (!m_dirty_value) { if (!m_dirty_value) {
set_raw_value(child_text_content()); set_raw_value(child_text_content());
if (m_text_node) if (m_text_node)
MUST(m_text_node->set_text_content(m_raw_value)); m_text_node->set_data(m_raw_value);
update_placeholder_visibility(); update_placeholder_visibility();
} }
} }

View file

@ -105,10 +105,10 @@ public:
WebIDL::ExceptionOr<void> set_min_length(WebIDL::Long); WebIDL::ExceptionOr<void> set_min_length(WebIDL::Long);
WebIDL::UnsignedLong cols() const; WebIDL::UnsignedLong cols() const;
WebIDL::ExceptionOr<void> set_cols(unsigned); void set_cols(unsigned);
WebIDL::UnsignedLong rows() const; WebIDL::UnsignedLong rows() const;
WebIDL::ExceptionOr<void> set_rows(WebIDL::UnsignedLong); void set_rows(WebIDL::UnsignedLong);
// https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionstart // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-textarea/input-selectionstart
WebIDL::UnsignedLong selection_start_binding() const; WebIDL::UnsignedLong selection_start_binding() const;

View file

@ -1305,7 +1305,7 @@ EventResult EventHandler::handle_keydown(UIEvents::KeyCode key, u32 modifiers, u
auto focused_area = m_navigable->active_document()->focused_area(); auto focused_area = m_navigable->active_document()->focused_area();
if (auto* media_element = as_if<HTML::HTMLMediaElement>(focused_area.ptr())) { if (auto* media_element = as_if<HTML::HTMLMediaElement>(focused_area.ptr())) {
if (media_element->handle_keydown({}, key, modifiers).release_value_but_fixme_should_propagate_errors()) if (media_element->handle_keydown({}, key, modifiers))
return EventResult::Handled; return EventResult::Handled;
} }

View file

@ -515,21 +515,19 @@ void Page::did_request_media_context_menu(UniqueNodeID media_id, CSSPixelPoint p
client().page_did_request_media_context_menu(position, target, modifiers, menu); client().page_did_request_media_context_menu(position, target, modifiers, menu);
} }
WebIDL::ExceptionOr<void> Page::toggle_media_play_state() void Page::toggle_media_play_state()
{ {
auto media_element = media_context_menu_element(); auto media_element = media_context_menu_element();
if (!media_element) if (!media_element)
return {}; return;
// AD-HOC: An execution context is required for Promise creation hooks. // AD-HOC: An execution context is required for Promise creation hooks.
HTML::TemporaryExecutionContext execution_context { media_element->realm() }; HTML::TemporaryExecutionContext execution_context { media_element->realm() };
if (media_element->potentially_playing()) if (media_element->potentially_playing())
TRY(media_element->pause()); media_element->pause();
else else
TRY(media_element->play()); media_element->play();
return {};
} }
void Page::toggle_media_mute_state() void Page::toggle_media_mute_state()
@ -544,11 +542,11 @@ void Page::toggle_media_mute_state()
media_element->set_muted(!media_element->muted()); media_element->set_muted(!media_element->muted());
} }
WebIDL::ExceptionOr<void> Page::toggle_media_loop_state() void Page::toggle_media_loop_state()
{ {
auto media_element = media_context_menu_element(); auto media_element = media_context_menu_element();
if (!media_element) if (!media_element)
return {}; return;
// AD-HOC: An execution context is required for Promise creation hooks. // AD-HOC: An execution context is required for Promise creation hooks.
HTML::TemporaryExecutionContext execution_context { media_element->realm() }; HTML::TemporaryExecutionContext execution_context { media_element->realm() };
@ -556,25 +554,21 @@ WebIDL::ExceptionOr<void> Page::toggle_media_loop_state()
if (media_element->has_attribute(HTML::AttributeNames::loop)) if (media_element->has_attribute(HTML::AttributeNames::loop))
media_element->remove_attribute(HTML::AttributeNames::loop); media_element->remove_attribute(HTML::AttributeNames::loop);
else else
TRY(media_element->set_attribute(HTML::AttributeNames::loop, String {})); media_element->set_attribute_value(HTML::AttributeNames::loop, String {});
return {};
} }
WebIDL::ExceptionOr<void> Page::toggle_media_controls_state() void Page::toggle_media_controls_state()
{ {
auto media_element = media_context_menu_element(); auto media_element = media_context_menu_element();
if (!media_element) if (!media_element)
return {}; return;
HTML::TemporaryExecutionContext execution_context { media_element->realm() }; HTML::TemporaryExecutionContext execution_context { media_element->realm() };
if (media_element->has_attribute(HTML::AttributeNames::controls)) if (media_element->has_attribute(HTML::AttributeNames::controls))
media_element->remove_attribute(HTML::AttributeNames::controls); media_element->remove_attribute(HTML::AttributeNames::controls);
else else
TRY(media_element->set_attribute(HTML::AttributeNames::controls, String {})); media_element->set_attribute_value(HTML::AttributeNames::controls, String {});
return {};
} }
void Page::toggle_page_mute_state() void Page::toggle_page_mute_state()

View file

@ -194,10 +194,10 @@ public:
bool is_looping { false }; bool is_looping { false };
}; };
void did_request_media_context_menu(UniqueNodeID media_id, CSSPixelPoint, ByteString const& target, unsigned modifiers, MediaContextMenu const&); void did_request_media_context_menu(UniqueNodeID media_id, CSSPixelPoint, ByteString const& target, unsigned modifiers, MediaContextMenu const&);
WebIDL::ExceptionOr<void> toggle_media_play_state(); void toggle_media_play_state();
void toggle_media_mute_state(); void toggle_media_mute_state();
WebIDL::ExceptionOr<void> toggle_media_loop_state(); void toggle_media_loop_state();
WebIDL::ExceptionOr<void> toggle_media_controls_state(); void toggle_media_controls_state();
HTML::MuteState page_mute_state() const { return m_mute_state; } HTML::MuteState page_mute_state() const { return m_mute_state; }
void toggle_page_mute_state(); void toggle_page_mute_state();

View file

@ -337,7 +337,7 @@ MediaPaintable::DispatchEventOfSameName MediaPaintable::handle_mouseup(Badge<Eve
if (cached_layout_boxes.control_box_rect.has_value() && cached_layout_boxes.control_box_rect->contains(position_adjusted_by_scroll_offset)) { if (cached_layout_boxes.control_box_rect.has_value() && cached_layout_boxes.control_box_rect->contains(position_adjusted_by_scroll_offset)) {
if (cached_layout_boxes.playback_button_rect.has_value() && cached_layout_boxes.playback_button_rect->contains(position_adjusted_by_scroll_offset)) { if (cached_layout_boxes.playback_button_rect.has_value() && cached_layout_boxes.playback_button_rect->contains(position_adjusted_by_scroll_offset)) {
media_element.toggle_playback().release_value_but_fixme_should_propagate_errors(); media_element.toggle_playback();
return DispatchEventOfSameName::Yes; return DispatchEventOfSameName::Yes;
} }
@ -350,7 +350,7 @@ MediaPaintable::DispatchEventOfSameName MediaPaintable::handle_mouseup(Badge<Eve
return DispatchEventOfSameName::No; return DispatchEventOfSameName::No;
} }
media_element.toggle_playback().release_value_but_fixme_should_propagate_errors(); media_element.toggle_playback();
return DispatchEventOfSameName::Yes; return DispatchEventOfSameName::Yes;
} }

View file

@ -22,10 +22,12 @@ namespace Web::SVG::AttributeNames {
__ENUMERATE_SVG_ATTRIBUTE(contentStyleType, "contentStyleType") \ __ENUMERATE_SVG_ATTRIBUTE(contentStyleType, "contentStyleType") \
__ENUMERATE_SVG_ATTRIBUTE(cx, "cx") \ __ENUMERATE_SVG_ATTRIBUTE(cx, "cx") \
__ENUMERATE_SVG_ATTRIBUTE(cy, "cy") \ __ENUMERATE_SVG_ATTRIBUTE(cy, "cy") \
__ENUMERATE_SVG_ATTRIBUTE(d, "d") \
__ENUMERATE_SVG_ATTRIBUTE(diffuseConstant, "diffuseConstant") \ __ENUMERATE_SVG_ATTRIBUTE(diffuseConstant, "diffuseConstant") \
__ENUMERATE_SVG_ATTRIBUTE(dx, "dx") \ __ENUMERATE_SVG_ATTRIBUTE(dx, "dx") \
__ENUMERATE_SVG_ATTRIBUTE(dy, "dy") \ __ENUMERATE_SVG_ATTRIBUTE(dy, "dy") \
__ENUMERATE_SVG_ATTRIBUTE(edgeMode, "edgeMode") \ __ENUMERATE_SVG_ATTRIBUTE(edgeMode, "edgeMode") \
__ENUMERATE_SVG_ATTRIBUTE(fill, "fill") \
__ENUMERATE_SVG_ATTRIBUTE(filterUnits, "filterUnits") \ __ENUMERATE_SVG_ATTRIBUTE(filterUnits, "filterUnits") \
__ENUMERATE_SVG_ATTRIBUTE(fr, "fr") \ __ENUMERATE_SVG_ATTRIBUTE(fr, "fr") \
__ENUMERATE_SVG_ATTRIBUTE(fx, "fx") \ __ENUMERATE_SVG_ATTRIBUTE(fx, "fx") \
@ -104,6 +106,7 @@ namespace Web::SVG::AttributeNames {
__ENUMERATE_SVG_ATTRIBUTE(x2, "x2") \ __ENUMERATE_SVG_ATTRIBUTE(x2, "x2") \
__ENUMERATE_SVG_ATTRIBUTE(xChannelSelector, "xChannelSelector") \ __ENUMERATE_SVG_ATTRIBUTE(xChannelSelector, "xChannelSelector") \
__ENUMERATE_SVG_ATTRIBUTE(xlink_href, "xlink:href") \ __ENUMERATE_SVG_ATTRIBUTE(xlink_href, "xlink:href") \
__ENUMERATE_SVG_ATTRIBUTE(xmlns, "xmlns") \
__ENUMERATE_SVG_ATTRIBUTE(y, "y") \ __ENUMERATE_SVG_ATTRIBUTE(y, "y") \
__ENUMERATE_SVG_ATTRIBUTE(y1, "y1") \ __ENUMERATE_SVG_ATTRIBUTE(y1, "y1") \
__ENUMERATE_SVG_ATTRIBUTE(y2, "y2") \ __ENUMERATE_SVG_ATTRIBUTE(y2, "y2") \

View file

@ -193,10 +193,10 @@ void SVGUseElement::clone_element_tree_as_our_shadow_tree(Element* to_clone)
// on the instance root element. However, if the computed value for the property on the use element is // on the instance root element. However, if the computed value for the property on the use element is
// auto, then the property is computed as normal for the element instance. // auto, then the property is computed as normal for the element instance.
if (has_attribute(AttributeNames::width)) { if (has_attribute(AttributeNames::width)) {
MUST(cloned_element.set_attribute(AttributeNames::width, get_attribute_value(AttributeNames::width))); cloned_element.set_attribute_value(AttributeNames::width, get_attribute_value(AttributeNames::width));
} }
if (has_attribute(AttributeNames::height)) { if (has_attribute(AttributeNames::height)) {
MUST(cloned_element.set_attribute(AttributeNames::height, get_attribute_value(AttributeNames::height))); cloned_element.set_attribute_value(AttributeNames::height, get_attribute_value(AttributeNames::height));
} }
} }
shadow_root()->append_child(cloned_reference_node).release_value_but_fixme_should_propagate_errors(); shadow_root()->append_child(cloned_reference_node).release_value_but_fixme_should_propagate_errors();

View file

@ -38,8 +38,8 @@ ErrorOr<GC::Ref<HTML::HTMLCanvasElement>, WebDriver::Error> draw_bounding_box_fr
auto& canvas = as<HTML::HTMLCanvasElement>(*canvas_element); auto& canvas = as<HTML::HTMLCanvasElement>(*canvas_element);
// FIXME: Handle DevicePixelRatio in HiDPI mode. // FIXME: Handle DevicePixelRatio in HiDPI mode.
MUST(canvas.set_width(paint_width)); canvas.set_width(paint_width);
MUST(canvas.set_height(paint_height)); canvas.set_height(paint_height);
// FIXME: 5. Let context, a canvas context mode, be the result of invoking the 2D context creation algorithm given canvas as the target. // FIXME: 5. Let context, a canvas context mode, be the result of invoking the 2D context creation algorithm given canvas as the target.
MUST(canvas.create_2d_context({})); MUST(canvas.create_2d_context({}));

View file

@ -164,23 +164,37 @@ void XMLDocumentBuilder::element_start(XML::Name const& name, OrderedHashMap<XML
if (attribute.key == "xmlns" || attribute.key.starts_with("xmlns:"sv)) { if (attribute.key == "xmlns" || attribute.key.starts_with("xmlns:"sv)) {
// The prefix xmlns is used only to declare namespace bindings and is by definition bound to the namespace name http://www.w3.org/2000/xmlns/. // The prefix xmlns is used only to declare namespace bindings and is by definition bound to the namespace name http://www.w3.org/2000/xmlns/.
if (!attribute.key.is_one_of("xmlns:"sv, "xmlns:xmlns"sv)) { if (!attribute.key.is_one_of("xmlns:"sv, "xmlns:xmlns"sv)) {
if (!node->set_attribute_ns(Namespace::XMLNS, MUST(String::from_byte_string(attribute.key)), Utf16String::from_utf8(attribute.value)).is_error()) auto maybe_extracted_qualified_name = validate_and_extract(node->realm(), Namespace::XMLNS, MUST(String::from_byte_string(attribute.key)), DOM::ValidationContext::Element);
if (!maybe_extracted_qualified_name.is_error()) {
auto extracted_qualified_name = maybe_extracted_qualified_name.release_value();
node->set_attribute_value(extracted_qualified_name.local_name(), MUST(String::from_byte_string(attribute.value)), extracted_qualified_name.prefix(), extracted_qualified_name.namespace_());
continue; continue;
} }
}
m_has_error = true; m_has_error = true;
} else if (attribute.key.contains(':')) { } else if (attribute.key.contains(':')) {
if (auto ns = namespace_for_name(attribute.key); ns.has_value()) { if (auto namespace_for_key = namespace_for_name(attribute.key); namespace_for_key.has_value()) {
if (!node->set_attribute_ns(ns.value(), MUST(String::from_byte_string(attribute.key)), Utf16String::from_utf8(attribute.value)).is_error()) auto maybe_extracted_qualified_name = validate_and_extract(node->realm(), namespace_for_key, MUST(String::from_byte_string(attribute.key)), DOM::ValidationContext::Element);
continue; if (!maybe_extracted_qualified_name.is_error()) {
} else if (attribute.key.starts_with("xml:"sv)) { auto extracted_qualified_name = maybe_extracted_qualified_name.release_value();
if (auto maybe_error = node->set_attribute_ns(Namespace::XML, MUST(String::from_byte_string(attribute.key)), Utf16String::from_utf8(attribute.value)); !maybe_error.is_error()) node->set_attribute_value(extracted_qualified_name.local_name(), MUST(String::from_byte_string(attribute.value)), extracted_qualified_name.prefix(), extracted_qualified_name.namespace_());
continue; continue;
} }
}
if (attribute.key.starts_with("xml:"sv)) {
auto maybe_extracted_qualified_name = validate_and_extract(node->realm(), Namespace::XML, MUST(String::from_byte_string(attribute.key)), DOM::ValidationContext::Element);
if (!maybe_extracted_qualified_name.is_error()) {
auto extracted_qualified_name = maybe_extracted_qualified_name.release_value();
node->set_attribute_value(extracted_qualified_name.local_name(), MUST(String::from_byte_string(attribute.value)), extracted_qualified_name.prefix(), extracted_qualified_name.namespace_());
continue;
}
}
m_has_error = true; m_has_error = true;
} else { } else {
if (!node->set_attribute(MUST(String::from_byte_string(attribute.key)), MUST(String::from_byte_string(attribute.value))).is_error()) node->set_attribute_value(MUST(String::from_byte_string(attribute.key)), MUST(String::from_byte_string(attribute.value)));
continue;
m_has_error = true;
} }
} }

View file

@ -40,6 +40,11 @@ private:
virtual void processing_instruction(StringView target, StringView data) override; virtual void processing_instruction(StringView target, StringView data) override;
virtual void document_end() override; virtual void document_end() override;
struct NamespaceAndPrefix {
FlyString ns;
Optional<ByteString> prefix;
};
Optional<FlyString> namespace_for_name(XML::Name const&); Optional<FlyString> namespace_for_name(XML::Name const&);
GC::Ref<DOM::Document> m_document; GC::Ref<DOM::Document> m_document;
@ -49,11 +54,6 @@ private:
bool m_has_error { false }; bool m_has_error { false };
StringBuilder m_text_builder { StringBuilder::Mode::UTF16 }; StringBuilder m_text_builder { StringBuilder::Mode::UTF16 };
struct NamespaceAndPrefix {
FlyString ns;
Optional<ByteString> prefix;
};
struct NamespaceStackEntry { struct NamespaceStackEntry {
Vector<NamespaceAndPrefix, 2> namespaces; Vector<NamespaceAndPrefix, 2> namespaces;
size_t depth; size_t depth;

View file

@ -4395,7 +4395,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
if (!cpp_value) if (!cpp_value)
impl->remove_attribute("@attribute.reflect_name@"_fly_string); impl->remove_attribute("@attribute.reflect_name@"_fly_string);
else else
MUST(impl->set_attribute("@attribute.reflect_name@"_fly_string, String {})); impl->set_attribute_value("@attribute.reflect_name@"_fly_string, String {});
)~~~"); )~~~");
} else if (attribute.type->name() == "unsigned long") { } else if (attribute.type->name() == "unsigned long") {
// The setter steps are: // The setter steps are:
@ -4411,11 +4411,11 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
u32 new_value = minimum; u32 new_value = minimum;
if (cpp_value >= minimum && cpp_value <= 2147483647) if (cpp_value >= minimum && cpp_value <= 2147483647)
new_value = cpp_value; new_value = cpp_value;
MUST(impl->set_attribute("@attribute.reflect_name@"_fly_string, String::number(new_value))); impl->set_attribute_value("@attribute.reflect_name@"_fly_string, String::number(new_value));
)~~~"); )~~~");
} else if (attribute.type->is_integer() && !attribute.type->is_nullable()) { } else if (attribute.type->is_integer() && !attribute.type->is_nullable()) {
attribute_generator.append(R"~~~( attribute_generator.append(R"~~~(
MUST(impl->set_attribute("@attribute.reflect_name@"_fly_string, String::number(cpp_value))); impl->set_attribute_value("@attribute.reflect_name@"_fly_string, String::number(cpp_value));
)~~~"); )~~~");
} }
// If a reflected IDL attribute has the type T?, where T is either Element or an interface that inherits // If a reflected IDL attribute has the type T?, where T is either Element or an interface that inherits
@ -4431,18 +4431,18 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
static auto content_attribute = "@attribute.reflect_name@"_fly_string; static auto content_attribute = "@attribute.reflect_name@"_fly_string;
if (!cpp_value) { if (!cpp_value) {
TRY(throw_dom_exception_if_needed(vm, [&] { return impl->set_@attribute.cpp_name@({}); })); impl->set_@attribute.cpp_name@({});
impl->remove_attribute(content_attribute); impl->remove_attribute(content_attribute);
return JS::js_undefined(); return JS::js_undefined();
} }
)~~~"); )~~~");
// 2. Run this's set the content attribute with the empty string. // 2. Run this's set the content attribute with the empty string.
attribute_generator.append(R"~~~( attribute_generator.append(R"~~~(
MUST(impl->set_attribute(content_attribute, String {})); impl->set_attribute_value(content_attribute, String {});
)~~~"); )~~~");
// 3. Set this's explicitly set attr-element to a weak reference to the given value. // 3. Set this's explicitly set attr-element to a weak reference to the given value.
attribute_generator.append(R"~~~( attribute_generator.append(R"~~~(
TRY(throw_dom_exception_if_needed(vm, [&] { return impl->set_@attribute.cpp_name@(*cpp_value); })); impl->set_@attribute.cpp_name@(*cpp_value);
)~~~"); )~~~");
} }
// If a reflected IDL attribute has the type FrozenArray<T>?, where T is either Element or an interface // If a reflected IDL attribute has the type FrozenArray<T>?, where T is either Element or an interface
@ -4457,7 +4457,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
static auto content_attribute = "@attribute.reflect_name@"_fly_string; static auto content_attribute = "@attribute.reflect_name@"_fly_string;
if (!cpp_value.has_value()) { if (!cpp_value.has_value()) {
TRY(throw_dom_exception_if_needed(vm, [&] { return impl->set_@attribute.cpp_name@({}); })); impl->set_@attribute.cpp_name@({});
impl->remove_attribute(content_attribute); impl->remove_attribute(content_attribute);
return JS::js_undefined(); return JS::js_undefined();
} }
@ -4465,7 +4465,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
// 2. Run this's set the content attribute with the empty string. // 2. Run this's set the content attribute with the empty string.
attribute_generator.append(R"~~~( attribute_generator.append(R"~~~(
MUST(impl->set_attribute(content_attribute, String {})); impl->set_attribute_value(content_attribute, String {});
)~~~"); )~~~");
// 3. Let elements be an empty list. // 3. Let elements be an empty list.
@ -4480,18 +4480,18 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
elements.unchecked_append(*element); elements.unchecked_append(*element);
} }
TRY(throw_dom_exception_if_needed(vm, [&] { return impl->set_@attribute.cpp_name@(move(elements)); })); impl->set_@attribute.cpp_name@(move(elements));
)~~~"); )~~~");
} else if (attribute.type->is_nullable()) { } else if (attribute.type->is_nullable()) {
attribute_generator.append(R"~~~( attribute_generator.append(R"~~~(
if (!cpp_value.has_value()) if (!cpp_value.has_value())
impl->remove_attribute("@attribute.reflect_name@"_fly_string); impl->remove_attribute("@attribute.reflect_name@"_fly_string);
else else
TRY(throw_dom_exception_if_needed(vm, [&] { return impl->set_attribute("@attribute.reflect_name@"_fly_string, cpp_value.value()); })); impl->set_attribute_value("@attribute.reflect_name@"_fly_string, cpp_value.value());
)~~~"); )~~~");
} else { } else {
attribute_generator.append(R"~~~( attribute_generator.append(R"~~~(
TRY(throw_dom_exception_if_needed(vm, [&] { return impl->set_attribute("@attribute.reflect_name@"_fly_string, cpp_value); })); impl->set_attribute_value("@attribute.reflect_name@"_fly_string, cpp_value);
)~~~"); )~~~");
} }

View file

@ -770,7 +770,7 @@ void ConnectionFromClient::add_dom_node_attributes(u64 page_id, Web::UniqueNodeI
for (auto const& attribute : attributes) { for (auto const& attribute : attributes) {
// NOTE: We ignore invalid attributes for now, but we may want to send feedback to the user that this failed. // NOTE: We ignore invalid attributes for now, but we may want to send feedback to the user that this failed.
(void)element.set_attribute(attribute.name, attribute.value); element.set_attribute_value(attribute.name, attribute.value);
} }
async_did_finish_editing_dom_node(page_id, element.unique_id()); async_did_finish_editing_dom_node(page_id, element.unique_id());
@ -792,7 +792,7 @@ void ConnectionFromClient::replace_dom_node_attribute(u64 page_id, Web::UniqueNo
should_remove_attribute = false; should_remove_attribute = false;
// NOTE: We ignore invalid attributes for now, but we may want to send feedback to the user that this failed. // NOTE: We ignore invalid attributes for now, but we may want to send feedback to the user that this failed.
(void)element.set_attribute(attribute.name, attribute.value); element.set_attribute_value(attribute.name, attribute.value);
} }
if (should_remove_attribute) if (should_remove_attribute)
@ -1299,7 +1299,7 @@ void ConnectionFromClient::retrieved_clipboard_entries(u64 page_id, u64 request_
void ConnectionFromClient::toggle_media_play_state(u64 page_id) void ConnectionFromClient::toggle_media_play_state(u64 page_id)
{ {
if (auto page = this->page(page_id); page.has_value()) if (auto page = this->page(page_id); page.has_value())
page->page().toggle_media_play_state().release_value_but_fixme_should_propagate_errors(); page->page().toggle_media_play_state();
} }
void ConnectionFromClient::toggle_media_mute_state(u64 page_id) void ConnectionFromClient::toggle_media_mute_state(u64 page_id)
@ -1311,13 +1311,13 @@ void ConnectionFromClient::toggle_media_mute_state(u64 page_id)
void ConnectionFromClient::toggle_media_loop_state(u64 page_id) void ConnectionFromClient::toggle_media_loop_state(u64 page_id)
{ {
if (auto page = this->page(page_id); page.has_value()) if (auto page = this->page(page_id); page.has_value())
page->page().toggle_media_loop_state().release_value_but_fixme_should_propagate_errors(); page->page().toggle_media_loop_state();
} }
void ConnectionFromClient::toggle_media_controls_state(u64 page_id) void ConnectionFromClient::toggle_media_controls_state(u64 page_id)
{ {
if (auto page = this->page(page_id); page.has_value()) if (auto page = this->page(page_id); page.has_value())
page->page().toggle_media_controls_state().release_value_but_fixme_should_propagate_errors(); page->page().toggle_media_controls_state();
} }
void ConnectionFromClient::toggle_page_mute_state(u64 page_id) void ConnectionFromClient::toggle_page_mute_state(u64 page_id)

View file

@ -442,9 +442,9 @@ void PageClient::select_dropdown_closed(Optional<u32> const& selected_item_id)
page().select_dropdown_closed(selected_item_id); page().select_dropdown_closed(selected_item_id);
} }
Web::WebIDL::ExceptionOr<void> PageClient::toggle_media_play_state() void PageClient::toggle_media_play_state()
{ {
return page().toggle_media_play_state(); page().toggle_media_play_state();
} }
void PageClient::toggle_media_mute_state() void PageClient::toggle_media_mute_state()
@ -452,14 +452,14 @@ void PageClient::toggle_media_mute_state()
page().toggle_media_mute_state(); page().toggle_media_mute_state();
} }
Web::WebIDL::ExceptionOr<void> PageClient::toggle_media_loop_state() void PageClient::toggle_media_loop_state()
{ {
return page().toggle_media_loop_state(); page().toggle_media_loop_state();
} }
Web::WebIDL::ExceptionOr<void> PageClient::toggle_media_controls_state() void PageClient::toggle_media_controls_state()
{ {
return page().toggle_media_controls_state(); page().toggle_media_controls_state();
} }
void PageClient::set_user_style(String source) void PageClient::set_user_style(String source)

View file

@ -64,10 +64,10 @@ public:
void set_window_position(Web::DevicePixelPoint); void set_window_position(Web::DevicePixelPoint);
void set_window_size(Web::DevicePixelSize); void set_window_size(Web::DevicePixelSize);
Web::WebIDL::ExceptionOr<void> toggle_media_play_state(); void toggle_media_play_state();
void toggle_media_mute_state(); void toggle_media_mute_state();
Web::WebIDL::ExceptionOr<void> toggle_media_loop_state(); void toggle_media_loop_state();
Web::WebIDL::ExceptionOr<void> toggle_media_controls_state(); void toggle_media_controls_state();
void alert_closed(); void alert_closed();
void confirm_closed(bool accepted); void confirm_closed(bool accepted);