Skip to content

Commit

Permalink
Merge branch 'master' into fix-input-default-type
Browse files Browse the repository at this point in the history
  • Loading branch information
re-fort committed Apr 14, 2023
2 parents b1fd478 + f884711 commit 374e187
Show file tree
Hide file tree
Showing 9 changed files with 491 additions and 55 deletions.
2 changes: 2 additions & 0 deletions .changeset/fair-dragons-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
---
---
6 changes: 6 additions & 0 deletions .changeset/little-suits-leave.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'rrweb': minor
'@rrweb/types': minor
---

click events (as well as mousedown/mouseup/touchstart/touchend events) now include a `.pointerType` attribute which distinguishes between ['pen', 'mouse' and 'touch' events](https://developer.mozilla.org/en-US/docs/Web/API/PointerEvent/pointerType)
61 changes: 55 additions & 6 deletions packages/rrweb/src/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import {
getWindowHeight,
getWindowWidth,
isBlocked,
isTouchEvent,
legacy_isTouchEvent,
patch,
StyleSheetMirror,
} from '../utils';
Expand All @@ -24,6 +24,7 @@ import {
mousePosition,
mouseInteractionCallBack,
MouseInteractions,
PointerTypes,
listenerHandler,
scrollCallback,
styleSheetRuleCallback,
Expand Down Expand Up @@ -174,7 +175,8 @@ function initMoveObserver({
throttle<MouseEvent | TouchEvent | DragEvent>(
callbackWrapper((evt) => {
const target = getEventTarget(evt);
const { clientX, clientY } = isTouchEvent(evt)
// 'legacy' here as we could switch to https://developer.mozilla.org/en-US/docs/Web/API/Element/pointermove_event
const { clientX, clientY } = legacy_isTouchEvent(evt)
? evt.changedTouches[0]
: evt;
if (!timeBaseline) {
Expand Down Expand Up @@ -232,23 +234,58 @@ function initMouseInteractionObserver({
: sampling.mouseInteraction;

const handlers: listenerHandler[] = [];
let currentPointerType: PointerTypes | null = null;
const getHandler = (eventKey: keyof typeof MouseInteractions) => {
return (event: MouseEvent | TouchEvent) => {
return (event: MouseEvent | TouchEvent | PointerEvent) => {
const target = getEventTarget(event) as Node;
if (isBlocked(target, blockClass, blockSelector, true)) {
return;
}
const e = isTouchEvent(event) ? event.changedTouches[0] : event;
let pointerType: PointerTypes | null = null;
let thisEventKey = eventKey;
if ('pointerType' in event) {
Object.keys(PointerTypes).forEach(
(pointerKey: keyof typeof PointerTypes) => {
if (event.pointerType === pointerKey.toLowerCase()) {
pointerType = PointerTypes[pointerKey];
return;
}
},
);
if (pointerType === PointerTypes.Touch) {
if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {
// we are actually listening on 'pointerdown'
thisEventKey = 'TouchStart';
} else if (
MouseInteractions[eventKey] === MouseInteractions.MouseUp
) {
// we are actually listening on 'pointerup'
thisEventKey = 'TouchEnd';
}
} else if (pointerType == PointerTypes.Pen) {
// TODO: these will get incorrectly emitted as MouseDown/MouseUp
}
} else if (legacy_isTouchEvent(event)) {
pointerType = PointerTypes.Touch;
}
if (pointerType !== null) {
currentPointerType = pointerType;
} else if (MouseInteractions[eventKey] === MouseInteractions.Click) {
pointerType = currentPointerType;
currentPointerType = null; // cleanup as we've used it
}
const e = legacy_isTouchEvent(event) ? event.changedTouches[0] : event;
if (!e) {
return;
}
const id = mirror.getId(target);
const { clientX, clientY } = e;
callbackWrapper(mouseInteractionCb)({
type: MouseInteractions[eventKey],
type: MouseInteractions[thisEventKey],
id,
x: clientX,
y: clientY,
...(pointerType !== null && { pointerType }),
});
};
};
Expand All @@ -260,8 +297,20 @@ function initMouseInteractionObserver({
disableMap[key] !== false,
)
.forEach((eventKey: keyof typeof MouseInteractions) => {
const eventName = eventKey.toLowerCase();
let eventName = eventKey.toLowerCase();
const handler = getHandler(eventKey);
if (window.PointerEvent) {
switch (MouseInteractions[eventKey]) {
case MouseInteractions.MouseDown:
case MouseInteractions.MouseUp:
eventName = eventName.replace('mouse', 'pointer');
break;
case MouseInteractions.TouchStart:
case MouseInteractions.TouchEnd:
// these are handled by pointerdown/pointerup
return;
}
}
handlers.push(on(eventName, handler, doc));
});
return callbackWrapper(() => {
Expand Down
4 changes: 2 additions & 2 deletions packages/rrweb/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,8 @@ export function isAncestorRemoved(target: Node, mirror: Mirror): boolean {
return isAncestorRemoved(target.parentNode, mirror);
}

export function isTouchEvent(
event: MouseEvent | TouchEvent,
export function legacy_isTouchEvent(
event: MouseEvent | TouchEvent | PointerEvent,
): event is TouchEvent {
return Boolean((event as TouchEvent).changedTouches);
}
Expand Down
Loading

0 comments on commit 374e187

Please sign in to comment.