Skip to content

Commit

Permalink
Merge branch 'main' into benoit/avoid-csp-warnings-when-computing-act…
Browse files Browse the repository at this point in the history
…ion-name
  • Loading branch information
bcaudan authored Oct 6, 2021
2 parents cd097c8 + 4cb949c commit 5fe5ad6
Show file tree
Hide file tree
Showing 8 changed files with 277 additions and 45 deletions.
4 changes: 3 additions & 1 deletion packages/core/src/domain/sessionManagement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,10 +111,12 @@ export function startSessionManagement<TrackingType extends string>(
debug: {
initTime,
checkDelay,
updateDelay: Number(sessionCookieCheck.created!) - Number(inMemorySession.created!),
createdDelay: Number(sessionCookieCheck.created!) - Number(inMemorySession.created!),
expireDelay: Number(sessionCookieCheck.expire!) - Number(inMemorySession.expire!),
productKey,
sessionCookieCheck,
inMemorySession,
_dd_s: getCookie(SESSION_COOKIE_NAME),
},
})
}
Expand Down
74 changes: 64 additions & 10 deletions packages/rum/src/domain/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import {
addEventListener,
includes,
DefaultPrivacyLevel,
isExperimentalFeatureEnabled,
noop,
} from '@datadog/browser-core'
import { NodePrivacyLevel } from '../../constants'
import { getNodePrivacyLevel, shouldMaskNode } from './privacy'
Expand All @@ -28,10 +30,22 @@ import {
ScrollCallback,
StyleSheetRuleCallback,
ViewportResizeCallback,
VisualViewportResizeCallback,
MousePosition,
MouseInteractionParam,
} from './types'
import { forEach, getWindowHeight, getWindowWidth, hookSetter, isTouchEvent } from './utils'
import { forEach, hookSetter, isTouchEvent } from './utils'
import { startMutationObserver, MutationController } from './mutationObserver'

import {
getVisualViewport,
getWindowHeight,
getWindowWidth,
getScrollX,
getScrollY,
convertMouseEventToLayoutCoordinates,
} from './viewports'

const MOUSE_MOVE_OBSERVER_THRESHOLD = 50
const SCROLL_OBSERVER_THRESHOLD = 100

Expand All @@ -46,6 +60,10 @@ export function initObservers(o: ObserverParam): ListenerHandler {
const styleSheetObserver = initStyleSheetObserver(o.styleSheetRuleCb)
const focusHandler = initFocusObserver(o.focusCb)

const visualViewportResizeHandler = isExperimentalFeatureEnabled('visualviewport')
? initVisualViewportResizeObserver(o.visualViewportResizeCb)
: noop

return () => {
mutationHandler()
mousemoveHandler()
Expand All @@ -56,6 +74,7 @@ export function initObservers(o: ObserverParam): ListenerHandler {
mediaInteractionHandler()
styleSheetObserver()
focusHandler()
visualViewportResizeHandler()
}
}

Expand All @@ -73,12 +92,17 @@ function initMoveObserver(cb: MousemoveCallBack): ListenerHandler {
const target = event.target as Node
if (hasSerializedNode(target)) {
const { clientX, clientY } = isTouchEvent(event) ? event.changedTouches[0] : event
const position = {
const position: MousePosition = {
id: getSerializedNodeId(target),
timeOffset: 0,
x: clientX,
y: clientY,
}
if (isExperimentalFeatureEnabled('visualviewport')) {
const { visualViewportX, visualViewportY } = convertMouseEventToLayoutCoordinates(clientX, clientY)
position.x = visualViewportX ?? clientX
position.y = visualViewportY ?? clientY
}
cb([position], isTouchEvent(event) ? IncrementalSource.TouchMove : IncrementalSource.MouseMove)
}
}),
Expand Down Expand Up @@ -115,12 +139,18 @@ function initMouseInteractionObserver(
return
}
const { clientX, clientY } = isTouchEvent(event) ? event.changedTouches[0] : event
cb({
const position: MouseInteractionParam = {
id: getSerializedNodeId(target),
type: eventTypeToMouseInteraction[event.type as keyof typeof eventTypeToMouseInteraction],
x: clientX,
y: clientY,
})
}
if (isExperimentalFeatureEnabled('visualviewport')) {
const { visualViewportX, visualViewportY } = convertMouseEventToLayoutCoordinates(clientX, clientY)
position.x = visualViewportX ?? clientX
position.y = visualViewportY ?? clientY
}
cb(position)
}
return addEventListeners(document, Object.keys(eventTypeToMouseInteraction) as DOM_EVENT[], handler, {
capture: true,
Expand All @@ -141,12 +171,20 @@ function initScrollObserver(cb: ScrollCallback, defaultPrivacyLevel: DefaultPriv
}
const id = getSerializedNodeId(target)
if (target === document) {
const scrollEl = (document.scrollingElement || document.documentElement)!
cb({
id,
x: scrollEl.scrollLeft,
y: scrollEl.scrollTop,
})
if (isExperimentalFeatureEnabled('visualviewport')) {
cb({
id,
x: getScrollX(),
y: getScrollY(),
})
} else {
const scrollEl = (document.scrollingElement || document.documentElement)!
cb({
id,
x: scrollEl.scrollLeft,
y: scrollEl.scrollTop,
})
}
} else {
cb({
id,
Expand Down Expand Up @@ -338,3 +376,19 @@ function initFocusObserver(focusCb: FocusCallback): ListenerHandler {
focusCb({ has_focus: document.hasFocus() })
}).stop
}

function initVisualViewportResizeObserver(cb: VisualViewportResizeCallback): ListenerHandler {
if (!visualViewport) {
return noop
}
const { throttled: updateDimension } = throttle(
monitor(() => {
cb(getVisualViewport())
}),
200
)
return addEventListeners(visualViewport, [DOM_EVENT.RESIZE, DOM_EVENT.SCROLL], updateDimension, {
capture: true,
passive: true,
}).stop
}
32 changes: 17 additions & 15 deletions packages/rum/src/domain/record/record.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { isExperimentalFeatureEnabled } from '@datadog/browser-core'
import { RecordType } from '../../types'
import { serializeDocument } from './serialize'
import { initObservers } from './observer'
import { IncrementalSource, RecordAPI, RecordOptions } from './types'
import { getWindowHeight, getWindowWidth } from './utils'

import { MutationController } from './mutationObserver'
import { getVisualViewport, getScrollX, getScrollY, getWindowHeight, getWindowWidth } from './viewports'

export function record(options: RecordOptions): RecordAPI {
const { emit } = options
Expand Down Expand Up @@ -37,26 +39,21 @@ export function record(options: RecordOptions): RecordAPI {
data: {
node: serializeDocument(document, options.defaultPrivacyLevel),
initialOffset: {
left:
window.pageXOffset !== undefined
? window.pageXOffset
: document?.documentElement.scrollLeft ||
document?.body?.parentElement?.scrollLeft ||
document?.body.scrollLeft ||
0,
top:
window.pageYOffset !== undefined
? window.pageYOffset
: document?.documentElement.scrollTop ||
document?.body?.parentElement?.scrollTop ||
document?.body.scrollTop ||
0,
left: getScrollX(),
top: getScrollY(),
},
},
type: RecordType.FullSnapshot,
})
}

if (isExperimentalFeatureEnabled('visualviewport') && window.visualViewport) {
emit({
data: getVisualViewport(),
type: RecordType.VisualViewport,
})
}

takeFullSnapshot()

const stopObservers = initObservers({
Expand Down Expand Up @@ -131,6 +128,11 @@ export function record(options: RecordOptions): RecordAPI {
type: RecordType.Focus,
data,
}),
visualViewportResizeCb: (data) =>
emit({
data,
type: RecordType.VisualViewport,
}),
})

return {
Expand Down
7 changes: 5 additions & 2 deletions packages/rum/src/domain/record/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { DefaultPrivacyLevel } from '@datadog/browser-core'
import { FocusRecord, RawRecord } from '../../types'
import { FocusRecord, RawRecord, VisualViewportRecord } from '../../types'
import { MutationController } from './mutationObserver'

export enum IncrementalSource {
Expand Down Expand Up @@ -79,6 +79,7 @@ export interface ObserverParam {
mouseInteractionCb: MouseInteractionCallBack
scrollCb: ScrollCallback
viewportResizeCb: ViewportResizeCallback
visualViewportResizeCb: VisualViewportResizeCallback
inputCb: InputCallback
mediaInteractionCb: MediaInteractionCallback
styleSheetRuleCb: StyleSheetRuleCallback
Expand Down Expand Up @@ -181,7 +182,7 @@ export const MouseInteractions = {

export type MouseInteractions = typeof MouseInteractions[keyof typeof MouseInteractions]

interface MouseInteractionParam {
export interface MouseInteractionParam {
type: MouseInteractions
id: number
x: number
Expand Down Expand Up @@ -242,6 +243,8 @@ export type MediaInteractionCallback = (p: MediaInteractionParam) => void

export type FocusCallback = (data: FocusRecord['data']) => void

export type VisualViewportResizeCallback = (data: VisualViewportRecord['data']) => void

export type ListenerHandler = () => void
export type HookResetter = () => void

Expand Down
16 changes: 0 additions & 16 deletions packages/rum/src/domain/record/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,6 @@ export function hookSetter<T>(
}
}

export function getWindowHeight(): number {
return (
window.innerHeight ||
(document.documentElement && document.documentElement.clientHeight) ||
(document.body && document.body.clientHeight)
)
}

export function getWindowWidth(): number {
return (
window.innerWidth ||
(document.documentElement && document.documentElement.clientWidth) ||
(document.body && document.body.clientWidth)
)
}

export function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent {
return Boolean((event as TouchEvent).changedTouches)
}
Expand Down
48 changes: 48 additions & 0 deletions packages/rum/src/domain/record/viewports.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { isSafari } from 'packages/core/test/specHelper'
import { getScrollX, getScrollY, getWindowWidth, getWindowHeight } from './viewports'

describe('layout viewport', () => {
beforeEach(() => {
document.body.style.setProperty('margin-bottom', '2000px')
})

afterEach(() => {
document.body.style.removeProperty('margin-bottom')
})

describe('get window width and height', () => {
it('normalized scroll matches native behaviour', () => {
const initialInnerWidth = getWindowWidth()
const initialInnerHeight = getWindowHeight()
expect(initialInnerWidth).toBe(window.innerWidth)
expect(initialInnerHeight).toBe(window.innerHeight)
})
})

describe('getScrollX/Y', () => {
it('normalized scroll matches native behaviour', () => {
const SCROLL_DOWN_PX = 100
expect(getScrollX()).toBe(window.scrollX || window.pageXOffset)
expect(getScrollY()).toBe(window.scrollY || window.pageYOffset)

if (!isSafari) {
// Mobile Safari 12.0 (iOS 12.1) not responding to native scroll
window.scrollTo(0, SCROLL_DOWN_PX)
expect(getScrollX()).toBe(window.scrollX || window.pageXOffset)
expect(getScrollY()).toBe(window.scrollY || window.pageYOffset)
}
})
it('normalized scroll updates when scrolled', () => {
const SCROLL_DOWN_PX = 100
expect(getScrollX()).toBe(0)
expect(getScrollY()).toBe(0)

if (!isSafari) {
// Mobile Safari 12.0 (iOS 12.1) not responding to native scroll
window.scrollTo(0, SCROLL_DOWN_PX)
expect(getScrollX()).toBe(0)
expect(getScrollY()).toBe(100)
}
})
})
})
Loading

0 comments on commit 5fe5ad6

Please sign in to comment.