diff --git a/.changeset/little-suits-leave.md b/.changeset/little-suits-leave.md index 29f44bb5ff..a1252eadb8 100644 --- a/.changeset/little-suits-leave.md +++ b/.changeset/little-suits-leave.md @@ -3,4 +3,4 @@ '@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 diff --git a/packages/rrweb/src/record/observer.ts b/packages/rrweb/src/record/observer.ts index 5aef5e4747..afd68f1864 100644 --- a/packages/rrweb/src/record/observer.ts +++ b/packages/rrweb/src/record/observer.ts @@ -244,14 +244,17 @@ function initMouseInteractionObserver({ 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; - } - }, - ); + switch (event.pointerType) { + case 'mouse': + pointerType = PointerTypes.Mouse; + break; + case 'touch': + pointerType = PointerTypes.Touch; + break; + case 'pen': + pointerType = PointerTypes.Pen; + break; + } if (pointerType === PointerTypes.Touch) { if (MouseInteractions[eventKey] === MouseInteractions.MouseDown) { // we are actually listening on 'pointerdown' @@ -262,7 +265,7 @@ function initMouseInteractionObserver({ // we are actually listening on 'pointerup' thisEventKey = 'TouchEnd'; } - } else if (pointerType == PointerTypes.Pen) { + } else if (pointerType === PointerTypes.Pen) { // TODO: these will get incorrectly emitted as MouseDown/MouseUp } } else if (legacy_isTouchEvent(event)) { @@ -270,6 +273,15 @@ function initMouseInteractionObserver({ } if (pointerType !== null) { 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) { pointerType = currentPointerType; currentPointerType = null; // cleanup as we've used it diff --git a/packages/rrweb/test/__snapshots__/integration.test.ts.snap b/packages/rrweb/test/__snapshots__/integration.test.ts.snap index 00c98f580e..f244948b67 100644 --- a/packages/rrweb/test/__snapshots__/integration.test.ts.snap +++ b/packages/rrweb/test/__snapshots__/integration.test.ts.snap @@ -1529,8 +1529,7 @@ exports[`record integration tests can record clicks 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 18, - \\"pointerType\\": 0 + \\"id\\": 18 } }, { @@ -1538,8 +1537,7 @@ exports[`record integration tests can record clicks 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 18, - \\"pointerType\\": 0 + \\"id\\": 18 } }, { @@ -1556,8 +1554,7 @@ exports[`record integration tests can record clicks 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 7, - \\"id\\": 18, - \\"pointerType\\": 2 + \\"id\\": 18 } }, { @@ -1565,8 +1562,7 @@ exports[`record integration tests can record clicks 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 9, - \\"id\\": 18, - \\"pointerType\\": 2 + \\"id\\": 18 } }, { @@ -1583,8 +1579,7 @@ exports[`record integration tests can record clicks 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 21, - \\"pointerType\\": 0 + \\"id\\": 21 } }, { @@ -1600,8 +1595,7 @@ exports[`record integration tests can record clicks 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 21, - \\"pointerType\\": 0 + \\"id\\": 21 } }, { @@ -2136,8 +2130,7 @@ exports[`record integration tests can record form interactions 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -2161,8 +2154,7 @@ exports[`record integration tests can record form interactions 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -2197,8 +2189,7 @@ exports[`record integration tests can record form interactions 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -2222,8 +2213,7 @@ exports[`record integration tests can record form interactions 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -2916,8 +2906,7 @@ exports[`record integration tests can record node mutations 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 26, - \\"pointerType\\": 0 + \\"id\\": 26 } }, { @@ -3374,8 +3363,7 @@ exports[`record integration tests can record node mutations 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 70, - \\"pointerType\\": 0 + \\"id\\": 70 } }, { @@ -3923,8 +3911,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -3948,8 +3935,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -3984,8 +3970,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -4009,8 +3994,7 @@ exports[`record integration tests can use maskInputOptions to configure which ty \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -4974,8 +4958,7 @@ exports[`record integration tests mutations should work when blocked class is un \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 42, - \\"pointerType\\": 0 + \\"id\\": 42 } }, { @@ -4991,8 +4974,7 @@ exports[`record integration tests mutations should work when blocked class is un \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 42, - \\"pointerType\\": 0 + \\"id\\": 42 } }, { @@ -5100,8 +5082,7 @@ exports[`record integration tests mutations should work when blocked class is un \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 68, - \\"pointerType\\": 0 + \\"id\\": 68 } }, { @@ -5125,8 +5106,7 @@ exports[`record integration tests mutations should work when blocked class is un \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 68, - \\"pointerType\\": 0 + \\"id\\": 68 } }, { @@ -5931,8 +5911,7 @@ exports[`record integration tests should mask inputs via function call 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -5956,8 +5935,7 @@ exports[`record integration tests should mask inputs via function call 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -5992,8 +5970,7 @@ exports[`record integration tests should mask inputs via function call 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -6017,8 +5994,7 @@ exports[`record integration tests should mask inputs via function call 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -6554,8 +6530,7 @@ exports[`record integration tests should mask password value attribute with mask \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 20, - \\"pointerType\\": 0 + \\"id\\": 20 } }, { @@ -6579,8 +6554,7 @@ exports[`record integration tests should mask password value attribute with mask \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 20, - \\"pointerType\\": 0 + \\"id\\": 20 } }, { @@ -6665,8 +6639,7 @@ exports[`record integration tests should mask password value attribute with mask \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 20, - \\"pointerType\\": 0 + \\"id\\": 20 } }, { @@ -6690,8 +6663,7 @@ exports[`record integration tests should mask password value attribute with mask \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 20, - \\"pointerType\\": 0 + \\"id\\": 20 } }, { @@ -9400,8 +9372,7 @@ exports[`record integration tests should not record input values if maskAllInput \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -9425,8 +9396,7 @@ exports[`record integration tests should not record input values if maskAllInput \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -9461,8 +9431,7 @@ exports[`record integration tests should not record input values if maskAllInput \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -9486,8 +9455,7 @@ exports[`record integration tests should not record input values if maskAllInput \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -11437,8 +11405,7 @@ exports[`record integration tests should record dynamic CSS changes 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 26, - \\"pointerType\\": 0 + \\"id\\": 26 } }, { @@ -11446,8 +11413,7 @@ exports[`record integration tests should record dynamic CSS changes 1`] = ` \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 26, - \\"pointerType\\": 0 + \\"id\\": 26 } }, { @@ -13119,8 +13085,7 @@ exports[`record integration tests should record input userTriggered values if us \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -13144,8 +13109,7 @@ exports[`record integration tests should record input userTriggered values if us \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 27, - \\"pointerType\\": 0 + \\"id\\": 27 } }, { @@ -13182,8 +13146,7 @@ exports[`record integration tests should record input userTriggered values if us \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { @@ -13207,8 +13170,7 @@ exports[`record integration tests should record input userTriggered values if us \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 37, - \\"pointerType\\": 0 + \\"id\\": 37 } }, { diff --git a/packages/rrweb/test/record/__snapshots__/cross-origin-iframes.test.ts.snap b/packages/rrweb/test/record/__snapshots__/cross-origin-iframes.test.ts.snap index a7607d666a..48d4bdb33a 100644 --- a/packages/rrweb/test/record/__snapshots__/cross-origin-iframes.test.ts.snap +++ b/packages/rrweb/test/record/__snapshots__/cross-origin-iframes.test.ts.snap @@ -1668,8 +1668,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] = \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 39, - \\"pointerType\\": 0 + \\"id\\": 39 } }, { @@ -1693,8 +1692,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] = \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 39, - \\"pointerType\\": 0 + \\"id\\": 39 } }, { @@ -1729,8 +1727,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] = \\"data\\": { \\"source\\": 2, \\"type\\": 1, - \\"id\\": 49, - \\"pointerType\\": 0 + \\"id\\": 49 } }, { @@ -1754,8 +1751,7 @@ exports[`cross origin iframes form.html should map input events correctly 1`] = \\"data\\": { \\"source\\": 2, \\"type\\": 0, - \\"id\\": 49, - \\"pointerType\\": 0 + \\"id\\": 49 } }, {