Files
rrweb/rrweb-simple-ext/popup.js
zhaoyilun 27a17d7068
Some checks failed
Tests / Tests (push) Has been cancelled
ESLint Check / ESLint Check and Report Upload (push) Has been cancelled
Prettier Check / Format Check (push) Has been cancelled
Prettier Check / Format Code (push) Has been cancelled
ESLint Check / Build Base for Bundle Size Comparison (push) Has been cancelled
Add SuperRPA integration guide, simple extension and standalone replay page
- docs/integration/superrpa-integration.zh_CN.md: complete integration guide
- rrweb-simple-ext/: minimal Chrome extension for page recording
- replay.html: standalone drag-and-drop replay viewer
- CLAUDE.md: project instructions

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-10 17:08:24 +08:00

94 lines
2.8 KiB
JavaScript

const startBtn = document.getElementById('startBtn');
const stopBtn = document.getElementById('stopBtn');
const viewBtn = document.getElementById('viewBtn');
const downloadBtn = document.getElementById('downloadBtn');
const statusDiv = document.getElementById('status');
const eventsDiv = document.getElementById('events');
function updateStatus(text) {
statusDiv.textContent = text;
}
function setRecording(isRecording) {
startBtn.disabled = isRecording;
startBtn.classList.toggle('disabled', isRecording);
stopBtn.disabled = !isRecording;
stopBtn.classList.toggle('disabled', !isRecording);
}
startBtn.addEventListener('click', async () => {
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
if (!tab) return;
// First inject content script programmatically
try {
await chrome.scripting.executeScript({
target: { tabId: tab.id },
files: ['content.js']
});
} catch(e) {
// Might already be injected, that's ok
}
chrome.runtime.sendMessage({ action: 'startRecording', tabId: tab.id }, (resp) => {
if (resp && resp.ok) {
setRecording(true);
updateStatus('Recording...');
}
});
});
stopBtn.addEventListener('click', () => {
chrome.runtime.sendMessage({ action: 'stopRecording' }, (resp) => {
if (resp && resp.ok) {
setRecording(false);
updateStatus('Stopped. Captured ' + resp.eventCount + ' events.');
viewBtn.disabled = false;
viewBtn.classList.remove('disabled');
downloadBtn.disabled = false;
downloadBtn.classList.remove('disabled');
}
});
});
viewBtn.addEventListener('click', () => {
chrome.runtime.sendMessage({ action: 'getEvents' }, (resp) => {
if (resp && resp.events) {
const summary = resp.events.map((e, i) =>
`${i}: type=${e.type} ts=${e.timestamp}`
).join('\n');
eventsDiv.textContent = `Total: ${resp.events.length} events\n\n${summary}`;
}
});
});
downloadBtn.addEventListener('click', () => {
chrome.runtime.sendMessage({ action: 'getEvents' }, (resp) => {
if (resp && resp.events) {
const blob = new Blob([JSON.stringify(resp.events, null, 2)], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'rrweb-events.json';
a.click();
URL.revokeObjectURL(url);
}
});
});
// Check current status on open
chrome.runtime.sendMessage({ action: 'getStatus' }, (resp) => {
if (resp) {
setRecording(resp.recording);
updateStatus(resp.recording
? 'Recording... (' + resp.eventCount + ' events)'
: 'Ready');
if (resp.eventCount > 0) {
viewBtn.disabled = false;
viewBtn.classList.remove('disabled');
downloadBtn.disabled = false;
downloadBtn.classList.remove('disabled');
}
}
});