diff --git a/Tests/LibWeb/Text/expected/HTML/form-image-submission.txt b/Tests/LibWeb/Text/expected/HTML/form-image-submission.txt
new file mode 100644
index 0000000000..5feee74756
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/HTML/form-image-submission.txt
@@ -0,0 +1 @@
+ 10,20
diff --git a/Tests/LibWeb/Text/input/HTML/form-image-submission.html b/Tests/LibWeb/Text/input/HTML/form-image-submission.html
new file mode 100644
index 0000000000..602f3bc7d2
--- /dev/null
+++ b/Tests/LibWeb/Text/input/HTML/form-image-submission.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
diff --git a/Userland/Libraries/LibWeb/HTML/FormControlInfrastructure.cpp b/Userland/Libraries/LibWeb/HTML/FormControlInfrastructure.cpp
index 7f782e9d53..f12b046c14 100644
--- a/Userland/Libraries/LibWeb/HTML/FormControlInfrastructure.cpp
+++ b/Userland/Libraries/LibWeb/HTML/FormControlInfrastructure.cpp
@@ -88,13 +88,32 @@ WebIDL::ExceptionOr>> construct_entry_list(J
// 2. If the field element is an input element whose type attribute is in the Image Button state, then:
if (auto* input_element = dynamic_cast(control.ptr()); input_element && input_element->type_state() == HTMLInputElement::TypeAttributeState::ImageButton) {
- // FIXME: 1. If the field element has a name attribute specified and its value is not the empty string, let name be that value followed by a single U+002E FULL STOP character (.). Otherwise, let name be the empty string.
- // FIXME: 2. Let namex be the string consisting of the concatenation of name and a single U0078 LATIN SMALL LETTER X character (x).
- // FIXME: 3. Let namey be the string consisting of the concatenation of name and a single U+0079 LATIN SMALL LETTER Y character (y).
- // FIXME: 4. The field element is submitter, and before this algorithm was invoked the user indicated a coordinate. Let x be the x-component of the coordinate selected by the user, and let y be the y-component of the coordinate selected by the user.
- // FIXME: 5. Create an entry with namex and x, and append it to entry list.
- // FIXME: 6. Create an entry with namey and y, and append it to entry list.
- // 7. Continue.
+ // 1. If the field element is not submitter, then continue.
+ if (input_element != submitter.ptr())
+ continue;
+
+ // 2. If the field element has a name attribute specified and its value is not the empty string, let name be
+ // that value followed by U+002E (.). Otherwise, let name be the empty string.
+ String name;
+ if (auto value = input_element->get_attribute(AttributeNames::name); value.has_value() && !value->is_empty())
+ name = MUST(String::formatted("{}.", *value));
+
+ // 3. Let namex be the concatenation of name and U+0078 (x).
+ auto name_x = MUST(String::formatted("{}x", name));
+
+ // 4. Let namey be the concatenation of name and U+0079 (y).
+ auto name_y = MUST(String::formatted("{}y", name));
+
+ // 5. Let (x, y) be the selected coordinate.
+ auto [x, y] = input_element->selected_coordinate();
+
+ // 6. Create an entry with namex and x, and append it to entry list.
+ entry_list.append(XHR::FormDataEntry { .name = move(name_x), .value = MUST(String::number(x)) });
+
+ // 7. Create an entry with namey and y, and append it to entry list.
+ entry_list.append(XHR::FormDataEntry { .name = move(name_y), .value = MUST(String::number(y)) });
+
+ // 8. Continue.
continue;
}
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp
index 8a8b9eb2d6..5512463c3a 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp
@@ -189,12 +189,22 @@ WebIDL::ExceptionOr HTMLFormElement::submit_form(JS::NonnullGCPtr result;
- // FIXME: 4. If submitter is an input element whose type attribute is in the Image Button state, then:
- // 1. Let (x, y) be the selected coordinate.
- // 2. Set result to the concatenation of x, ",", and y.
+ // 4. If submitter is an input element whose type attribute is in the Image Button state, then:
+ if (is(*submitter)) {
+ auto const& input_element = static_cast(*submitter);
+
+ if (input_element.type_state() == HTMLInputElement::TypeAttributeState::ImageButton) {
+ // 1. Let (x, y) be the selected coordinate.
+ auto [x, y] = input_element.selected_coordinate();
+
+ // 2. Set result to the concatenation of x, ",", and y.
+ result = MUST(String::formatted("{},{}", x, y));
+ }
+ }
// 5. Otherwise, if submitter has a value, then set result to that value.
- result = submitter->get_attribute_value(AttributeNames::value);
+ if (!result.has_value())
+ result = submitter->get_attribute_value(AttributeNames::value);
// 6. Close the dialog subject with result.
subject->close(move(result));
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp
index f4a14bcbd7..d623b19626 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp
+++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp
@@ -39,6 +39,7 @@
#include
#include
#include
+#include
#include
#include
@@ -304,8 +305,12 @@ WebIDL::ExceptionOr HTMLInputElement::run_input_activation_behavior(DOM::E
if (!document().is_fully_active())
return {};
- // FIXME: 3. If the user activated the control while explicitly selecting a coordinate, then set the element's selected
- // coordinate to that coordinate.
+ // 3. If the user activated the control while explicitly selecting a coordinate, then set the element's selected
+ // coordinate to that coordinate.
+ if (event.is_trusted() && is(event)) {
+ auto const& mouse_event = static_cast(event);
+ m_selected_coordinate = { mouse_event.offset_x(), mouse_event.offset_y() };
+ }
// 4. Submit the element's form owner from the element with userInvolvement set to event's user navigation involvement.
TRY(form->submit_form(*this, { .user_involvement = user_navigation_involvement(event) }));
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
index b85ed9d35c..4fa885efdf 100644
--- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
+++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.h
@@ -104,6 +104,12 @@ public:
unsigned size() const;
WebIDL::ExceptionOr set_size(unsigned value);
+ struct SelectedCoordinate {
+ double x { 0.0 };
+ double y { 0.0 };
+ };
+ SelectedCoordinate selected_coordinate() const { return m_selected_coordinate; }
+
JS::Object* value_as_date() const;
WebIDL::ExceptionOr set_value_as_date(Optional> const&);
@@ -252,6 +258,7 @@ private:
JS::GCPtr image_data() const;
JS::GCPtr m_image_request;
+ SelectedCoordinate m_selected_coordinate;
Optional m_load_event_delayer;