@@ -238,27 +238,34 @@ async function handleSelectionComplete(payload: any) {
238238 // Crop and add watermark via offscreen document
239239 await ensureOffscreenDocument ( ) ;
240240
241- const response = await chrome . runtime . sendMessage ( {
242- type : 'ADD_WATERMARK' ,
243- payload : {
244- dataUrl,
245- timestamp : captureTime . toISOString ( ) ,
246- width : coordinates . width ,
247- height : coordinates . height ,
248- timestampSize : settings . timestampSize ,
249- timestampFormat : settings . timestampFormat ,
250- timestampOpacity : settings . timestampOpacity ,
251- timestampPosition : settings . timestampPosition ,
252- includeTimestamp : settings . includeTimestamp ,
253- crop : coordinates ,
254- } ,
255- } ) ;
256-
257- if ( response . success ) {
258- dataUrl = response . data . dataUrl ;
241+ const watermarkResponse = await Promise . race ( [
242+ chrome . runtime . sendMessage ( {
243+ type : 'ADD_WATERMARK' ,
244+ payload : {
245+ dataUrl,
246+ timestamp : captureTime . toISOString ( ) ,
247+ width : coordinates . width ,
248+ height : coordinates . height ,
249+ timestampSize : settings . timestampSize ,
250+ timestampFormat : settings . timestampFormat ,
251+ timestampOpacity : settings . timestampOpacity ,
252+ timestampPosition : settings . timestampPosition ,
253+ includeTimestamp : settings . includeTimestamp ,
254+ outputFormat : settings . screenshotFormat === 'jpeg' ? 'jpeg' : 'png' ,
255+ outputQuality : settings . screenshotFormat === 'jpeg' ? settings . screenshotQuality / 100 : undefined ,
256+ crop : coordinates ,
257+ } ,
258+ } ) ,
259+ new Promise < never > ( ( _ , reject ) =>
260+ setTimeout ( ( ) => reject ( new Error ( 'Offscreen operation timed out' ) ) , 30000 )
261+ ) ,
262+ ] ) as any ;
263+
264+ if ( watermarkResponse . success ) {
265+ dataUrl = watermarkResponse . data . dataUrl ;
259266 console . log ( '✅ Selection cropped and watermark added' ) ;
260267 } else {
261- console . warn ( 'Failed to process selection:' , response . error ) ;
268+ console . warn ( 'Failed to process selection:' , watermarkResponse . error ) ;
262269 }
263270
264271 // Get location if enabled via offscreen document
@@ -418,6 +425,20 @@ async function handleScreenshotCapture(
418425 return await handleSelectionCapture ( tab ) ;
419426 }
420427
428+ // Check for restricted URLs that cannot be captured
429+ const restrictedPatterns = [
430+ / ^ c h r o m e : \/ \/ / ,
431+ / ^ c h r o m e - e x t e n s i o n : \/ \/ / ,
432+ / ^ h t t p s : \/ \/ c h r o m e \. g o o g l e \. c o m \/ w e b s t o r e / ,
433+ / ^ a b o u t : / ,
434+ / ^ e d g e : \/ \/ / ,
435+ ] ;
436+ if ( tab . url && restrictedPatterns . some ( ( re ) => re . test ( tab . url ! ) ) ) {
437+ throw new Error (
438+ 'Screenshots cannot be taken on this page. Please navigate to a regular website and try again.'
439+ ) ;
440+ }
441+
421442 // Capture timestamp at the very start for consistency
422443 const captureTime = new Date ( ) ;
423444
@@ -439,26 +460,33 @@ async function handleScreenshotCapture(
439460 try {
440461 await ensureOffscreenDocument ( ) ;
441462
442- const response = await chrome . runtime . sendMessage ( {
443- type : 'ADD_WATERMARK' ,
444- payload : {
445- dataUrl,
446- timestamp : captureTime . toISOString ( ) ,
447- width,
448- height,
449- timestampSize : settings . timestampSize ,
450- timestampFormat : settings . timestampFormat ,
451- timestampOpacity : settings . timestampOpacity ,
452- timestampPosition : settings . timestampPosition ,
453- includeTimestamp : settings . includeTimestamp ,
454- } ,
455- } ) ;
456-
457- if ( response . success ) {
458- dataUrl = response . data . dataUrl ;
463+ const watermarkResponse = await Promise . race ( [
464+ chrome . runtime . sendMessage ( {
465+ type : 'ADD_WATERMARK' ,
466+ payload : {
467+ dataUrl,
468+ timestamp : captureTime . toISOString ( ) ,
469+ width,
470+ height,
471+ timestampSize : settings . timestampSize ,
472+ timestampFormat : settings . timestampFormat ,
473+ timestampOpacity : settings . timestampOpacity ,
474+ timestampPosition : settings . timestampPosition ,
475+ includeTimestamp : settings . includeTimestamp ,
476+ outputFormat : settings . screenshotFormat === 'jpeg' ? 'jpeg' : 'png' ,
477+ outputQuality : settings . screenshotFormat === 'jpeg' ? settings . screenshotQuality / 100 : undefined ,
478+ } ,
479+ } ) ,
480+ new Promise < never > ( ( _ , reject ) =>
481+ setTimeout ( ( ) => reject ( new Error ( 'Offscreen operation timed out' ) ) , 30000 )
482+ ) ,
483+ ] ) as any ;
484+
485+ if ( watermarkResponse . success ) {
486+ dataUrl = watermarkResponse . data . dataUrl ;
459487 console . log ( '✅ Watermark added successfully' ) ;
460488 } else {
461- console . warn ( 'Failed to add watermark:' , response . error ) ;
489+ console . warn ( 'Failed to add watermark:' , watermarkResponse . error ) ;
462490 }
463491 } catch ( error ) {
464492 console . error ( 'Watermark error:' , error ) ;
0 commit comments