Files
rrweb/packages/rrweb/typings/utils.d.ts
Eoghan Murray 0d5b46068d The desktop pointer cursor is not representative of mobile (#662)
* Simplify css for click animation

* Refactor to transfer responsibility for casting multiple synchronous to index.ts from machine.ts (so they can be dealt with in bulk)

* During synchronous application of a batch of events, move the mouse to the last position so that it's in the correct place when the timer starts

 - previous `needCastInSyncMode` added in 4bf533a675 meant that the isSync versions of MouseMove/TouchMove were being accidentally ignored
 - each synchronous MouseMove would have resulted in a separate mouse position update
 - the Click/TouchStart/TouchEnd events didn't have an async version

* The desktop pointer cursor is not representative of what is happening on a mobile device.

Instead, check a recording for any presence of a Touch event, and switch to a touch visualisation mode for the entire recording.
(for now, we use this mode even for mixed touch/mouse devices - this could be improved upon in future)

Show a round circle representing the users' finger which is visible only between TouchStart and TouchEnd events
Again this can be evolved upon, but this change should be a good start in the right direction.

* It's more correct to not have a transition for repositioning of touch as user can lift finger off screen and place elsewhere; however we can now have much smoother touch movement during the .touch-active phase as we know the finger is on the screen. This has a .25s delaying effect on the touch position which IMO is acceptable; e.g. scroll position can lag behind a touch movement and this seems to bring them more in sync

* Ensure we end up with the correct touch-active state after a series of synchronous events

* Important to discontinue tail animations and position transitions when user has lifted their finger and placed it into a new position. This is apparent in a replay session where the user is scrolling the page using repeated TouchMove bottom-to-top movements

* Simplify by unwrapping `mouseState.touchActive` and `mouseState.pos` into their own global vars
2026-04-01 12:00:00 +08:00

70 lines
3.1 KiB
TypeScript

import { Mirror, throttleOptions, listenerHandler, hookResetter, blockClass, eventWithTime, addedNodeMutation, removedNodeMutation, textMutation, attributeMutation, mutationData, scrollData, inputData, DocumentDimension } from './types';
import { INode, serializedNodeWithId } from 'rrweb-snapshot';
export declare function on(type: string, fn: EventListenerOrEventListenerObject, target?: Document | Window): listenerHandler;
export declare function createMirror(): Mirror;
export declare let _mirror: Mirror;
export declare function throttle<T>(func: (arg: T) => void, wait: number, options?: throttleOptions): (arg: T) => void;
export declare function hookSetter<T>(target: T, key: string | number | symbol, d: PropertyDescriptor, isRevoked?: boolean, win?: Window & typeof globalThis): hookResetter;
export declare function patch(source: {
[key: string]: any;
}, name: string, replacement: (...args: any[]) => any): () => void;
export declare function getWindowHeight(): number;
export declare function getWindowWidth(): number;
export declare function isBlocked(node: Node | null, blockClass: blockClass): boolean;
export declare function isIgnored(n: Node | INode): boolean;
export declare function isAncestorRemoved(target: INode, mirror: Mirror): boolean;
export declare function isTouchEvent(event: MouseEvent | TouchEvent): event is TouchEvent;
export declare function polyfill(win?: Window & typeof globalThis): void;
export declare type TreeNode = {
id: number;
mutation: addedNodeMutation;
parent?: TreeNode;
children: Record<number, TreeNode>;
texts: textMutation[];
attributes: attributeMutation[];
};
export declare class TreeIndex {
tree: Record<number, TreeNode>;
private removeNodeMutations;
private textMutations;
private attributeMutations;
private indexes;
private removeIdSet;
private scrollMap;
private inputMap;
constructor();
add(mutation: addedNodeMutation): void;
remove(mutation: removedNodeMutation, mirror: Mirror): void;
text(mutation: textMutation): void;
attribute(mutation: attributeMutation): void;
scroll(d: scrollData): void;
input(d: inputData): void;
flush(): {
mutationData: mutationData;
scrollMap: TreeIndex['scrollMap'];
inputMap: TreeIndex['inputMap'];
};
private reset;
idRemoved(id: number): boolean;
}
declare type ResolveTree = {
value: addedNodeMutation;
children: ResolveTree[];
parent: ResolveTree | null;
};
export declare function queueToResolveTrees(queue: addedNodeMutation[]): ResolveTree[];
export declare function iterateResolveTree(tree: ResolveTree, cb: (mutation: addedNodeMutation) => unknown): void;
declare type HTMLIFrameINode = HTMLIFrameElement & {
__sn: serializedNodeWithId;
};
export declare type AppendedIframe = {
mutationInQueue: addedNodeMutation;
builtNode: HTMLIFrameINode;
};
export declare function isIframeINode(node: INode | ShadowRoot): node is HTMLIFrameINode;
export declare function getBaseDimension(node: Node, rootIframe: Node): DocumentDimension;
export declare function hasShadowRoot<T extends Node>(n: T): n is T & {
shadowRoot: ShadowRoot;
};
export {};