export more props of replayer to the UI

This commit is contained in:
Yanzhen Yu
2018-10-17 17:47:38 +08:00
parent d827fdc947
commit 8186f05e1c
5 changed files with 68 additions and 16 deletions

6
index.d.ts vendored Normal file
View File

@@ -0,0 +1,6 @@
// TODO: remove this when mitt updated
declare namespace mitt {
interface MittStatic {
(all?: { [key: string]: Array<Handler> }): Emitter;
}
}

View File

@@ -2,7 +2,8 @@
"name": "rrweb", "name": "rrweb",
"version": "0.3.0", "version": "0.3.0",
"description": "record and replay the web", "description": "record and replay the web",
"main": "index.js", "main": "dist/index.js",
"module": "dist/module.js",
"scripts": { "scripts": {
"test": "TS_NODE_CACHE=false TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts", "test": "TS_NODE_CACHE=false TS_NODE_FILES=true mocha -r ts-node/register test/**/*.ts",
"bundle": "rollup --config" "bundle": "rollup --config"
@@ -38,6 +39,7 @@
"typescript": "^3.1.1" "typescript": "^3.1.1"
}, },
"dependencies": { "dependencies": {
"rrweb-snapshot": "file:../snapshot" "mitt": "^1.1.3",
"rrweb-snapshot": "^0.4.2"
} }
} }

View File

@@ -22,21 +22,21 @@ export default [
], ],
}, },
{ {
input: './src/replay/index.ts', input: './src/index.ts',
plugins: [typescript(), resolve()], plugins: [typescript(), resolve()],
output: [ output: [
{ {
format: 'cjs', format: 'cjs',
file: './dist/replay/index.js', file: './dist/index.js',
}, },
{ {
format: 'esm', format: 'esm',
file: './dist/replay/module.js', file: './dist/module.js',
}, },
{ {
name: 'replay', name: 'rrweb',
format: 'iife', format: 'iife',
file: './dist/replay/browser.js', file: './dist/browser.js',
}, },
], ],
}, },

View File

@@ -1,4 +1,5 @@
import { rebuild, serializeNodeWithId } from 'rrweb-snapshot'; import { rebuild, serializeNodeWithId } from 'rrweb-snapshot';
import * as mittProxy from 'mitt';
import { later, clear } from './timer'; import { later, clear } from './timer';
import { import {
EventType, EventType,
@@ -8,27 +9,44 @@ import {
eventWithTime, eventWithTime,
MouseInteractions, MouseInteractions,
playerConfig, playerConfig,
playerMetaData,
viewportResizeDimention,
} from '../types'; } from '../types';
import { mirror, getIdNodeMap } from '../utils'; import { mirror, getIdNodeMap } from '../utils';
// https://github.com/rollup/rollup/issues/1267#issuecomment-296395734
// tslint:disable-next-line
const mitt = (mittProxy as any).default || mittProxy;
const defaultConfig: playerConfig = { const defaultConfig: playerConfig = {
speed: 1, speed: 1,
root: document.body,
}; };
export class Replayer { export class Replayer {
public wrapper: HTMLDivElement;
private events: eventWithTime[] = []; private events: eventWithTime[] = [];
private config: playerConfig; private config: playerConfig;
private wrapper: HTMLDivElement;
private iframe: HTMLIFrameElement; private iframe: HTMLIFrameElement;
private mouse: HTMLDivElement; private mouse: HTMLDivElement;
private startTime: number = 0; private startTime: number = 0;
private timerIds: number[] = []; private timerIds: number[] = [];
private emitter: mitt.Emitter = mitt();
constructor(events: eventWithTime[], config: playerConfig = defaultConfig) { constructor(events: eventWithTime[], config?: Partial<playerConfig>) {
this.events = events; this.events = events;
this.config = config; this.handleResize = this.handleResize.bind(this);
this.setConfig(Object.assign({}, defaultConfig, config));
this.setupDom();
this.emitter.on('resize', this.handleResize as mitt.Handler);
}
public on(event: string, handler: mitt.Handler) {
this.emitter.on(event, handler);
} }
public setConfig(config: Partial<playerConfig>) { public setConfig(config: Partial<playerConfig>) {
@@ -38,16 +56,30 @@ export class Replayer {
}; };
} }
public getMetaData(): playerMetaData {
if (this.events.length < 2) {
return {
totalTime: 0,
};
}
const firstEvent = this.events[0];
const lastEvent = this.events[this.events.length - 1];
return {
totalTime: lastEvent.timestamp - firstEvent.timestamp,
};
}
public play() { public play() {
this.setupDom();
for (const event of this.events) { for (const event of this.events) {
switch (event.type) { switch (event.type) {
case EventType.DomContentLoaded: case EventType.DomContentLoaded:
this.startTime = event.timestamp; this.startTime = event.timestamp;
break; break;
case EventType.Load: case EventType.Load:
this.iframe.width = `${event.data.width}px`; this.emitter.emit('resize', {
this.iframe.height = `${event.data.height}px`; width: event.data.width,
height: event.data.height,
});
break; break;
case EventType.FullSnapshot: case EventType.FullSnapshot:
this.later(() => { this.later(() => {
@@ -72,7 +104,7 @@ export class Replayer {
private setupDom() { private setupDom() {
this.wrapper = document.createElement('div'); this.wrapper = document.createElement('div');
this.wrapper.classList.add('replayer-wrapper'); this.wrapper.classList.add('replayer-wrapper');
document.body.appendChild(this.wrapper); this.config.root.appendChild(this.wrapper);
this.mouse = document.createElement('div'); this.mouse = document.createElement('div');
this.mouse.classList.add('replayer-mouse'); this.mouse.classList.add('replayer-mouse');
@@ -82,6 +114,11 @@ export class Replayer {
this.wrapper.appendChild(this.iframe); this.wrapper.appendChild(this.iframe);
} }
private handleResize(dimension: viewportResizeDimention) {
this.iframe.width = `${dimension.width}px`;
this.iframe.height = `${dimension.height}px`;
}
private later(cb: () => void, delayMs: number) { private later(cb: () => void, delayMs: number) {
const id = later(cb, delayMs, this.config.speed); const id = later(cb, delayMs, this.config.speed);
this.timerIds.push(id); this.timerIds.push(id);
@@ -213,8 +250,10 @@ export class Replayer {
break; break;
} }
case IncrementalSource.ViewportResize: case IncrementalSource.ViewportResize:
this.iframe.width = `${d.width}px`; this.emitter.emit('resize', {
this.iframe.height = `${d.height}px`; width: d.width,
height: d.height,
});
break; break;
case IncrementalSource.Input: { case IncrementalSource.Input: {
const target: HTMLInputElement = (mirror.getNode( const target: HTMLInputElement = (mirror.getNode(

View File

@@ -206,4 +206,9 @@ export type hookResetter = () => void;
export type playerConfig = { export type playerConfig = {
speed: number; speed: number;
root: Element;
};
export type playerMetaData = {
totalTime: number;
}; };