[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
|
/// 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.
|
/// to what the DOM would return if we had currentTarget readily available.
|
||||||
///
|
///
|
||||||
/// This needs an `eventTarget`, because the `event.target` (which is what
|
/// This takes an optional `eventTarget`, because the `event.target` may have
|
||||||
/// this would really need to use) gets lost when the `event` comes from a
|
/// the wrong value for "coalesced" events. See:
|
||||||
/// "coalesced" event (see https://github.com/flutter/flutter/issues/155987).
|
///
|
||||||
|
/// - 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
|
/// It also takes into account semantics being enabled to fix the case where
|
||||||
/// offsetX, offsetY == 0 (TalkBack events).
|
/// offsetX, offsetY == 0 (TalkBack events).
|
||||||
@ -41,12 +44,12 @@ ui.Offset computeEventOffsetToTarget(
|
|||||||
if (isInput) {
|
if (isInput) {
|
||||||
final EditableTextGeometry? inputGeometry = textEditing.strategy.geometry;
|
final EditableTextGeometry? inputGeometry = textEditing.strategy.geometry;
|
||||||
if (inputGeometry != null) {
|
if (inputGeometry != null) {
|
||||||
return _computeOffsetForInputs(event, inputGeometry);
|
return _computeOffsetForInputs(event, eventTarget, inputGeometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// On another DOM Element (normally a platform view)
|
// On another DOM Element (normally a platform view)
|
||||||
final bool isTargetOutsideOfShadowDOM = event.target != actualTarget;
|
final bool isTargetOutsideOfShadowDOM = eventTarget != actualTarget;
|
||||||
if (isTargetOutsideOfShadowDOM) {
|
if (isTargetOutsideOfShadowDOM) {
|
||||||
final DomRect origin = actualTarget.getBoundingClientRect();
|
final DomRect origin = actualTarget.getBoundingClientRect();
|
||||||
// event.clientX/Y and origin.x/y are relative **to the viewport**.
|
// 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
|
/// sent from the framework, which includes information on how to transform the
|
||||||
/// underlying input element. We transform the `event.offset` points we receive
|
/// underlying input element. We transform the `event.offset` points we receive
|
||||||
/// using the values from the input's transform matrix.
|
/// 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;
|
final DomHTMLElement domElement = textEditing.strategy.activeDomElement;
|
||||||
assert(targetElement == domElement, 'The targeted input element must be the active input element');
|
assert(targetElement == domElement, 'The targeted input element must be the active input element');
|
||||||
final Float32List transformValues = inputGeometry.globalTransform;
|
final Float32List transformValues = inputGeometry.globalTransform;
|
||||||
|
@ -32,6 +32,7 @@ void doTests() {
|
|||||||
group('computeEventOffsetToTarget', () {
|
group('computeEventOffsetToTarget', () {
|
||||||
setUp(() {
|
setUp(() {
|
||||||
view = EngineFlutterView(EnginePlatformDispatcher.instance, domDocument.body!);
|
view = EngineFlutterView(EnginePlatformDispatcher.instance, domDocument.body!);
|
||||||
|
EnginePlatformDispatcher.instance.viewManager.registerView(view);
|
||||||
rootElement = view.dom.rootElement;
|
rootElement = view.dom.rootElement;
|
||||||
eventSource = createDomElement('div-event-source');
|
eventSource = createDomElement('div-event-source');
|
||||||
rootElement.append(eventSource);
|
rootElement.append(eventSource);
|
||||||
@ -58,6 +59,7 @@ void doTests() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
tearDown(() {
|
tearDown(() {
|
||||||
|
EnginePlatformDispatcher.instance.viewManager.unregisterView(view.viewId);
|
||||||
view.dispose();
|
view.dispose();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -101,6 +103,36 @@ void doTests() {
|
|||||||
expect(offset.dy, 110);
|
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 {
|
test('Event dispatched by TalkBack gets a computed offset', () async {
|
||||||
// Fill this in to test _computeOffsetForTalkbackEvent
|
// Fill this in to test _computeOffsetForTalkbackEvent
|
||||||
}, skip: 'To be implemented!');
|
}, skip: 'To be implemented!');
|
||||||
|
Loading…
x
Reference in New Issue
Block a user