mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 12:05:15 +00:00
LibWeb: Make MouseEvent.offsetX/Y ignore transforms
That is what the spec calls it, at least. In code, this manifests as making the offset very aware of the element's transform, because the click position comes relative to the viewport, not to the transformed element.
This commit is contained in:
parent
c1596192fa
commit
4dc65c57a0
Notes:
github-actions[bot]
2024-12-13 06:19:51 +00:00
Author: https://github.com/Psychpsyo Commit: https://github.com/LadybirdBrowser/ladybird/commit/4dc65c57a0d Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2372 Reviewed-by: https://github.com/kalenikaliaksandr
3 changed files with 58 additions and 4 deletions
|
@ -147,13 +147,44 @@ static Gfx::StandardCursor cursor_css_to_gfx(Optional<CSS::Cursor> cursor)
|
|||
}
|
||||
}
|
||||
|
||||
// https://drafts.csswg.org/cssom-view/#dom-mouseevent-offsetx
|
||||
static CSSPixelPoint compute_mouse_event_offset(CSSPixelPoint position, Layout::Node const& layout_node)
|
||||
{
|
||||
auto top_left_of_layout_node = layout_node.first_paintable()->box_type_agnostic_position();
|
||||
return {
|
||||
position.x() - top_left_of_layout_node.x(),
|
||||
position.y() - top_left_of_layout_node.y()
|
||||
// If the event’s dispatch flag is set,
|
||||
// FIXME: Is this guaranteed to be dispatched?
|
||||
|
||||
// return the x-coordinate of the position where the event occurred,
|
||||
Gfx::Point<float> precision_offset = {
|
||||
position.x().to_double(),
|
||||
position.y().to_double()
|
||||
};
|
||||
|
||||
// ignoring the transforms that apply to the element and its ancestors,
|
||||
if (layout_node.has_css_transform()) {
|
||||
auto const& paintable_box = layout_node.dom_node()->paintable_box();
|
||||
auto const affine_transform = Gfx::extract_2d_affine_transform(paintable_box->transform().inverse());
|
||||
|
||||
auto const& origin = paintable_box->transform_origin();
|
||||
Gfx::Point<float> const precision_origin = {
|
||||
origin.x().to_double(),
|
||||
origin.y().to_double()
|
||||
};
|
||||
|
||||
precision_offset.translate_by(-precision_origin);
|
||||
precision_offset.transform_by(affine_transform);
|
||||
precision_offset.translate_by(precision_origin);
|
||||
}
|
||||
|
||||
// relative to the origin of the padding edge of the target node
|
||||
auto const top_left_of_layout_node = layout_node.first_paintable()->box_type_agnostic_position();
|
||||
CSSPixelPoint offset = {
|
||||
CSSPixels(precision_offset.x()),
|
||||
CSSPixels(precision_offset.y())
|
||||
};
|
||||
offset -= top_left_of_layout_node;
|
||||
|
||||
// and terminate these steps.
|
||||
return offset;
|
||||
}
|
||||
|
||||
EventHandler::EventHandler(Badge<HTML::Navigable>, HTML::Navigable& navigable)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
offsetX: 45.75
|
||||
offsetY: 57.078125
|
|
@ -0,0 +1,21 @@
|
|||
<!DOCTYPE html>
|
||||
<style>
|
||||
div {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color: gray;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
</style>
|
||||
<div onClick="
|
||||
println(`offsetX: ${event.offsetX}`);
|
||||
println(`offsetY: ${event.offsetY}`);
|
||||
"></div>
|
||||
|
||||
<script src="../include.js"></script>
|
||||
|
||||
<script>
|
||||
test(() => {
|
||||
internals.click(50, 60);
|
||||
});
|
||||
</script>
|
Loading…
Add table
Reference in a new issue