Skip to content

Commit

Permalink
Copy rrweb-io/rrweb#630 for DragEvent errors (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
John Pham authored Aug 6, 2021
1 parent f4d6bf9 commit dfbf895
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 25 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@highlight-run/rrweb",
"version": "0.12.3",
"version": "0.12.4",
"description": "record and replay the web",
"scripts": {
"test": "npm run bundle:browser && cross-env TS_NODE_CACHE=false TS_NODE_FILES=true mocha -r ts-node/register -r ignore-styles -r jsdom-global/register test/**.test.ts",
Expand Down
24 changes: 15 additions & 9 deletions src/record/mutation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,10 @@ export default class MutationBuffer {
const shadowHost: Element | null = n.getRootNode
? (n.getRootNode() as ShadowRoot)?.host
: null;
const notInDoc = !this.doc.contains(n) && !this.doc.contains(shadowHost);
// ensure shadowHost is a Node, or doc.contains will throw an error
const notInDoc =
!this.doc.contains(n) &&
(!(shadowHost instanceof Node) || !this.doc.contains(shadowHost));
if (!n.parentNode || notInDoc) {
return;
}
Expand All @@ -298,7 +301,7 @@ export default class MutationBuffer {
maskInputFn: this.maskInputFn,
slimDOMOptions: this.slimDOMOptions,
recordCanvas: this.recordCanvas,
enableStrictPrivacy: this.enableStrictPrivacy,
enableStrictPrivacy: this.enableStrictPrivacy,
onSerialize: (currentN) => {
if (isIframeINode(currentN)) {
this.iframeManager.addIframe(currentN);
Expand Down Expand Up @@ -362,13 +365,16 @@ export default class MutationBuffer {
if (!node) {
for (let index = addList.length - 1; index >= 0; index--) {
const _node = addList.get(index)!;
const parentId = this.mirror.getId(
(_node.value.parentNode as Node) as INode,
);
const nextId = getNextId(_node.value);
if (parentId !== -1 && nextId !== -1) {
node = _node;
break;
// ensure _node is defined before attempting to find value
if (_node) {
const parentId = this.mirror.getId(
(_node.value.parentNode as Node) as INode,
);
const nextId = getNextId(_node.value);
if (parentId !== -1 && nextId !== -1) {
node = _node;
break;
}
}
}
}
Expand Down
54 changes: 39 additions & 15 deletions src/record/observer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,21 +196,42 @@ function initMoveObserver(
},
callbackThreshold,
);
const updatePosition = throttle<MouseEvent | TouchEvent | DragEvent>(
// update position for mouse, touch, and drag events (drag event extends mouse event)
function handleUpdatePositionEvent(evt: MouseEvent | TouchEvent) {
const target = getEventTarget(evt);
const { clientX, clientY } = isTouchEvent(evt)
? evt.changedTouches[0]
: evt;
if (!timeBaseline) {
timeBaseline = Date.now();
}
positions.push({
x: clientX,
y: clientY,
id: mirror.getId(target as INode),
timeOffset: Date.now() - timeBaseline,
});
}

// separate call for non-drag events, in case DragEvent is not defined
const updatePosition = throttle<MouseEvent | TouchEvent>(
(evt) => {
const target = getEventTarget(evt);
const { clientX, clientY } = isTouchEvent(evt)
? evt.changedTouches[0]
: evt;
if (!timeBaseline) {
timeBaseline = Date.now();
}
positions.push({
x: clientX,
y: clientY,
id: mirror.getId(target as INode),
timeOffset: Date.now() - timeBaseline,
});
handleUpdatePositionEvent(evt);
wrappedCb(
evt instanceof MouseEvent
? IncrementalSource.MouseMove
: IncrementalSource.TouchMove,
);
},
threshold,
{
trailing: false,
},
);
// call for drag events, when DragEvent is defined
const updateDragPosition = throttle<MouseEvent | TouchEvent | DragEvent>(
(evt) => {
handleUpdatePositionEvent(evt);
wrappedCb(
evt instanceof DragEvent
? IncrementalSource.Drag
Expand All @@ -224,10 +245,13 @@ function initMoveObserver(
trailing: false,
},
);
// it is possible DragEvent is undefined even on devices
// that support event 'drag'
const dragEventDefined = typeof DragEvent !== 'undefined';
const handlers = [
on('mousemove', updatePosition, doc),
on('touchmove', updatePosition, doc),
on('drag', updatePosition, doc),
on('drag', dragEventDefined ? updateDragPosition : updatePosition, doc),
];
return () => {
handlers.forEach((h) => h());
Expand Down

0 comments on commit dfbf895

Please sign in to comment.