Guard against redefinition of Date.now (#1196)

* Guard against presence of likely older third party libraries which (re)define Date.now, e.g. https://github.com/datejs/Datejs/issues/92

* Apply formatting changes

* (remove nowTimestamp import where Date.now() is not used)

* Add a PURE marker so an empty `ìf` statement doesn't show up in the rrweb-replay output

* Update packages/rrweb/src/utils.ts

Fix typing issue with regex against `Date.now()`

Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>

* Create little-radios-thank.md

* Apply formatting changes

* Update .changeset/little-radios-thank.md

* Apply formatting changes

---------

Co-authored-by: eoghanmurray <eoghanmurray@users.noreply.github.com>
Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
This commit is contained in:
Eoghan Murray
2026-04-01 12:00:00 +08:00
committed by GitHub
parent e042576127
commit f29a30bfb7
5 changed files with 24 additions and 3 deletions

View File

@@ -0,0 +1,5 @@
---
'rrweb': patch
---
Guard against presence of older 3rd party javascript libraries which redefine Date.now()

View File

@@ -0,0 +1,5 @@
---
'rrweb': patch
---
Guard against redefinition of Date.now by third party libraries which are also present on a page alongside rrweb

View File

@@ -14,6 +14,7 @@ import {
hasShadowRoot, hasShadowRoot,
isSerializedIframe, isSerializedIframe,
isSerializedStylesheet, isSerializedStylesheet,
nowTimestamp,
} from '../utils'; } from '../utils';
import type { recordOptions } from '../types'; import type { recordOptions } from '../types';
import { import {
@@ -42,7 +43,7 @@ import {
function wrapEvent(e: event): eventWithTime { function wrapEvent(e: event): eventWithTime {
return { return {
...e, ...e,
timestamp: Date.now(), timestamp: nowTimestamp(),
}; };
} }

View File

@@ -17,6 +17,7 @@ import {
legacy_isTouchEvent, legacy_isTouchEvent,
patch, patch,
StyleSheetMirror, StyleSheetMirror,
nowTimestamp,
} from '../utils'; } from '../utils';
import type { observerParam, MutationBufferParam } from '../types'; import type { observerParam, MutationBufferParam } from '../types';
import { import {
@@ -181,13 +182,13 @@ function initMoveObserver({
? evt.changedTouches[0] ? evt.changedTouches[0]
: evt; : evt;
if (!timeBaseline) { if (!timeBaseline) {
timeBaseline = Date.now(); timeBaseline = nowTimestamp();
} }
positions.push({ positions.push({
x: clientX, x: clientX,
y: clientY, y: clientY,
id: mirror.getId(target as Node), id: mirror.getId(target as Node),
timeOffset: Date.now() - timeBaseline, timeOffset: nowTimestamp() - timeBaseline,
}); });
// it is possible DragEvent is undefined even on devices // it is possible DragEvent is undefined even on devices
// that support event 'drag' // that support event 'drag'

View File

@@ -168,6 +168,15 @@ export function patch(
} }
} }
// guard against old third party libraries which redefine Date.now
let nowTimestamp = Date.now;
if (!(/*@__PURE__*/ /[1-9][0-9]{12}/.test(Date.now().toString()))) {
// they have already redefined it! use a fallback
nowTimestamp = () => new Date().getTime();
}
export { nowTimestamp };
export function getWindowScroll(win: Window) { export function getWindowScroll(win: Window) {
const doc = win.document; const doc = win.document;
return { return {