diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 82aabd04d83..333e0b0be87 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -1881,6 +1882,41 @@ WebIDL::ExceptionOr HTMLInputElement::set_size(WebIDL::UnsignedLong value) return set_attribute(HTML::AttributeNames::size, String::number(value)); } +// https://html.spec.whatwg.org/multipage/input.html#dom-input-width +WebIDL::UnsignedLong HTMLInputElement::width() const +{ + const_cast(document()).update_layout(); + + // When the input element's type attribute is not in the Image Button state, then no image is available. + if (type_state() != TypeAttributeState::ImageButton) + return 0; + + // Return the rendered width of the image, in CSS pixels, if the image is being rendered. + if (auto* paintable_box = this->paintable_box()) + return paintable_box->content_width().to_int(); + + // On setting [the width or height IDL attribute], they must act as if they reflected the respective content attributes of the same name. + if (auto width_string = get_attribute(HTML::AttributeNames::width); width_string.has_value()) { + if (auto width = parse_non_negative_integer(*width_string); width.has_value() && *width <= 2147483647) + return *width; + } + + // ...or else the natural width and height of the image, in CSS pixels, if an image is available but not being rendered + if (auto bitmap = current_image_bitmap()) + return bitmap->width(); + + // ...or else 0, if the image is not available or does not have intrinsic dimensions. + return 0; +} + +WebIDL::ExceptionOr HTMLInputElement::set_width(WebIDL::UnsignedLong value) +{ + if (value > 2147483647) + value = 0; + + return set_attribute(HTML::AttributeNames::width, String::number(value)); +} + // https://html.spec.whatwg.org/multipage/input.html#concept-input-value-string-number Optional HTMLInputElement::convert_string_to_number(StringView input) const { diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index 964bc121f5c..1a6dc787bdc 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -128,6 +128,9 @@ public: WebIDL::UnsignedLong size() const; WebIDL::ExceptionOr set_size(WebIDL::UnsignedLong value); + WebIDL::UnsignedLong width() const; + WebIDL::ExceptionOr set_width(WebIDL::UnsignedLong value); + struct SelectedCoordinate { int x { 0 }; int y { 0 }; diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.idl b/Libraries/LibWeb/HTML/HTMLInputElement.idl index 1ed87bf4d2e..eba5df54d9d 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.idl +++ b/Libraries/LibWeb/HTML/HTMLInputElement.idl @@ -43,7 +43,7 @@ interface HTMLInputElement : HTMLElement { [CEReactions, LegacyNullToEmptyString] attribute DOMString value; attribute object? valueAsDate; attribute unrestricted double valueAsNumber; - [FIXME, CEReactions] attribute unsigned long width; + [CEReactions] attribute unsigned long width; undefined stepUp(optional long n = 1); undefined stepDown(optional long n = 1); diff --git a/Tests/LibWeb/Text/expected/HTML/unsigned-long-reflection.txt b/Tests/LibWeb/Text/expected/HTML/unsigned-long-reflection.txt index 2f8169498cb..d1c0fac3f76 100644 --- a/Tests/LibWeb/Text/expected/HTML/unsigned-long-reflection.txt +++ b/Tests/LibWeb/Text/expected/HTML/unsigned-long-reflection.txt @@ -37,6 +37,26 @@ input.getAttribute("size") after input.setAttribute("size", "4294967295"): 42949 input.size after input.setAttribute("size", "4294967295"): 20 input.getAttribute("size") after input.size = 4294967295: 20 input.size after input.size = 4294967295: 20 +input.getAttribute("width") after input.setAttribute("width", "0"): 0 +input.width after input.setAttribute("width", "0"): 0 +input.getAttribute("width") after input.width = 0: 0 +input.width after input.width = 0: 0 +input.getAttribute("width") after input.setAttribute("width", "1"): 1 +input.width after input.setAttribute("width", "1"): 1 +input.getAttribute("width") after input.width = 1: 1 +input.width after input.width = 1: 0 +input.getAttribute("width") after input.setAttribute("width", "2147483647"): 2147483647 +input.width after input.setAttribute("width", "2147483647"): 2147483647 +input.getAttribute("width") after input.width = 2147483647: 2147483647 +input.width after input.width = 2147483647: 0 +input.getAttribute("width") after input.setAttribute("width", "2147483648"): 2147483648 +input.width after input.setAttribute("width", "2147483648"): 0 +input.getAttribute("width") after input.width = 2147483648: 0 +input.width after input.width = 2147483648: 0 +input.getAttribute("width") after input.setAttribute("width", "4294967295"): 4294967295 +input.width after input.setAttribute("width", "4294967295"): 0 +input.getAttribute("width") after input.width = 4294967295: 0 +input.width after input.width = 4294967295: 0 marquee.getAttribute("scrollamount") after marquee.setAttribute("scrollAmount", "0"): 0 marquee.scrollAmount after marquee.setAttribute("scrollamount", "0"): 0 marquee.getAttribute("scrollamount") after marquee.scrollAmount = 0: 0 diff --git a/Tests/LibWeb/Text/input/HTML/unsigned-long-reflection.html b/Tests/LibWeb/Text/input/HTML/unsigned-long-reflection.html index 00ff3915bb0..9b8177a6d21 100644 --- a/Tests/LibWeb/Text/input/HTML/unsigned-long-reflection.html +++ b/Tests/LibWeb/Text/input/HTML/unsigned-long-reflection.html @@ -2,10 +2,19 @@