[web] Use eventTarget
when computing pointer offset (flutter/engine#56949)
These changes are mainly things I missed in https://github.com/flutter/engine/pull/56719 Fixes https://github.com/flutter/flutter/issues/159804
This commit is contained in:
parent
ba21393f49
commit
a3ed100995
@ -18,9 +18,12 @@ import '../window.dart';
|
||||
/// The offset is *not* multiplied by DPR or anything else, it's the closest
|
||||
/// to what the DOM would return if we had currentTarget readily available.
|
||||
///
|
||||
/// This needs an `eventTarget`, because the `event.target` (which is what
|
||||
/// this would really need to use) gets lost when the `event` comes from a
|
||||
/// "coalesced" event (see https://github.com/flutter/flutter/issues/155987).
|
||||
/// This takes an optional `eventTarget`, because the `event.target` may have
|
||||
/// the wrong value for "coalesced" events. See:
|
||||
///
|
||||
/// - https://github.com/flutter/flutter/issues/155987
|
||||
/// - https://github.com/flutter/flutter/issues/159804
|
||||
/// - https://g-issues.chromium.org/issues/382473107
|
||||
///
|
||||
/// It also takes into account semantics being enabled to fix the case where
|
||||
/// offsetX, offsetY == 0 (TalkBack events).
|
||||
@ -41,12 +44,12 @@ ui.Offset computeEventOffsetToTarget(
|
||||
if (isInput) {
|
||||
final EditableTextGeometry? inputGeometry = textEditing.strategy.geometry;
|
||||
if (inputGeometry != null) {
|
||||
return _computeOffsetForInputs(event, inputGeometry);
|
||||
return _computeOffsetForInputs(event, eventTarget, inputGeometry);
|
||||
}
|
||||
}
|
||||
|
||||
// On another DOM Element (normally a platform view)
|
||||
final bool isTargetOutsideOfShadowDOM = event.target != actualTarget;
|
||||
final bool isTargetOutsideOfShadowDOM = eventTarget != actualTarget;
|
||||
if (isTargetOutsideOfShadowDOM) {
|
||||
final DomRect origin = actualTarget.getBoundingClientRect();
|
||||
// event.clientX/Y and origin.x/y are relative **to the viewport**.
|
||||
@ -70,8 +73,14 @@ ui.Offset computeEventOffsetToTarget(
|
||||
/// sent from the framework, which includes information on how to transform the
|
||||
/// underlying input element. We transform the `event.offset` points we receive
|
||||
/// using the values from the input's transform matrix.
|
||||
ui.Offset _computeOffsetForInputs(DomMouseEvent event, EditableTextGeometry inputGeometry) {
|
||||
final DomElement targetElement = event.target! as DomHTMLElement;
|
||||
///
|
||||
/// See [computeEventOffsetToTarget] for more information about `eventTarget`.
|
||||
ui.Offset _computeOffsetForInputs(
|
||||
DomMouseEvent event,
|
||||
DomEventTarget eventTarget,
|
||||
EditableTextGeometry inputGeometry,
|
||||
) {
|
||||
final DomElement targetElement = eventTarget as DomElement;
|
||||
final DomHTMLElement domElement = textEditing.strategy.activeDomElement;
|
||||
assert(targetElement == domElement, 'The targeted input element must be the active input element');
|
||||
final Float32List transformValues = inputGeometry.globalTransform;
|
||||
|
@ -32,6 +32,7 @@ void doTests() {
|
||||
group('computeEventOffsetToTarget', () {
|
||||
setUp(() {
|
||||
view = EngineFlutterView(EnginePlatformDispatcher.instance, domDocument.body!);
|
||||
EnginePlatformDispatcher.instance.viewManager.registerView(view);
|
||||
rootElement = view.dom.rootElement;
|
||||
eventSource = createDomElement('div-event-source');
|
||||
rootElement.append(eventSource);
|
||||
@ -58,6 +59,7 @@ void doTests() {
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
EnginePlatformDispatcher.instance.viewManager.unregisterView(view.viewId);
|
||||
view.dispose();
|
||||
});
|
||||
|
||||
@ -101,6 +103,36 @@ void doTests() {
|
||||
expect(offset.dy, 110);
|
||||
});
|
||||
|
||||
test('eventTarget takes precedence', () async {
|
||||
final input = view.dom.textEditingHost.appendChild(createDomElement('input'));
|
||||
|
||||
textEditing.strategy.enable(
|
||||
InputConfiguration(viewId: view.viewId),
|
||||
onChange: (_, __) {},
|
||||
onAction: (_) {},
|
||||
);
|
||||
|
||||
addTearDown(() {
|
||||
textEditing.strategy.disable();
|
||||
});
|
||||
|
||||
final moveEvent = createDomPointerEvent('pointermove', <String, Object>{
|
||||
'bubbles': true,
|
||||
'clientX': 10,
|
||||
'clientY': 20,
|
||||
});
|
||||
|
||||
expect(
|
||||
() => computeEventOffsetToTarget(moveEvent, view),
|
||||
throwsA(anything),
|
||||
);
|
||||
|
||||
expect(
|
||||
() => computeEventOffsetToTarget(moveEvent, view, eventTarget: input),
|
||||
returnsNormally,
|
||||
);
|
||||
});
|
||||
|
||||
test('Event dispatched by TalkBack gets a computed offset', () async {
|
||||
// Fill this in to test _computeOffsetForTalkbackEvent
|
||||
}, skip: 'To be implemented!');
|
||||
|
Loading…
x
Reference in New Issue
Block a user