Skip to content

Commit 051b827

Browse files
MaxGhenisclaude
andcommitted
Fix: Move scroll injection to service worker
Offscreen documents can only use chrome.runtime API, not chrome.scripting. This was likely causing the Chrome crash when reloading the extension. - offscreen.js now sends 'injectScroll' message to service worker - background.js handles scroll script injection via chrome.scripting.executeScript Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 9110b06 commit 051b827

2 files changed

Lines changed: 69 additions & 28 deletions

File tree

background.js

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,44 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
66
startRecording(message.tabId, message.duration, message.delay);
77
sendResponse({ status: 'started' });
88
}
9+
if (message.action === 'injectScroll') {
10+
injectScrollScript(message.tabId, message.duration);
11+
sendResponse({ status: 'injected' });
12+
}
913
if (message.action === 'recordingComplete') {
1014
handleRecordingComplete();
1115
console.log('Recording saved!');
1216
}
1317
return true;
1418
});
19+
20+
// Inject scroll script into target tab (called by offscreen document)
21+
async function injectScrollScript(tabId, duration) {
22+
try {
23+
console.log('Injecting scroll script for', duration, 'seconds');
24+
await chrome.scripting.executeScript({
25+
target: { tabId },
26+
func: (scrollDuration) => {
27+
const totalHeight = document.documentElement.scrollHeight - window.innerHeight;
28+
const startTime = Date.now();
29+
const endTime = startTime + (scrollDuration * 1000);
30+
31+
function smoothScroll() {
32+
const now = Date.now();
33+
if (now >= endTime) return;
34+
35+
const progress = (now - startTime) / (scrollDuration * 1000);
36+
const targetY = totalHeight * progress;
37+
window.scrollTo({ top: targetY, behavior: 'instant' });
38+
39+
requestAnimationFrame(smoothScroll);
40+
}
41+
42+
smoothScroll();
43+
},
44+
args: [duration],
45+
});
46+
} catch (error) {
47+
console.error('Failed to inject scroll script:', error);
48+
}
49+
}

offscreen.js

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -31,58 +31,64 @@ async function startCapture(streamId, tabId, duration, delay) {
3131
});
3232

3333
mediaRecorder.ondataavailable = (event) => {
34+
console.log('Data available:', event.data.size, 'bytes');
3435
if (event.data.size > 0) {
3536
recordedChunks.push(event.data);
3637
}
3738
};
3839

3940
mediaRecorder.onstop = async () => {
41+
console.log('MediaRecorder stopped, chunks:', recordedChunks.length);
4042
stream.getTracks().forEach(track => track.stop());
4143

4244
const blob = new Blob(recordedChunks, { type: 'video/webm' });
45+
console.log('Blob size:', blob.size, 'bytes');
46+
47+
if (blob.size === 0) {
48+
console.error('Empty recording - no data captured');
49+
chrome.runtime.sendMessage({ action: 'recordingComplete' });
50+
return;
51+
}
52+
4353
const url = URL.createObjectURL(blob);
54+
console.log('Blob URL:', url);
4455

4556
// Download the video
4657
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
47-
await chrome.downloads.download({
48-
url: url,
49-
filename: `scrollywood-${timestamp}.webm`,
50-
saveAs: true,
51-
});
58+
const filename = `scrollywood-${timestamp}.webm`;
59+
console.log('Downloading as:', filename);
60+
61+
try {
62+
const downloadId = await chrome.downloads.download({
63+
url: url,
64+
filename: filename,
65+
saveAs: true,
66+
});
67+
console.log('Download started, ID:', downloadId);
68+
} catch (err) {
69+
console.error('Download error:', err);
70+
}
5271

5372
chrome.runtime.sendMessage({ action: 'recordingComplete' });
5473
};
5574

75+
mediaRecorder.onerror = (event) => {
76+
console.error('MediaRecorder error:', event.error);
77+
};
78+
5679
// Start recording
5780
mediaRecorder.start(1000);
5881
console.log('Recording started, waiting for delay...');
5982

6083
// Wait for initial delay
6184
await sleep(delay * 1000);
6285

63-
// Inject scroll script
64-
console.log('Starting scroll...');
65-
await chrome.scripting.executeScript({
66-
target: { tabId },
67-
func: (scrollDuration) => {
68-
const totalHeight = document.documentElement.scrollHeight - window.innerHeight;
69-
const startTime = Date.now();
70-
const endTime = startTime + (scrollDuration * 1000);
71-
72-
function smoothScroll() {
73-
const now = Date.now();
74-
if (now >= endTime) return;
75-
76-
const progress = (now - startTime) / (scrollDuration * 1000);
77-
const targetY = totalHeight * progress;
78-
window.scrollTo({ top: targetY, behavior: 'instant' });
79-
80-
requestAnimationFrame(smoothScroll);
81-
}
82-
83-
smoothScroll();
84-
},
85-
args: [duration],
86+
// Ask service worker to inject scroll script (scripting API not available in offscreen)
87+
console.log('Requesting scroll injection...');
88+
chrome.runtime.sendMessage({
89+
action: 'injectScroll',
90+
tabId,
91+
duration,
8692
});
8793

8894
// Wait for scroll to complete plus extra time at the end

0 commit comments

Comments
 (0)