Skip to content

Commit

Permalink
stop computing coordinates for focus/blur records
Browse files Browse the repository at this point in the history
  • Loading branch information
bcaudan committed Jan 31, 2023
1 parent be0ff2a commit cd66e28
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 16 deletions.
70 changes: 68 additions & 2 deletions packages/rum/src/domain/record/observers.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,13 @@ import type { RawRumEventCollectedData } from 'packages/rum-core/src/domain/life
import { createNewEvent, isFirefox } from '../../../../core/test/specHelper'
import { NodePrivacyLevel, PRIVACY_ATTR_NAME, PRIVACY_ATTR_VALUE_MASK_USER_INPUT } from '../../constants'
import { RecordType } from '../../types'
import type { FrustrationCallback, InputCallback, StyleSheetCallback } from './observers'
import { initStyleSheetObserver, initFrustrationObserver, initInputObserver } from './observers'
import type { FrustrationCallback, InputCallback, MouseInteractionCallBack, StyleSheetCallback } from './observers'
import {
initStyleSheetObserver,
initFrustrationObserver,
initInputObserver,
initMouseInteractionObserver,
} from './observers'
import { serializeDocument, SerializationContextStatus } from './serialize'
import { createElementsScrollPositions } from './elementsScrollPositions'
import type { ShadowRootsController } from './shadowRootsController'
Expand Down Expand Up @@ -328,3 +333,64 @@ describe('initStyleSheetObserver', () => {
})
})
})

describe('initMouseInteractionObserver', () => {
let mouseInteractionCallbackSpy: jasmine.Spy<MouseInteractionCallBack>
let stopObserver: () => void
let sandbox: HTMLDivElement
let a: HTMLAnchorElement
let coordinatesComputed: boolean

beforeEach(() => {
if (isIE()) {
pending('IE not supported')
}
if (!window.visualViewport) {
pending('no visualViewport')
}

sandbox = document.createElement('div')
a = document.createElement('a')
a.setAttribute('tabindex', '0') // make the element focusable
sandbox.appendChild(a)
document.body.appendChild(sandbox)
a.focus()

serializeDocument(document, DEFAULT_CONFIGURATION, {
shadowRootsController: DEFAULT_SHADOW_ROOT_CONTROLLER,
status: SerializationContextStatus.INITIAL_FULL_SNAPSHOT,
elementsScrollPositions: createElementsScrollPositions(),
})

coordinatesComputed = false
Object.defineProperty(window.visualViewport, 'offsetTop', {
get() {
coordinatesComputed = true
return 0
},
configurable: true,
})

mouseInteractionCallbackSpy = jasmine.createSpy()
stopObserver = initMouseInteractionObserver(mouseInteractionCallbackSpy, DefaultPrivacyLevel.ALLOW)
})

afterEach(() => {
sandbox.remove()
delete (window.visualViewport as any).offsetTop
stopObserver()
})

it('should compute x/y coordinates for click record', () => {
a.click()
expect(mouseInteractionCallbackSpy).toHaveBeenCalled()
expect(coordinatesComputed).toBeTrue()
})

// related to safari issue, see RUMF-1450
it('should not compute x/y coordinates for blur record', () => {
a.blur()
expect(mouseInteractionCallbackSpy).toHaveBeenCalled()
expect(coordinatesComputed).toBeFalse()
})
})
36 changes: 22 additions & 14 deletions packages/rum/src/domain/record/observers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ type MousemoveCallBack = (

export type MutationCallBack = (m: BrowserMutationPayload) => void

type MouseInteractionCallBack = (record: BrowserIncrementalSnapshotRecord) => void
export type MouseInteractionCallBack = (record: BrowserIncrementalSnapshotRecord) => void

type ScrollCallback = (p: ScrollPosition) => void

Expand Down Expand Up @@ -194,7 +194,7 @@ const eventTypeToMouseInteraction = {
[DOM_EVENT.TOUCH_START]: MouseInteractionType.TouchStart,
[DOM_EVENT.TOUCH_END]: MouseInteractionType.TouchEnd,
}
function initMouseInteractionObserver(
export function initMouseInteractionObserver(
cb: MouseInteractionCallBack,
defaultPrivacyLevel: DefaultPrivacyLevel
): ListenerHandler {
Expand All @@ -203,22 +203,20 @@ function initMouseInteractionObserver(
if (getNodePrivacyLevel(target, defaultPrivacyLevel) === NodePrivacyLevel.HIDDEN || !hasSerializedNode(target)) {
return
}
const { clientX, clientY } = isTouchEvent(event) ? event.changedTouches[0] : event
const position: MouseInteraction = {
id: getSerializedNodeId(target),
type: eventTypeToMouseInteraction[event.type as keyof typeof eventTypeToMouseInteraction],
x: clientX,
y: clientY,
}
if (window.visualViewport) {
const { visualViewportX, visualViewportY } = convertMouseEventToLayoutCoordinates(clientX, clientY)
position.x = visualViewportX
position.y = visualViewportY
const id = getSerializedNodeId(target)
const type = eventTypeToMouseInteraction[event.type as keyof typeof eventTypeToMouseInteraction]

let interaction: MouseInteraction
if (type !== MouseInteractionType.Blur && type !== MouseInteractionType.Focus) {
const { x, y } = computeCoordinates(event)
interaction = { id, type, x, y }
} else {
interaction = { id, type }
}

const record = assign(
{ id: getRecordIdForEvent(event) },
assembleIncrementalSnapshot<MouseInteractionData>(IncrementalSource.MouseInteraction, position)
assembleIncrementalSnapshot<MouseInteractionData>(IncrementalSource.MouseInteraction, interaction)
)
cb(record)
}
Expand All @@ -228,6 +226,16 @@ function initMouseInteractionObserver(
}).stop
}

function computeCoordinates(event: MouseEvent | TouchEvent) {
let { clientX: x, clientY: y } = isTouchEvent(event) ? event.changedTouches[0] : event
if (window.visualViewport) {
const { visualViewportX, visualViewportY } = convertMouseEventToLayoutCoordinates(x, y)
x = visualViewportX
y = visualViewportY
}
return { x, y }
}

function initScrollObserver(
cb: ScrollCallback,
defaultPrivacyLevel: DefaultPrivacyLevel,
Expand Down

0 comments on commit cd66e28

Please sign in to comment.