Reduce verbosity/redundancy of new pointerType attribute (#1206)

* Reduce verbosity/redundancy of output of new pointerType attribute by confining it only to clicks (and to a MouseDown/MouseUp from a PointerTypes.Pen, as these don't yet have a dedicated PendDown/PenUp)

* Update how the changeset will read for the next release based on the trimming in this PR

* Prefer triple equals

* The assignment to the outer `pointerType` variable in an anonymous function was somehow missed by the `typings` check

* Apply formatting changes

* Update packages/rrweb/src/record/observer.ts

* Update packages/rrweb/src/record/observer.ts

---------

Co-authored-by: Yun Feng <yun.feng0817@gmail.com>
This commit is contained in:
Eoghan Murray
2026-04-01 12:00:00 +08:00
committed by GitHub
parent ec5e536891
commit aa4c7f9820
4 changed files with 64 additions and 94 deletions

View File

@@ -3,4 +3,4 @@
'@rrweb/types': 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) click 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). There is no new PenDown/PenUp events, but these can be detected with a MouseDown/MouseUp + pointerType=pen

View File

@@ -244,14 +244,17 @@ function initMouseInteractionObserver({
let pointerType: PointerTypes | null = null; let pointerType: PointerTypes | null = null;
let thisEventKey = eventKey; let thisEventKey = eventKey;
if ('pointerType' in event) { if ('pointerType' in event) {
Object.keys(PointerTypes).forEach( switch (event.pointerType) {
(pointerKey: keyof typeof PointerTypes) => { case 'mouse':
if (event.pointerType === pointerKey.toLowerCase()) { pointerType = PointerTypes.Mouse;
pointerType = PointerTypes[pointerKey]; break;
return; case 'touch':
} pointerType = PointerTypes.Touch;
}, break;
); case 'pen':
pointerType = PointerTypes.Pen;
break;
}
if (pointerType === PointerTypes.Touch) { if (pointerType === PointerTypes.Touch) {
if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) { if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) {
// we are actually listening on 'pointerdown' // we are actually listening on 'pointerdown'
@@ -262,7 +265,7 @@ function initMouseInteractionObserver({
// we are actually listening on 'pointerup' // we are actually listening on 'pointerup'
thisEventKey = 'TouchEnd'; thisEventKey = 'TouchEnd';
} }
} else if (pointerType == PointerTypes.Pen) { } else if (pointerType === PointerTypes.Pen) {
// TODO: these will get incorrectly emitted as MouseDown/MouseUp // TODO: these will get incorrectly emitted as MouseDown/MouseUp
} }
} else if (legacy_isTouchEvent(event)) { } else if (legacy_isTouchEvent(event)) {
@@ -270,6 +273,15 @@ function initMouseInteractionObserver({
} }
if (pointerType !== null) { if (pointerType !== null) {
currentPointerType = pointerType; currentPointerType = pointerType;
if (
(thisEventKey.startsWith('Touch') &&
pointerType === PointerTypes.Touch) ||
(thisEventKey.startsWith('Mouse') &&
pointerType === PointerTypes.Mouse)
) {
// don't output redundant info
pointerType = null;
}
} else if (MouseInteractions[eventKey] === MouseInteractions.Click) { } else if (MouseInteractions[eventKey] === MouseInteractions.Click) {
pointerType = currentPointerType; pointerType = currentPointerType;
currentPointerType = null; // cleanup as we've used it currentPointerType = null; // cleanup as we've used it

View File

@@ -1529,8 +1529,7 @@ exports[`record integration tests can record clicks 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 18, \\"id\\": 18
\\"pointerType\\": 0
} }
}, },
{ {
@@ -1538,8 +1537,7 @@ exports[`record integration tests can record clicks 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 18, \\"id\\": 18
\\"pointerType\\": 0
} }
}, },
{ {
@@ -1556,8 +1554,7 @@ exports[`record integration tests can record clicks 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 7, \\"type\\": 7,
\\"id\\": 18, \\"id\\": 18
\\"pointerType\\": 2
} }
}, },
{ {
@@ -1565,8 +1562,7 @@ exports[`record integration tests can record clicks 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 9, \\"type\\": 9,
\\"id\\": 18, \\"id\\": 18
\\"pointerType\\": 2
} }
}, },
{ {
@@ -1583,8 +1579,7 @@ exports[`record integration tests can record clicks 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 21, \\"id\\": 21
\\"pointerType\\": 0
} }
}, },
{ {
@@ -1600,8 +1595,7 @@ exports[`record integration tests can record clicks 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 21, \\"id\\": 21
\\"pointerType\\": 0
} }
}, },
{ {
@@ -2136,8 +2130,7 @@ exports[`record integration tests can record form interactions 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -2161,8 +2154,7 @@ exports[`record integration tests can record form interactions 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -2197,8 +2189,7 @@ exports[`record integration tests can record form interactions 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -2222,8 +2213,7 @@ exports[`record integration tests can record form interactions 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -2916,8 +2906,7 @@ exports[`record integration tests can record node mutations 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 26, \\"id\\": 26
\\"pointerType\\": 0
} }
}, },
{ {
@@ -3374,8 +3363,7 @@ exports[`record integration tests can record node mutations 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 70, \\"id\\": 70
\\"pointerType\\": 0
} }
}, },
{ {
@@ -3923,8 +3911,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -3948,8 +3935,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -3984,8 +3970,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -4009,8 +3994,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -4974,8 +4958,7 @@ exports[`record integration tests mutations should work when blocked class is un
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 42, \\"id\\": 42
\\"pointerType\\": 0
} }
}, },
{ {
@@ -4991,8 +4974,7 @@ exports[`record integration tests mutations should work when blocked class is un
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 42, \\"id\\": 42
\\"pointerType\\": 0
} }
}, },
{ {
@@ -5100,8 +5082,7 @@ exports[`record integration tests mutations should work when blocked class is un
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 68, \\"id\\": 68
\\"pointerType\\": 0
} }
}, },
{ {
@@ -5125,8 +5106,7 @@ exports[`record integration tests mutations should work when blocked class is un
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 68, \\"id\\": 68
\\"pointerType\\": 0
} }
}, },
{ {
@@ -5931,8 +5911,7 @@ exports[`record integration tests should mask inputs via function call 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -5956,8 +5935,7 @@ exports[`record integration tests should mask inputs via function call 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -5992,8 +5970,7 @@ exports[`record integration tests should mask inputs via function call 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -6017,8 +5994,7 @@ exports[`record integration tests should mask inputs via function call 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -6554,8 +6530,7 @@ exports[`record integration tests should mask password value attribute with mask
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 20, \\"id\\": 20
\\"pointerType\\": 0
} }
}, },
{ {
@@ -6579,8 +6554,7 @@ exports[`record integration tests should mask password value attribute with mask
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 20, \\"id\\": 20
\\"pointerType\\": 0
} }
}, },
{ {
@@ -6665,8 +6639,7 @@ exports[`record integration tests should mask password value attribute with mask
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 20, \\"id\\": 20
\\"pointerType\\": 0
} }
}, },
{ {
@@ -6690,8 +6663,7 @@ exports[`record integration tests should mask password value attribute with mask
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 20, \\"id\\": 20
\\"pointerType\\": 0
} }
}, },
{ {
@@ -9400,8 +9372,7 @@ exports[`record integration tests should not record input values if maskAllInput
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -9425,8 +9396,7 @@ exports[`record integration tests should not record input values if maskAllInput
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -9461,8 +9431,7 @@ exports[`record integration tests should not record input values if maskAllInput
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -9486,8 +9455,7 @@ exports[`record integration tests should not record input values if maskAllInput
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -11437,8 +11405,7 @@ exports[`record integration tests should record dynamic CSS changes 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 26, \\"id\\": 26
\\"pointerType\\": 0
} }
}, },
{ {
@@ -11446,8 +11413,7 @@ exports[`record integration tests should record dynamic CSS changes 1`] = `
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 26, \\"id\\": 26
\\"pointerType\\": 0
} }
}, },
{ {
@@ -13119,8 +13085,7 @@ exports[`record integration tests should record input userTriggered values if us
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -13144,8 +13109,7 @@ exports[`record integration tests should record input userTriggered values if us
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 27, \\"id\\": 27
\\"pointerType\\": 0
} }
}, },
{ {
@@ -13182,8 +13146,7 @@ exports[`record integration tests should record input userTriggered values if us
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {
@@ -13207,8 +13170,7 @@ exports[`record integration tests should record input userTriggered values if us
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 37, \\"id\\": 37
\\"pointerType\\": 0
} }
}, },
{ {

View File

@@ -1668,8 +1668,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] =
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 39, \\"id\\": 39
\\"pointerType\\": 0
} }
}, },
{ {
@@ -1693,8 +1692,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] =
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 39, \\"id\\": 39
\\"pointerType\\": 0
} }
}, },
{ {
@@ -1729,8 +1727,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] =
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 1, \\"type\\": 1,
\\"id\\": 49, \\"id\\": 49
\\"pointerType\\": 0
} }
}, },
{ {
@@ -1754,8 +1751,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] =
\\"data\\": { \\"data\\": {
\\"source\\": 2, \\"source\\": 2,
\\"type\\": 0, \\"type\\": 0,
\\"id\\": 49, \\"id\\": 49
\\"pointerType\\": 0
} }
}, },
{ {