rrweb extension implementation (#1044)
* feat: add rrweb web-extension package * refactor: make the extension suitable for manifest v3 * update tsconfig.json * use version_name rather than recorder_version in manifest.json * update manifest.json * enable to keep recording after changing tabs * enable to record between tabs and urls * fix CI error * try to fix CI error * feat: add pause and resume buttons * feat: add a link to new session after recording * improve session list * refactor: migrate session storage from chrome local storage to indexedDB * feat: add pagination to session list * fix: multiple recorders are started after pausing and resuming process * fix: can't stop recording on firefox browser * update type import of 'eventWithTime' * fix CI error * doc: add readme * Apply suggestions from Justin's code review Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com> * refactor: make use of webNavigation API to implement recording consistent during page navigation * fix firefox compatibility issue and add title to pages * add mouseleave listener to enhance the recording liability * fix firefox compatibility issue and improve the experience of recording resume after closing tabs * update tsconfig * upgrade vite-plugin-web-extension config to fix some bugs on facebook web page * update import links * refactor: cross tab recording mechanism apply Justin's suggestion * refactor: slipt util/index.ts into multiple files * implement cross-origin iframe recording * fix: regression of issue: ShadowHost can't be a string (issue 941) * refactor shadow dom recording to make tests cover key code * Apply formatting changes * increase the node memory limitation to avoid CI failure * Create lovely-pears-cross.md * Apply formatting changes * Update packages/web-extension/package.json * Update .changeset/lovely-pears-cross.md * update change logs * delete duplicated property --------- Co-authored-by: Justin Halsall <Juice10@users.noreply.github.com>
This commit is contained in:
72
packages/web-extension/src/content/inject.ts
Normal file
72
packages/web-extension/src/content/inject.ts
Normal file
@@ -0,0 +1,72 @@
|
||||
import { record } from 'rrweb';
|
||||
import type { recordOptions } from 'rrweb/typings/types';
|
||||
import type { eventWithTime } from '@rrweb/types';
|
||||
import { MessageName, RecordStartedMessage } from '~/types';
|
||||
import { isInCrossOriginIFrame } from '~/utils';
|
||||
|
||||
/**
|
||||
* This script is injected into both main page and cross-origin IFrames through <script> tags.
|
||||
*/
|
||||
|
||||
const events: eventWithTime[] = [];
|
||||
let stopFn: (() => void) | null = null;
|
||||
|
||||
function startRecord(config: recordOptions<eventWithTime>) {
|
||||
events.length = 0;
|
||||
stopFn =
|
||||
record({
|
||||
emit: (event) => {
|
||||
events.push(event);
|
||||
postMessage({
|
||||
message: MessageName.EmitEvent,
|
||||
event,
|
||||
});
|
||||
},
|
||||
...config,
|
||||
}) || null;
|
||||
postMessage({
|
||||
message: MessageName.RecordStarted,
|
||||
startTimestamp: Date.now(),
|
||||
} as RecordStartedMessage);
|
||||
}
|
||||
|
||||
const messageHandler = (
|
||||
event: MessageEvent<{
|
||||
message: MessageName;
|
||||
config?: recordOptions<eventWithTime>;
|
||||
}>,
|
||||
) => {
|
||||
if (event.source !== window) return;
|
||||
const data = event.data;
|
||||
const eventHandler = {
|
||||
[MessageName.StartRecord]: () => {
|
||||
startRecord(data.config || {});
|
||||
},
|
||||
[MessageName.StopRecord]: () => {
|
||||
if (stopFn) stopFn();
|
||||
postMessage({
|
||||
message: MessageName.RecordStopped,
|
||||
events,
|
||||
endTimestamp: Date.now(),
|
||||
});
|
||||
window.removeEventListener('message', messageHandler);
|
||||
},
|
||||
} as Record<MessageName, () => void>;
|
||||
if (eventHandler[data.message]) eventHandler[data.message]();
|
||||
};
|
||||
|
||||
/**
|
||||
* Only post message in the main page.
|
||||
*/
|
||||
function postMessage(message: unknown) {
|
||||
if (!isInCrossOriginIFrame()) window.postMessage(message, location.origin);
|
||||
}
|
||||
|
||||
window.addEventListener('message', messageHandler);
|
||||
|
||||
window.postMessage(
|
||||
{
|
||||
message: MessageName.RecordScriptReady,
|
||||
},
|
||||
location.origin,
|
||||
);
|
||||
Reference in New Issue
Block a user