script: Pass more information to the MouseEvent constructor (#37672)

- Instead of eagerly computing `pageX` and `pageY`, collect the offset
  from the content's initial containing block in the compositor and pass
  that information through to `MouseEvent`. This prevents a layout flush
  that was happening when eagerly trying to fetch `Document` scroll
  offsets.
- Pass keyboard modifiers properly to `MouseEvent`.
- Now all this information is stored and passed as `Point2D` (typed) and
  `Modifiers` which greatly reduces the amount of arguments that need to
  be passed around.

Testing: It is difficult to test input events as they require WebDriver
which
isn't completely working yet. I have manually run Speedometer 2.1 and I
have
verified that this fixes the regression from #37601.
Fixes: #37601.

Signed-off-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
Martin Robinson 2025-06-25 14:29:27 +02:00 committed by GitHub
parent 50cf01cf3d
commit 0346a62214
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 374 additions and 369 deletions

View file

@ -28,6 +28,7 @@ js = { workspace = true }
jstraceable_derive = { path = "../jstraceable_derive" }
libc = { workspace = true }
log = { workspace = true }
keyboard-types = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
num-traits = { workspace = true }

View file

@ -22,9 +22,11 @@ use js::rust::{
HandleId, HandleValue, MutableHandleValue, ToString, get_object_class, is_dom_class,
is_dom_object, maybe_wrap_value,
};
use keyboard_types::Modifiers;
use num_traits::Float;
use crate::JSTraceable;
use crate::codegen::GenericBindings::EventModifierInitBinding::EventModifierInit;
use crate::inheritance::Castable;
use crate::num::Finite;
use crate::reflector::{DomObject, Reflector};
@ -589,3 +591,52 @@ pub(crate) unsafe fn windowproxy_from_handlevalue<D: crate::DomTypes>(
let ptr = value.to_private() as *const D::WindowProxy;
Ok(DomRoot::from_ref(&*ptr))
}
impl<D: crate::DomTypes> EventModifierInit<D> {
pub fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::empty();
if self.altKey {
modifiers.insert(Modifiers::ALT);
}
if self.ctrlKey {
modifiers.insert(Modifiers::CONTROL);
}
if self.shiftKey {
modifiers.insert(Modifiers::SHIFT);
}
if self.metaKey {
modifiers.insert(Modifiers::META);
}
if self.keyModifierStateAltGraph {
modifiers.insert(Modifiers::ALT_GRAPH);
}
if self.keyModifierStateCapsLock {
modifiers.insert(Modifiers::CAPS_LOCK);
}
if self.keyModifierStateFn {
modifiers.insert(Modifiers::FN);
}
if self.keyModifierStateFnLock {
modifiers.insert(Modifiers::FN_LOCK);
}
if self.keyModifierStateHyper {
modifiers.insert(Modifiers::HYPER);
}
if self.keyModifierStateNumLock {
modifiers.insert(Modifiers::NUM_LOCK);
}
if self.keyModifierStateScrollLock {
modifiers.insert(Modifiers::SCROLL_LOCK);
}
if self.keyModifierStateSuper {
modifiers.insert(Modifiers::SUPER);
}
if self.keyModifierStateSymbol {
modifiers.insert(Modifiers::SYMBOL);
}
if self.keyModifierStateSymbolLock {
modifiers.insert(Modifiers::SYMBOL_LOCK);
}
modifiers
}
}