Skip to content

Commit dbc29c5

Browse files
committed
DragEvent handling, null check fixes
1 parent 9875a3d commit dbc29c5

File tree

2 files changed

+54
-23
lines changed

2 files changed

+54
-23
lines changed

src/record/mutation.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,10 @@ export default class MutationBuffer {
270270
const shadowHost: Element | null = n.getRootNode
271271
? (n.getRootNode() as ShadowRoot)?.host
272272
: null;
273-
const notInDoc = !this.doc.contains(n) && !this.doc.contains(shadowHost);
273+
// ensure shadowHost is a Node, or doc.contains will throw an error
274+
const notInDoc =
275+
!this.doc.contains(n) &&
276+
(!(shadowHost instanceof Node) || !this.doc.contains(shadowHost));
274277
if (!n.parentNode || notInDoc) {
275278
return;
276279
}
@@ -358,13 +361,16 @@ export default class MutationBuffer {
358361
if (!node) {
359362
for (let index = addList.length - 1; index >= 0; index--) {
360363
const _node = addList.get(index)!;
361-
const parentId = this.mirror.getId(
362-
(_node.value.parentNode as Node) as INode,
363-
);
364-
const nextId = getNextId(_node.value);
365-
if (parentId !== -1 && nextId !== -1) {
366-
node = _node;
367-
break;
364+
// ensure _node is defined before attempting to find value
365+
if (_node) {
366+
const parentId = this.mirror.getId(
367+
(_node.value.parentNode as Node) as INode,
368+
);
369+
const nextId = getNextId(_node.value);
370+
if (parentId !== -1 && nextId !== -1) {
371+
node = _node;
372+
break;
373+
}
368374
}
369375
}
370376
}

src/record/observer.ts

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -194,21 +194,43 @@ function initMoveObserver(
194194
},
195195
callbackThreshold,
196196
);
197-
const updatePosition = throttle<MouseEvent | TouchEvent | DragEvent>(
197+
198+
// update position for mouse, touch, and drag events (drag event extends mouse event)
199+
function handleUpdatePositionEvent(evt: MouseEvent | TouchEvent) {
200+
const target = getEventTarget(evt);
201+
const { clientX, clientY } = isTouchEvent(evt)
202+
? evt.changedTouches[0]
203+
: evt;
204+
if (!timeBaseline) {
205+
timeBaseline = Date.now();
206+
}
207+
positions.push({
208+
x: clientX,
209+
y: clientY,
210+
id: mirror.getId(target as INode),
211+
timeOffset: Date.now() - timeBaseline,
212+
});
213+
}
214+
215+
// separate call for non-drag events, in case DragEvent is not defined
216+
const updatePosition = throttle<MouseEvent | TouchEvent>(
198217
(evt) => {
199-
const target = getEventTarget(evt);
200-
const { clientX, clientY } = isTouchEvent(evt)
201-
? evt.changedTouches[0]
202-
: evt;
203-
if (!timeBaseline) {
204-
timeBaseline = Date.now();
205-
}
206-
positions.push({
207-
x: clientX,
208-
y: clientY,
209-
id: mirror.getId(target as INode),
210-
timeOffset: Date.now() - timeBaseline,
211-
});
218+
handleUpdatePositionEvent(evt);
219+
wrappedCb(
220+
evt instanceof MouseEvent
221+
? IncrementalSource.MouseMove
222+
: IncrementalSource.TouchMove,
223+
);
224+
},
225+
threshold,
226+
{
227+
trailing: false,
228+
},
229+
);
230+
// call for drag events, when DragEvent is defined
231+
const updateDragPosition = throttle<MouseEvent | TouchEvent | DragEvent>(
232+
(evt) => {
233+
handleUpdatePositionEvent(evt);
212234
wrappedCb(
213235
evt instanceof DragEvent
214236
? IncrementalSource.Drag
@@ -222,10 +244,13 @@ function initMoveObserver(
222244
trailing: false,
223245
},
224246
);
247+
// it is possible DragEvent is undefined even on devices
248+
// that support event 'drag'
249+
const dragEventDefined = typeof DragEvent !== 'undefined';
225250
const handlers = [
226251
on('mousemove', updatePosition, doc),
227252
on('touchmove', updatePosition, doc),
228-
on('drag', updatePosition, doc),
253+
on('drag', dragEventDefined ? updateDragPosition : updatePosition, doc),
229254
];
230255
return () => {
231256
handlers.forEach((h) => h());

0 commit comments

Comments
 (0)