Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 0db35f0

Browse files
Goamandmo-odoo
authored andcommitted
[IMP] Nomarlizer: make PointerEventPosition
The properties to access the `x` and `y` are not the same on MouseEvent and TouchEvent. And it is not possible to mutate or recreate similar event when passing it through functions. In the future, we need to be able to access and modifiy the x and y. For instance, when the browser is overloaded and the event are all aggregated in one stack, it is still possible to scroll the browser. When we scroll the browser, the x and y positions are not accurate and we need to be able to change them to reflect what happen after the scroll.
1 parent 19851f5 commit 0db35f0

File tree

1 file changed

+43
-27
lines changed

1 file changed

+43
-27
lines changed

packages/plugin-dom-editable/src/EventNormalizer.ts

Lines changed: 43 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,16 @@ const alphabetsContainingSpaces = new RegExp(
7979
')$',
8080
);
8181

82+
/**
83+
* Information about the MouseEvent or TouchEvent that represent their
84+
* positions.
85+
*/
86+
interface PointerEventPosition {
87+
target: EventTarget;
88+
x: number;
89+
y: number;
90+
}
91+
8292
/**
8393
* These javascript event types might, in case of safari or spell-checking
8494
* keyboard, trigger dom events in multiple javascript stacks. They will require
@@ -592,9 +602,13 @@ export class EventNormalizer {
592602
this._enableNormalizer(eventTarget);
593603
} else {
594604
if (eventTarget && ev.constructor.name === 'MouseEvent') {
595-
eventTarget = this._getEventTarget(ev as MouseEvent);
605+
eventTarget = this._getEventTarget(
606+
this._getPointerEventPosition(ev as MouseEvent),
607+
);
596608
} else if (eventTarget && ev.constructor.name === 'TouchEvent') {
597-
eventTarget = this._getEventTarget(ev as TouchEvent);
609+
eventTarget = this._getEventTarget(
610+
this._getPointerEventPosition(ev as TouchEvent),
611+
);
598612
} else if (this._isInEditable(eventTarget)) {
599613
eventTarget = eventTarget?.ownerDocument.getSelection().focusNode;
600614
}
@@ -1407,7 +1421,7 @@ export class EventNormalizer {
14071421
*
14081422
* @param [ev]
14091423
*/
1410-
_getSelection(ev?: MouseEvent | TouchEvent): DomSelectionDescription {
1424+
_getSelection(ev?: PointerEventPosition): DomSelectionDescription {
14111425
let selectionDescription: DomSelectionDescription;
14121426
let target: Node;
14131427
let root: Document | ShadowRoot;
@@ -1623,17 +1637,9 @@ export class EventNormalizer {
16231637
*
16241638
* @param ev
16251639
*/
1626-
_getEventCaretPosition(ev: MouseEvent | TouchEvent): CaretPosition {
1627-
const x =
1628-
ev.constructor.name === 'TouchEvent'
1629-
? (ev as TouchEvent).touches[0].clientX
1630-
: (ev as MouseEvent).clientX;
1631-
const y =
1632-
ev.constructor.name === 'TouchEvent'
1633-
? (ev as TouchEvent).touches[0].clientY
1634-
: (ev as MouseEvent).clientY;
1640+
_getEventCaretPosition(ev: PointerEventPosition): CaretPosition {
16351641
const target = ev.target as Node;
1636-
let caretPosition = caretPositionFromPoint(x, y, target.ownerDocument);
1642+
let caretPosition = caretPositionFromPoint(ev.x, ev.y, target.ownerDocument);
16371643
if (!caretPosition) {
16381644
caretPosition = { offsetNode: ev.target as Node, offset: 0 };
16391645
}
@@ -1645,17 +1651,9 @@ export class EventNormalizer {
16451651
*
16461652
* @param ev
16471653
*/
1648-
_getEventTarget(ev: MouseEvent | TouchEvent): Node {
1649-
const x =
1650-
ev.constructor.name === 'TouchEvent'
1651-
? (ev as TouchEvent).touches[0].clientX
1652-
: (ev as MouseEvent).clientX;
1653-
const y =
1654-
ev.constructor.name === 'TouchEvent'
1655-
? (ev as TouchEvent).touches[0].clientY
1656-
: (ev as MouseEvent).clientY;
1654+
_getEventTarget(ev: PointerEventPosition): Node {
16571655
const target = ev.target as Node;
1658-
return elementFromPoint(x, y, target.ownerDocument) || target;
1656+
return elementFromPoint(ev.x, ev.y, target.ownerDocument) || target;
16591657
}
16601658

16611659
//--------------------------------------------------------------------------
@@ -1714,8 +1712,9 @@ export class EventNormalizer {
17141712
_onPointerDown(ev: MouseEvent | TouchEvent): void {
17151713
// Don't trigger events on the editable if the click was done outside of
17161714
// the editable itself or on something else than an element.
1717-
const target = this._getEventTarget(ev);
1718-
const caretPosition = this._getEventCaretPosition(ev);
1715+
const pointerEventPosition = this._getPointerEventPosition(ev);
1716+
const target = this._getEventTarget(pointerEventPosition);
1717+
const caretPosition = this._getEventCaretPosition(pointerEventPosition);
17191718
if (target && this._isInEditable(caretPosition.offsetNode)) {
17201719
this._mousedownInEditable = true;
17211720
this._initialCaretPosition = caretPosition;
@@ -1743,7 +1742,7 @@ export class EventNormalizer {
17431742
this._initialCaretPosition = this._getEventCaretPosition(ev);
17441743
this._pointerSelectionTimeout = new Timeout<EventBatch>(() => {
17451744
if (ev.defaultPrevented) return { actions: [] };
1746-
return this._analyzeSelectionChange(ev);
1745+
return this._analyzeSelectionChange(this._getPointerEventPosition(ev));
17471746
});
17481747
this._triggerEventBatch(this._pointerSelectionTimeout.promise);
17491748
} catch (e) {
@@ -1775,7 +1774,7 @@ export class EventNormalizer {
17751774
*
17761775
* @param ev
17771776
*/
1778-
_analyzeSelectionChange(ev: MouseEvent | TouchEvent): EventBatch {
1777+
_analyzeSelectionChange(ev: PointerEventPosition): EventBatch {
17791778
const eventBatch = {
17801779
actions: [],
17811780
mutatedElements: new Set([]),
@@ -2007,4 +2006,21 @@ export class EventNormalizer {
20072006
this._shadowNormalizers.set(root, eventNormalizer);
20082007
}
20092008
}
2009+
2010+
/**
2011+
* Retrieve a `PointerEventPosition` from a` MouseEvent` or a `TouchEvent`.
2012+
*/
2013+
_getPointerEventPosition(ev: MouseEvent | TouchEvent): PointerEventPosition {
2014+
return {
2015+
x:
2016+
ev.constructor.name === 'TouchEvent'
2017+
? (ev as TouchEvent).touches[0].clientX
2018+
: (ev as MouseEvent).clientX,
2019+
y:
2020+
ev.constructor.name === 'TouchEvent'
2021+
? (ev as TouchEvent).touches[0].clientY
2022+
: (ev as MouseEvent).clientY,
2023+
target: ev.target,
2024+
};
2025+
}
20102026
}

0 commit comments

Comments
 (0)