Bug 282266 - Populate imageClickedPoint when submitter is an image button. r=dom-core,layout-reviewers,emilio,masayuki

If the form submission originated from an event dispatch, this patch
ensures that the submitted image button coordinate is not the default.

Differential Revision: https://phabricator.services.mozilla.com/D224651
This commit is contained in:
Zach Hoffman
2024-10-15 12:27:57 +00:00
parent f862603b75
commit b335283083
4 changed files with 79 additions and 11 deletions

View File

@@ -23,6 +23,7 @@
#include "mozilla/dom/WindowContext.h"
#include "mozilla/dom/InputType.h"
#include "mozilla/dom/UserActivation.h"
#include "mozilla/dom/MouseEvent.h"
#include "mozilla/dom/MutationEventBinding.h"
#include "mozilla/dom/WheelEventBinding.h"
#include "mozilla/dom/WindowGlobalChild.h"
@@ -3353,6 +3354,18 @@ void HTMLInputElement::LegacyPreActivationBehavior(
// latest one will be deferred until after the exit point of the
// handler.
mForm->OnSubmitClickBegin(this);
if (aVisitor.mDOMEvent) {
if (auto* mouseEvent = aVisitor.mDOMEvent->AsMouseEvent()) {
CSSIntPoint pt = mouseEvent->OffsetPoint();
if (auto* imageClickedPoint = static_cast<CSSIntPoint*>(
GetProperty(nsGkAtoms::imageClickedPoint))) {
// Ensures that a dispatched event's clicked point is not the default
// value.
*imageClickedPoint = pt;
}
}
}
}
}

View File

@@ -1,3 +0,0 @@
[constructor-submitter-coordinate.html]
[The constructed FormData object should contain correct entries for Image Button submitter's dispatched coordinate]
expected: FAIL

View File

@@ -1,18 +1,21 @@
<!DOCTYPE html>
<meta charset='utf-8'>
<meta name=viewport content='width=device-width,initial-scale=1'>
<link rel='help' href='https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set'>
<link ref='help' href='https://xhr.spec.whatwg.org/#dom-formdata'>
<script src='/resources/testharness.js'></script>
<script src='/resources/testharnessreport.js'></script>
<form>
<input type=image src='/media/1x1-green.png'></button>
<input type=image src='/images/100px-green-rect.svg'>
</form>
<script>
"use strict";
test(() => {
promise_test(async () => {
await new Promise(r => window.addEventListener("load", r));
const form = document.querySelector("form");
const submitter = form.querySelector("input[type=image]");
@@ -23,14 +26,14 @@ test(() => {
});
const domRect = submitter.getBoundingClientRect();
const clientX = Math.round((domRect.left + domRect.right) / 7);
const clientY = Math.round((domRect.top + domRect.bottom) / 4);
submitter.dispatchEvent(
new MouseEvent("click", {
clientX: Math.round(domRect.x) + 1,
clientY: Math.round(domRect.y) + 2
})
new MouseEvent("click", {clientX, clientY})
);
assert_equals(formData?.get("x"), "1");
assert_equals(formData?.get("y"), "2");
assert_equals(formData?.get("x"), "23");
assert_equals(formData?.get("y"), "46");
}, "The constructed FormData object should contain correct entries for Image Button submitter's dispatched coordinate");
</script>

View File

@@ -0,0 +1,55 @@
<!doctype html>
<meta charset="utf-8">
<meta name=viewport content="width=device-width,initial-scale=1">
<title>Test image button coordinates</title>
<link rel="help" href="https://html.spec.whatwg.org/multipage/input.html#image-button-state-(type=image)">
<link rel="help" href="https://xhr.spec.whatwg.org/#dom-formdata">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=282266">
<link rel="author" title="Zach Hoffman" href="mailto:zach@zrhoffman.net">
<form id="myForm" onsubmit="return false;">
<input id="myImage" name="myImage" type="image" src="/images/100px-green-rect.svg">
</form>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/resources/testdriver.js"></script>
<script src="/resources/testdriver-vendor.js"></script>
<script>
promise_test(async t => {
await new Promise(r => window.addEventListener("load", r));
const xCoordinates = [];
const yCoordinates = [];
let formData;
myForm.addEventListener("submit", t.step_func(e => {
e.preventDefault();
formData = new FormData(myForm, myImage);
xCoordinates.push(formData.get("myImage.x"));
yCoordinates.push(formData.get("myImage.y"));
}));
await test_driver.click(myImage);
const [clientX, clientY] = getInViewCenterPoint(myImage.getBoundingClientRect());
const mouseEvent = new MouseEvent("click", {clientX, clientY});
myImage.dispatchEvent(mouseEvent);
assert_equals(xCoordinates.length, 2, "there should be 2 X coordinates");
assert_equals(yCoordinates.length, 2, "there should be 2 Y coordinates");
assert_equals(xCoordinates[1], xCoordinates[0], "dispatched event X coordinate should match user intention X coordinate");
assert_equals(yCoordinates[1], yCoordinates[0], "dispatched event Y coordinate should match user intention Y coordinate");
}, "dispatched event coordinates should match user intention coordinates")
// Private function from testdriver.js.
function getInViewCenterPoint(rect) {
var left = Math.max(0, rect.left);
var right = Math.min(window.innerWidth, rect.right);
var top = Math.max(0, rect.top);
var bottom = Math.min(window.innerHeight, rect.bottom);
var x = 0.5 * (left + right);
var y = 0.5 * (top + bottom);
return [x, y];
}
</script>