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) \
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
#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); }));
// 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);
@ -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.)
if (!src_value.is_undefined()) {
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.

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.
if (vm.argument_count() > 0) {
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.
if (vm.argument_count() > 1) {
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.

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.
if (!vm.argument(1).is_undefined()) {
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.
if (vm.argument_count() > 2) {
auto default_selected = vm.argument(2).to_boolean();
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);
// 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.
set_is_updating(false);

View file

@ -258,7 +258,7 @@ void DOMTokenList::set_value(String const& value)
if (!associated_element)
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
@ -294,7 +294,7 @@ void DOMTokenList::run_update_steps()
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.
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

View file

@ -3189,7 +3189,7 @@ String Document::fg_color() const
void Document::set_fg_color(String const& value)
{
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
@ -3202,7 +3202,7 @@ String Document::link_color() const
void Document::set_link_color(String const& value)
{
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
@ -3215,7 +3215,7 @@ String Document::vlink_color() const
void Document::set_vlink_color(String const& value)
{
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
@ -3228,7 +3228,7 @@ String Document::alink_color() const
void Document::set_alink_color(String const& value)
{
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
@ -3241,7 +3241,7 @@ String Document::bg_color() const
void Document::set_bg_color(String const& value)
{
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

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));
MUST(style_element->set_text_content(R"~~~(
style_element->string_replace_all(R"~~~(
:root {
background-color: #222;
}
@ -310,29 +310,29 @@ static WebIDL::ExceptionOr<GC::Ref<DOM::Document>> load_media_document(HTML::Nav
img {
background-color: #fff;
}
)~~~"_utf16));
)~~~"_utf16);
TRY(document->head()->append_child(style_element));
auto url_string = document->url_string();
if (type.is_image()) {
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(insert_title(document, url_string));
} else if (type.type() == "video"sv) {
auto video_element = TRY(DOM::create_element(document, HTML::TagNames::video, Namespace::HTML));
TRY(video_element->set_attribute(HTML::AttributeNames::src, url_string));
TRY(video_element->set_attribute(HTML::AttributeNames::autoplay, String {}));
TRY(video_element->set_attribute(HTML::AttributeNames::controls, String {}));
video_element->set_attribute_value(HTML::AttributeNames::src, url_string);
video_element->set_attribute_value(HTML::AttributeNames::autoplay, String {});
video_element->set_attribute_value(HTML::AttributeNames::controls, String {});
TRY(document->body()->append_child(video_element));
TRY(insert_title(document, url_string));
} else if (type.type() == "audio"sv) {
auto audio_element = TRY(DOM::create_element(document, HTML::TagNames::audio, Namespace::HTML));
TRY(audio_element->set_attribute(HTML::AttributeNames::src, url_string));
TRY(audio_element->set_attribute(HTML::AttributeNames::autoplay, String {}));
TRY(audio_element->set_attribute(HTML::AttributeNames::controls, String {}));
audio_element->set_attribute_value(HTML::AttributeNames::src, url_string);
audio_element->set_attribute_value(HTML::AttributeNames::autoplay, String {});
audio_element->set_attribute_value(HTML::AttributeNames::controls, String {});
TRY(document->body()->append_child(audio_element));
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
// 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.
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
// 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(
[](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); }));
@ -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
// 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".
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
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.
return attributes()->set_attribute(attr);
}
// 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.
return attributes()->set_attribute(attr);
@ -1746,7 +1746,7 @@ i32 Element::tab_index() const
// https://html.spec.whatwg.org/multipage/interaction.html#dom-tabindex
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
@ -2544,6 +2544,22 @@ ErrorOr<void> Element::scroll_into_view(Optional<Variant<bool, ScrollIntoViewOpt
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)
{
Vector<CSS::InvalidationSet::Property, 1> changed_properties;

View file

@ -149,13 +149,13 @@ public:
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(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>, 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_ = {});
WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node(Attr&);
WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node_ns(Attr&);
WebIDL::ExceptionOr<GC::Ptr<Attr>> set_attribute_node_for_bindings(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(Attr&);
@ -336,20 +336,9 @@ public:
ErrorOr<void> scroll_into_view(Optional<Variant<bool, ScrollIntoViewOptions>> = {});
// https://www.w3.org/TR/wai-aria-1.2/#ARIAMixin
#define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \
Optional<String> name() const 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 {}; \
}
#define __ENUMERATE_ARIA_ATTRIBUTE(name, attribute) \
virtual Optional<String> name() const override; \
virtual void set_##name(Optional<String> const& value) override;
ENUMERATE_ARIA_ATTRIBUTES
#undef __ENUMERATE_ARIA_ATTRIBUTE

View file

@ -54,8 +54,8 @@ interface Element : Node {
sequence<DOMString> getAttributeNames();
DOMString? getAttribute(DOMString qualifiedName);
DOMString? getAttributeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName);
[CEReactions] 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_for_bindings] undefined setAttribute(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 removeAttributeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName);
[CEReactions] boolean toggleAttribute(DOMString qualifiedName, optional boolean force);
@ -64,8 +64,8 @@ interface Element : Node {
Attr? getAttributeNode([FlyString] DOMString qualifiedName);
Attr? getAttributeNodeNS([FlyString] DOMString? namespace, [FlyString] DOMString localName);
[CEReactions] Attr? setAttributeNode(Attr attr);
[CEReactions] Attr? setAttributeNodeNS(Attr attr);
[CEReactions, ImplementedAs=set_attribute_node_for_bindings] Attr? setAttributeNode(Attr attr);
[CEReactions, ImplementedAs=set_attribute_node_ns_for_bindings] Attr? setAttributeNodeNS(Attr attr);
[CEReactions] Attr removeAttributeNode(Attr attr);
ShadowRoot attachShadow(ShadowRootInit init);

View file

@ -86,7 +86,7 @@ bool command_create_link_action(DOM::Document& document, Utf16String const& valu
return IterationDecision::Break;
if (auto* anchor = as_if<HTML::HTMLAnchorElement>(*ancestor); anchor && anchor->is_editable()
&& 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());
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));
// 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.
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.
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.

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
// 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.
if (command == CommandNames::fontName) {
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));
// 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.
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
// * xxx-large: 7
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
@ -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.
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.

View file

@ -48,11 +48,10 @@ String AutocompleteElement::autocomplete() const
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.
TRY(autocomplete_element_to_html_element().set_attribute(AttributeNames::autocomplete, value));
return {};
autocomplete_element_to_html_element().set_attribute_value(AttributeNames::autocomplete, value);
}
enum class Category {

View file

@ -30,7 +30,7 @@ public:
Vector<String> autocomplete_tokens() 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
// 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);
// 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 {};
}

View file

@ -230,10 +230,10 @@ String FormAssociatedElement::form_action() const
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();
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

View file

@ -138,7 +138,7 @@ public:
virtual void clear_algorithm();
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
bool report_validity();

View file

@ -57,9 +57,9 @@ Optional<String> HTMLAnchorElement::hyperlink_element_utils_href() const
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

View file

@ -55,7 +55,7 @@ private:
virtual DOM::Document& hyperlink_element_utils_document() override { return document(); }
virtual DOM::Element& hyperlink_element_utils_element() override { return *this; }
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 bool hyperlink_element_utils_is_html_anchor_element() const final { return true; }
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);
}
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

View file

@ -38,7 +38,7 @@ private:
virtual DOM::Document& hyperlink_element_utils_document() override { return document(); }
virtual DOM::Element& hyperlink_element_utils_element() override { return *this; }
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 bool hyperlink_element_utils_is_html_anchor_element() const override { return false; }
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
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.
return set_attribute(AttributeNames::href, href);
set_attribute_value(AttributeNames::href, href);
}
}

View file

@ -18,7 +18,7 @@ public:
virtual ~HTMLBaseElement() override;
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; }

View file

@ -93,10 +93,10 @@ String HTMLButtonElement::type_for_bindings() const
}
// 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.
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_)
@ -339,9 +339,9 @@ String HTMLButtonElement::command() const
}
// 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;
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;
@ -81,7 +81,7 @@ public:
virtual void activation_behavior(DOM::Event const&) override;
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; }
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] attribute DOMString name;
[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 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)
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();
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)
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();
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_)

View file

@ -34,8 +34,8 @@ public:
WebIDL::UnsignedLong width() const;
WebIDL::UnsignedLong height() const;
WebIDL::ExceptionOr<void> set_width(WebIDL::UnsignedLong);
WebIDL::ExceptionOr<void> set_height(WebIDL::UnsignedLong);
void set_width(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;

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:
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 {
display: list-item;
counter-increment: list-item 0;
@ -252,7 +252,8 @@ WebIDL::ExceptionOr<void> HTMLDetailsElement::create_shadow_tree_if_needed()
:host([open]) summary {
list-style-type: disclosure-open;
}
)~~~"_utf16));
)~~~"_utf16);
MUST(style->append_child(style_text));
MUST(shadow_root->append_child(style));
m_summary_slot = static_cast<HTML::HTMLSlotElement&>(*summary_slot);
@ -300,14 +301,14 @@ void HTMLDetailsElement::update_shadow_tree_style()
return;
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;
)~~~"_string));
)~~~"_string);
} else {
MUST(m_descendants_slot->set_attribute(HTML::AttributeNames::style, R"~~~(
m_descendants_slot->set_attribute_value(HTML::AttributeNames::style, R"~~~(
display: block;
content-visibility: hidden;
)~~~"_string));
)~~~"_string);
}
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);
// 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.
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);
// 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.
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
// attribute's value to "no" otherwise.
if (new_value)
MUST(set_attribute(HTML::AttributeNames::translate, "yes"_string));
set_attribute_value(HTML::AttributeNames::translate, "yes"_string);
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
@ -144,7 +144,7 @@ StringView HTMLElement::dir() const
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
@ -183,15 +183,15 @@ WebIDL::ExceptionOr<void> HTMLElement::set_content_editable(StringView content_e
return {};
}
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 {};
}
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 {};
}
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 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>()) {
auto const& string = given_value.get<String>();
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;
}
// 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.
MUST(set_attribute(HTML::AttributeNames::hidden, ""_string));
set_attribute_value(HTML::AttributeNames::hidden, ""_string);
}
// 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
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.
// The popover IDL attribute must reflect the popover attribute, limited to only known values.
if (value.has_value())
return set_attribute(HTML::AttributeNames::popover, value.release_value());
remove_attribute(HTML::AttributeNames::popover);
return {};
set_attribute_value(HTML::AttributeNames::popover, value.release_value());
else
remove_attribute(HTML::AttributeNames::popover);
}
void HTMLElement::adjust_computed_style(CSS::ComputedProperties& style)
@ -2143,6 +2142,11 @@ bool HTMLElement::draggable() const
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
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".
if (spellcheck)
MUST(set_attribute(HTML::AttributeNames::spellcheck, "true"_string));
set_attribute_value(HTML::AttributeNames::spellcheck, "true"_string);
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
@ -2239,7 +2243,7 @@ String HTMLElement::writing_suggestions() const
void HTMLElement::set_writing_suggestions(String const& 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
@ -2332,7 +2336,7 @@ String HTMLElement::autocapitalize() const
void HTMLElement::set_autocapitalize(String const& 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
@ -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".
if (given_value)
MUST(set_attribute(HTML::AttributeNames::autocorrect, "on"_string));
set_attribute_value(HTML::AttributeNames::autocorrect, "on"_string);
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<void> set_popover(Optional<String> value);
void set_popover(Optional<String> value);
Optional<String> popover() const;
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 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 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
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.
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
@ -715,9 +715,9 @@ String HTMLFormElement::action() const
}
// 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_)

View file

@ -96,12 +96,12 @@ public:
bool constructing_entry_list() const { return m_constructing_entry_list; }
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();
String action() const;
WebIDL::ExceptionOr<void> set_action(String const&);
void set_action(String 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
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.
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
void HTMLHyperlinkElementUtils::update_href()
{
// 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

View file

@ -21,7 +21,7 @@ public:
String origin() const;
String href() const;
WebIDL::ExceptionOr<void> set_href(String);
void set_href(String);
String protocol() const;
void set_protocol(StringView);
@ -54,7 +54,7 @@ protected:
virtual DOM::Document& hyperlink_element_utils_document() = 0;
virtual DOM::Element& hyperlink_element_utils_element() = 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 bool hyperlink_element_utils_is_html_anchor_element() 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/TraversableNavigable.h>
#include <LibWeb/Layout/NavigableContainerViewport.h>
#include <LibWeb/TrustedTypes/TrustedTypePolicy.h>
#include <LibWeb/TrustedTypes/RequireTrustedTypesForDirective.h>
#include <LibWeb/TrustedTypes/TrustedTypePolicy.h>
namespace Web::HTML {

View file

@ -242,11 +242,11 @@ WebIDL::UnsignedLong HTMLImageElement::width() const
return 0;
}
WebIDL::ExceptionOr<void> HTMLImageElement::set_width(WebIDL::UnsignedLong width)
void HTMLImageElement::set_width(WebIDL::UnsignedLong width)
{
if (width > 2147483647)
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
@ -273,11 +273,11 @@ WebIDL::UnsignedLong HTMLImageElement::height() const
return 0;
}
WebIDL::ExceptionOr<void> HTMLImageElement::set_height(WebIDL::UnsignedLong height)
void HTMLImageElement::set_height(WebIDL::UnsignedLong height)
{
if (height > 2147483647)
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

View file

@ -53,10 +53,10 @@ public:
virtual RefPtr<Gfx::ImmutableBitmap> default_image_bitmap_sized(Gfx::IntSize) const override;
WebIDL::UnsignedLong width() const;
WebIDL::ExceptionOr<void> set_width(WebIDL::UnsignedLong);
void set_width(WebIDL::UnsignedLong);
WebIDL::UnsignedLong height() const;
WebIDL::ExceptionOr<void> set_height(WebIDL::UnsignedLong);
void set_height(WebIDL::UnsignedLong);
unsigned natural_width() 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::DefaultOn:
// 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;
// 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);
set_shadow_root(shadow_root);
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());
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));
m_text_node = realm().create<DOM::Text>(document(), Utf16String {});
m_text_node = realm().create<DOM::Text>(document(), m_value);
if (type_state() == TypeAttributeState::Password)
m_text_node->set_is_password_input({}, true);
MUST(m_text_node->set_text_content(m_value));
handle_maxlength_attribute();
MUST(m_inner_text_element->append_child(*m_text_node));
@ -1099,11 +1098,22 @@ void HTMLInputElement::create_text_input_shadow_tree()
// Up button
auto up_button = MUST(DOM::create_element(document(), HTML::TagNames::button, Namespace::HTML));
// 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;
cursor: default;
)~~~"_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));
)~~~"_string);
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));
auto mouseup_callback_function = JS::NativeFunction::create(
@ -1131,11 +1141,22 @@ void HTMLInputElement::create_text_input_shadow_tree()
// Down button
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;
cursor: default;
)~~~"_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));
)~~~"_string);
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));
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 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;
height: fit-content;
padding: 4px;
border: 1px solid ButtonBorder;
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();
MUST(m_color_well_element->set_attribute(HTML::AttributeNames::style, R"~~~(
m_color_well_element->set_attribute_value(HTML::AttributeNames::style, R"~~~(
width: 32px;
height: 16px;
border: 1px solid ButtonBorder;
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(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_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&) {
show_the_picker_if_applicable(*this);
@ -1225,15 +1246,15 @@ void HTMLInputElement::update_file_input_shadow_tree()
return;
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->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
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 {
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
// 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))) {
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
@ -1619,9 +1640,9 @@ StringView HTMLInputElement::type() const
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
@ -2172,7 +2193,8 @@ WebIDL::Long HTMLInputElement::max_length() const
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.
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
@ -2189,7 +2211,8 @@ WebIDL::Long HTMLInputElement::min_length() const
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.
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
@ -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);
if (value > 2147483647)
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
@ -2240,12 +2264,12 @@ WebIDL::UnsignedLong HTMLInputElement::height() const
return 0;
}
WebIDL::ExceptionOr<void> HTMLInputElement::set_height(WebIDL::UnsignedLong value)
void HTMLInputElement::set_height(WebIDL::UnsignedLong value)
{
if (value > 2147483647)
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
@ -2275,12 +2299,12 @@ WebIDL::UnsignedLong HTMLInputElement::width() const
return 0;
}
WebIDL::ExceptionOr<void> HTMLInputElement::set_width(WebIDL::UnsignedLong value)
void HTMLInputElement::set_width(WebIDL::UnsignedLong value)
{
if (value > 2147483647)
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

View file

@ -76,7 +76,7 @@ public:
StringView type() const;
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); }
@ -139,10 +139,10 @@ public:
WebIDL::ExceptionOr<void> set_size(WebIDL::UnsignedLong value);
WebIDL::UnsignedLong height() const;
WebIDL::ExceptionOr<void> set_height(WebIDL::UnsignedLong value);
void set_height(WebIDL::UnsignedLong value);
WebIDL::UnsignedLong width() const;
WebIDL::ExceptionOr<void> set_width(WebIDL::UnsignedLong value);
void set_width(WebIDL::UnsignedLong value);
struct SelectedCoordinate {
int x { 0 };

View file

@ -52,6 +52,11 @@ WebIDL::Long HTMLLIElement::value()
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
{
if (Base::is_presentational_hint(name))

View file

@ -36,10 +36,7 @@ public:
}
WebIDL::Long value();
void set_value(WebIDL::Long value)
{
MUST(set_attribute(AttributeNames::value, String::number(value)));
}
void set_value(WebIDL::Long value);
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)set_attribute(HTML::AttributeNames::media, media);
set_attribute_value(HTML::AttributeNames::media, media);
if (auto sheet = m_loaded_style_sheet)
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
WebIDL::ExceptionOr<void> HTMLMarqueeElement::set_scroll_amount(WebIDL::UnsignedLong value)
void HTMLMarqueeElement::set_scroll_amount(WebIDL::UnsignedLong value)
{
if (value > 2147483647)
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
@ -106,11 +106,11 @@ WebIDL::UnsignedLong HTMLMarqueeElement::scroll_delay()
}
// 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)
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;
WebIDL::UnsignedLong scroll_amount();
WebIDL::ExceptionOr<void> set_scroll_amount(WebIDL::UnsignedLong);
void set_scroll_amount(WebIDL::UnsignedLong);
WebIDL::UnsignedLong scroll_delay();
WebIDL::ExceptionOr<void> set_scroll_delay(WebIDL::UnsignedLong);
void set_scroll_delay(WebIDL::UnsignedLong);
private:
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]() {
// If the media element's node document stops being a fully active document, then the playback will stop until
// the document is active again.
pause_element().release_value_but_fixme_should_propagate_errors();
pause_element();
});
document().page().register_media_element({}, unique_id());
@ -136,7 +136,7 @@ void HTMLMediaElement::removed_from(DOM::Node* old_parent, DOM::Node& old_root)
return;
// 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
@ -369,7 +369,7 @@ void HTMLMediaElement::set_duration(double duration)
paintable->set_needs_display();
}
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> HTMLMediaElement::play()
GC::Ref<WebIDL::Promise> HTMLMediaElement::play()
{
auto& realm = this->realm();
@ -387,37 +387,33 @@ WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> HTMLMediaElement::play()
m_pending_play_promises.append(promise);
// 4. Run the internal play steps for the media element.
TRY(play_element());
play_element();
// 5. Return promise.
return promise;
}
// 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
// selection algorithm.
if (m_network_state == NetworkState::Empty)
TRY(select_resource());
select_resource();
// 2. Run the internal pause steps for the media element.
TRY(pause_element());
return {};
pause_element();
}
WebIDL::ExceptionOr<void> HTMLMediaElement::toggle_playback()
void HTMLMediaElement::toggle_playback()
{
// AD-HOC: An execution context is required for Promise creation hooks.
TemporaryExecutionContext execution_context { realm() };
if (potentially_playing())
TRY(pause());
pause();
else
TRY(play());
return {};
play();
}
// 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;
// 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.
return {};
@ -825,7 +821,7 @@ void HTMLMediaElement::children_changed(ChildrenChangedMetadata const* metadata)
}
// 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();
@ -972,8 +968,6 @@ WebIDL::ExceptionOr<void> HTMLMediaElement::select_resource()
break;
}
});
return {};
}
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
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
// selection algorithm.
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
// 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.
m_can_autoplay = false;
return {};
}
// 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.
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.
m_official_playback_position = m_current_playback_position;
}
return {};
}
// 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::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)
return false;
switch (key) {
case UIEvents::KeyCode::Key_Space:
TRY(toggle_playback());
toggle_playback();
break;
case UIEvents::KeyCode::Key_Home:
@ -2258,7 +2248,8 @@ WebIDL::ExceptionOr<bool> HTMLMediaElement::handle_keydown(Badge<Web::EventHandl
else
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;
}

View file

@ -48,7 +48,7 @@ public:
void set_decoder_error(String error_message);
String const& current_src() const { return m_current_src; }
WebIDL::ExceptionOr<void> select_resource();
void select_resource();
enum class NetworkState : u16 {
Empty,
@ -106,9 +106,9 @@ public:
bool paused() const { return m_paused; }
bool ended() const;
bool potentially_playing() const;
WebIDL::ExceptionOr<GC::Ref<WebIDL::Promise>> play();
WebIDL::ExceptionOr<void> pause();
WebIDL::ExceptionOr<void> toggle_playback();
GC::Ref<WebIDL::Promise> play();
void pause();
void toggle_playback();
double volume() const { return m_volume; }
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);
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 {
PlaybackButton,
@ -203,8 +203,8 @@ private:
void set_ready_state(ReadyState);
void on_playback_manager_state_change();
WebIDL::ExceptionOr<void> play_element();
WebIDL::ExceptionOr<void> pause_element();
void play_element();
void pause_element();
void seek_element(double playback_position, MediaSeekMode = MediaSeekMode::Accurate);
void finish_seeking_element();
void notify_about_playing();

View file

@ -54,11 +54,10 @@ double HTMLMeterElement::value() const
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();
return {};
}
// https://html.spec.whatwg.org/multipage/form-elements.html#concept-meter-minimum
@ -72,11 +71,10 @@ double HTMLMeterElement::min() const
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();
return {};
}
// 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());
}
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();
return {};
}
// 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());
}
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();
return {};
}
// 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());
}
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();
return {};
}
// 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());
}
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();
return {};
}
void HTMLMeterElement::inserted()

View file

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

View file

@ -52,6 +52,11 @@ WebIDL::Long HTMLOListElement::start()
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
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; }
WebIDL::Long start();
void set_start(WebIDL::Long start)
{
MUST(set_attribute(AttributeNames::start, String::number(start)));
}
void set_start(WebIDL::Long start);
AK::Checked<i32> starting_value() const;

View file

@ -180,6 +180,11 @@ String HTMLObjectElement::data() const
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)
{
switch (m_representation) {

View file

@ -37,7 +37,7 @@ public:
virtual void form_associated_element_was_removed(DOM::Node*) override;
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); }

View file

@ -99,9 +99,9 @@ Utf16String HTMLOptionElement::value() const
}
// 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)
@ -129,7 +129,7 @@ String HTMLOptionElement::label() const
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-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
}

View file

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

View file

@ -51,14 +51,13 @@ double HTMLProgressElement::value() const
return 0;
}
WebIDL::ExceptionOr<void> HTMLProgressElement::set_value(double value)
void HTMLProgressElement::set_value(double value)
{
if (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();
return {};
}
// https://html.spec.whatwg.org/multipage/form-elements.html#dom-progress-max
@ -72,14 +71,13 @@ WebIDL::Double HTMLProgressElement::max() const
return 1;
}
WebIDL::ExceptionOr<void> HTMLProgressElement::set_max(double value)
void HTMLProgressElement::set_max(double value)
{
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();
return {};
}
double HTMLProgressElement::position() const

View file

@ -20,10 +20,10 @@ public:
virtual ~HTMLProgressElement() override;
double value() const;
WebIDL::ExceptionOr<void> set_value(double);
void set_value(double);
WebIDL::Double max() const;
WebIDL::ExceptionOr<void> set_max(WebIDL::Double value);
void set_max(WebIDL::Double value);
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.
if (async) {
MUST(set_attribute(HTML::AttributeNames::async, ""_string));
set_attribute_value(HTML::AttributeNames::async, ""_string);
}
// 3. Otherwise, remove this's async content attribute.
else {

View file

@ -110,11 +110,11 @@ WebIDL::UnsignedLong HTMLSelectElement::size() const
return 0;
}
WebIDL::ExceptionOr<void> HTMLSelectElement::set_size(WebIDL::UnsignedLong size)
void HTMLSelectElement::set_size(WebIDL::UnsignedLong size)
{
if (size > 2147483647)
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
@ -590,29 +590,36 @@ void HTMLSelectElement::create_shadow_tree_if_needed()
set_shadow_root(shadow_root);
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;
align-items: center;
height: 100%;
)~~~"_string));
)~~~"_string);
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();
MUST(m_inner_text_element->set_attribute(HTML::AttributeNames::style, R"~~~(
m_inner_text_element->set_attribute_value(HTML::AttributeNames::style, R"~~~(
flex: 1;
)~~~"_string));
)~~~"_string);
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();
MUST(m_chevron_icon_element->set_attribute(HTML::AttributeNames::style, R"~~~(
m_chevron_icon_element->set_attribute_value(HTML::AttributeNames::style, R"~~~(
width: 16px;
height: 16px;
margin-left: 4px;
)~~~"_string));
MUST(m_chevron_icon_element->set_inner_html(Utf16String::from_utf8(chevron_svg)));
)~~~"_string);
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));
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
for (auto const& option_element : m_cached_list_of_options) {
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;
}
}

View file

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

View file

@ -41,7 +41,7 @@ void HTMLSourceElement::inserted()
if (auto* media_element = as_if<HTMLMediaElement>(parent); media_element
&& !media_element->has_attribute(HTML::AttributeNames::src)
&& 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

View file

@ -37,7 +37,7 @@ void HTMLSummaryElement::activation_behavior(DOM::Event const&)
if (parent->has_attribute(HTML::AttributeNames::open))
parent->remove_attribute(HTML::AttributeNames::open);
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

View file

@ -157,11 +157,11 @@ WebIDL::UnsignedLong HTMLTableCellElement::col_span() const
return value;
}
WebIDL::ExceptionOr<void> HTMLTableCellElement::set_col_span(WebIDL::UnsignedLong value)
void HTMLTableCellElement::set_col_span(WebIDL::UnsignedLong value)
{
if (value > 2147483647)
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:
@ -187,11 +187,11 @@ WebIDL::UnsignedLong HTMLTableCellElement::row_span() const
return *optional_value;
}
WebIDL::ExceptionOr<void> HTMLTableCellElement::set_row_span(WebIDL::UnsignedLong value)
void HTMLTableCellElement::set_row_span(WebIDL::UnsignedLong value)
{
if (value > 2147483647)
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

View file

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

View file

@ -44,11 +44,11 @@ WebIDL::UnsignedLong HTMLTableColElement::span() const
return 1;
}
WebIDL::ExceptionOr<void> HTMLTableColElement::set_span(unsigned int value)
void HTMLTableColElement::set_span(unsigned int value)
{
if (value > 2147483647)
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

View file

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

View file

@ -117,7 +117,7 @@ void HTMLTextAreaElement::reset_algorithm()
set_raw_value(child_text_content());
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();
}
}
@ -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".
if (api_value() != old_api_value) {
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();
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)
{
// 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
@ -261,7 +262,8 @@ WebIDL::Long HTMLTextAreaElement::min_length() const
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.
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
@ -275,12 +277,12 @@ unsigned HTMLTextAreaElement::cols() const
return 20;
}
WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_cols(WebIDL::UnsignedLong cols)
void HTMLTextAreaElement::set_cols(WebIDL::UnsignedLong cols)
{
if (cols == 0 || cols > 2147483647)
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
@ -294,12 +296,12 @@ WebIDL::UnsignedLong HTMLTextAreaElement::rows() const
return 2;
}
WebIDL::ExceptionOr<void> HTMLTextAreaElement::set_rows(WebIDL::UnsignedLong rows)
void HTMLTextAreaElement::set_rows(WebIDL::UnsignedLong rows)
{
if (rows == 0 || rows > 2147483647)
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
@ -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));
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.
// 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();
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) {
set_raw_value(child_text_content());
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();
}
}

View file

@ -105,10 +105,10 @@ public:
WebIDL::ExceptionOr<void> set_min_length(WebIDL::Long);
WebIDL::UnsignedLong cols() const;
WebIDL::ExceptionOr<void> set_cols(unsigned);
void set_cols(unsigned);
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
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();
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;
}

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);
}
WebIDL::ExceptionOr<void> Page::toggle_media_play_state()
void Page::toggle_media_play_state()
{
auto media_element = media_context_menu_element();
if (!media_element)
return {};
return;
// AD-HOC: An execution context is required for Promise creation hooks.
HTML::TemporaryExecutionContext execution_context { media_element->realm() };
if (media_element->potentially_playing())
TRY(media_element->pause());
media_element->pause();
else
TRY(media_element->play());
return {};
media_element->play();
}
void Page::toggle_media_mute_state()
@ -544,11 +542,11 @@ void Page::toggle_media_mute_state()
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();
if (!media_element)
return {};
return;
// AD-HOC: An execution context is required for Promise creation hooks.
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))
media_element->remove_attribute(HTML::AttributeNames::loop);
else
TRY(media_element->set_attribute(HTML::AttributeNames::loop, String {}));
return {};
media_element->set_attribute_value(HTML::AttributeNames::loop, String {});
}
WebIDL::ExceptionOr<void> Page::toggle_media_controls_state()
void Page::toggle_media_controls_state()
{
auto media_element = media_context_menu_element();
if (!media_element)
return {};
return;
HTML::TemporaryExecutionContext execution_context { media_element->realm() };
if (media_element->has_attribute(HTML::AttributeNames::controls))
media_element->remove_attribute(HTML::AttributeNames::controls);
else
TRY(media_element->set_attribute(HTML::AttributeNames::controls, String {}));
return {};
media_element->set_attribute_value(HTML::AttributeNames::controls, String {});
}
void Page::toggle_page_mute_state()

View file

@ -194,10 +194,10 @@ public:
bool is_looping { false };
};
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();
WebIDL::ExceptionOr<void> toggle_media_loop_state();
WebIDL::ExceptionOr<void> toggle_media_controls_state();
void toggle_media_loop_state();
void toggle_media_controls_state();
HTML::MuteState page_mute_state() const { return m_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.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;
}
@ -350,7 +350,7 @@ MediaPaintable::DispatchEventOfSameName MediaPaintable::handle_mouseup(Badge<Eve
return DispatchEventOfSameName::No;
}
media_element.toggle_playback().release_value_but_fixme_should_propagate_errors();
media_element.toggle_playback();
return DispatchEventOfSameName::Yes;
}

View file

@ -22,10 +22,12 @@ namespace Web::SVG::AttributeNames {
__ENUMERATE_SVG_ATTRIBUTE(contentStyleType, "contentStyleType") \
__ENUMERATE_SVG_ATTRIBUTE(cx, "cx") \
__ENUMERATE_SVG_ATTRIBUTE(cy, "cy") \
__ENUMERATE_SVG_ATTRIBUTE(d, "d") \
__ENUMERATE_SVG_ATTRIBUTE(diffuseConstant, "diffuseConstant") \
__ENUMERATE_SVG_ATTRIBUTE(dx, "dx") \
__ENUMERATE_SVG_ATTRIBUTE(dy, "dy") \
__ENUMERATE_SVG_ATTRIBUTE(edgeMode, "edgeMode") \
__ENUMERATE_SVG_ATTRIBUTE(fill, "fill") \
__ENUMERATE_SVG_ATTRIBUTE(filterUnits, "filterUnits") \
__ENUMERATE_SVG_ATTRIBUTE(fr, "fr") \
__ENUMERATE_SVG_ATTRIBUTE(fx, "fx") \
@ -104,6 +106,7 @@ namespace Web::SVG::AttributeNames {
__ENUMERATE_SVG_ATTRIBUTE(x2, "x2") \
__ENUMERATE_SVG_ATTRIBUTE(xChannelSelector, "xChannelSelector") \
__ENUMERATE_SVG_ATTRIBUTE(xlink_href, "xlink:href") \
__ENUMERATE_SVG_ATTRIBUTE(xmlns, "xmlns") \
__ENUMERATE_SVG_ATTRIBUTE(y, "y") \
__ENUMERATE_SVG_ATTRIBUTE(y1, "y1") \
__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
// auto, then the property is computed as normal for the element instance.
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)) {
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();

View file

@ -38,8 +38,8 @@ ErrorOr<GC::Ref<HTML::HTMLCanvasElement>, WebDriver::Error> draw_bounding_box_fr
auto& canvas = as<HTML::HTMLCanvasElement>(*canvas_element);
// FIXME: Handle DevicePixelRatio in HiDPI mode.
MUST(canvas.set_width(paint_width));
MUST(canvas.set_height(paint_height));
canvas.set_width(paint_width);
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.
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)) {
// 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 (!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;
}
}
m_has_error = true;
} else if (attribute.key.contains(':')) {
if (auto ns = namespace_for_name(attribute.key); ns.has_value()) {
if (!node->set_attribute_ns(ns.value(), MUST(String::from_byte_string(attribute.key)), Utf16String::from_utf8(attribute.value)).is_error())
continue;
} else if (attribute.key.starts_with("xml:"sv)) {
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())
if (auto namespace_for_key = namespace_for_name(attribute.key); namespace_for_key.has_value()) {
auto maybe_extracted_qualified_name = validate_and_extract(node->realm(), namespace_for_key, 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;
}
}
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;
} else {
if (!node->set_attribute(MUST(String::from_byte_string(attribute.key)), MUST(String::from_byte_string(attribute.value))).is_error())
continue;
m_has_error = true;
node->set_attribute_value(MUST(String::from_byte_string(attribute.key)), MUST(String::from_byte_string(attribute.value)));
}
}

View file

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

View file

@ -4395,7 +4395,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
if (!cpp_value)
impl->remove_attribute("@attribute.reflect_name@"_fly_string);
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") {
// The setter steps are:
@ -4411,11 +4411,11 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
u32 new_value = minimum;
if (cpp_value >= minimum && cpp_value <= 2147483647)
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()) {
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
@ -4431,18 +4431,18 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
static auto content_attribute = "@attribute.reflect_name@"_fly_string;
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);
return JS::js_undefined();
}
)~~~");
// 2. Run this's set the content attribute with the empty string.
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.
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
@ -4457,7 +4457,7 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
static auto content_attribute = "@attribute.reflect_name@"_fly_string;
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);
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.
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.
@ -4480,18 +4480,18 @@ JS_DEFINE_NATIVE_FUNCTION(@class_name@::@attribute.setter_callback@)
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()) {
attribute_generator.append(R"~~~(
if (!cpp_value.has_value())
impl->remove_attribute("@attribute.reflect_name@"_fly_string);
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 {
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) {
// 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());
@ -792,7 +792,7 @@ void ConnectionFromClient::replace_dom_node_attribute(u64 page_id, Web::UniqueNo
should_remove_attribute = false;
// 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)
@ -1299,7 +1299,7 @@ void ConnectionFromClient::retrieved_clipboard_entries(u64 page_id, u64 request_
void ConnectionFromClient::toggle_media_play_state(u64 page_id)
{
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)
@ -1311,13 +1311,13 @@ void ConnectionFromClient::toggle_media_mute_state(u64 page_id)
void ConnectionFromClient::toggle_media_loop_state(u64 page_id)
{
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)
{
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)

View file

@ -442,9 +442,9 @@ void PageClient::select_dropdown_closed(Optional<u32> const& 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()
@ -452,14 +452,14 @@ void PageClient::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)

View file

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