LibWeb: Don't double-dispatch click events on a label's child input

If the user clicked directly on the input inside a label, then it
already received a click event. Dispatching a second one via the label
is redundant, and means that if the input is a checkbox, it gets its
value toggled twice.
This commit is contained in:
Sam Atkins 2025-04-15 12:01:07 +01:00
parent d616ab0d95
commit d62f0247a6
3 changed files with 54 additions and 1 deletions

View file

@ -555,7 +555,7 @@ EventResult EventHandler::handle_mouseup(CSSPixelPoint viewport_position, CSSPix
}
if (auto* input_control = input_control_associated_with_ancestor_label_element(*paintable)) {
if (button == UIEvents::MouseButton::Primary) {
if (button == UIEvents::MouseButton::Primary && input_control != node) {
input_control->dispatch_event(UIEvents::MouseEvent::create_from_platform_event(node->realm(), UIEvents::EventNames::click, screen_position, page_offset, viewport_position, offset, {}, button, buttons, modifiers).release_value_but_fixme_should_propagate_errors());
}
}

View file

@ -0,0 +1,2 @@
click event on input#radio1
click event on input#radio2

View file

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="en">
<style>
* {
margin: 0;
}
.box {
display: inline-block;
width: 100px;
height: 100px;
background-color: purple;
}
label {
display: block;
width: 200px;
height: 200px;
border: 1px solid black;
}
</style>
<script src="../include.js"></script>
<body>
<form>
<label>
<input type="checkbox" id="radio1" class="target">
</label>
<label>
<input type="checkbox" id="radio2" class="target">
</label>
<input type="checkbox" id="done">
</form>
</body>
<script>
asyncTest(done => {
document.querySelectorAll('.target').forEach(function (element) {
element.addEventListener('click', function (event) {
println(`click event on input#${event.target.id}`);
});
});
document.getElementById('done').addEventListener('click', function (event) {
done();
});
internals.click(5, 10);
internals.click(5, 210);
internals.click(5, 410);
});
</script>
</html>