// offscreen.js // This script runs in the offscreen document to access DOM APIs like navigator.clipboard const textEl = document.querySelector('#text'); let lastText = ''; setInterval(async () => { try { textEl.focus(); textEl.value = ''; textEl.select(); // Method 1: execCommand try { document.execCommand('paste'); } catch (e) { // Ignore } let text = textEl.value; // Method 2: navigator.clipboard (Fallback) if (!text) { try { text = await navigator.clipboard.readText(); } catch (e) { // Silent fail for navigator } } if (text && text.trim().length > 0 && text !== lastText) { lastText = text; chrome.runtime.sendMessage({ type: 'clipboard-data', target: 'background', data: text }).catch(() => {}); } } catch (error) { // Ignore critical errors to keep running } }, 50); // Listen for messages from background if we need to change behavior chrome.runtime.onMessage.addListener((message) => { if (message.target === 'offscreen') { // Handle commands if (message.type === 'play-sound') { playNotificationSound(); } } }); function playNotificationSound() { const audioContext = new (window.AudioContext || window.webkitAudioContext)(); const oscillator = audioContext.createOscillator(); const gainNode = audioContext.createGain(); oscillator.connect(gainNode); gainNode.connect(audioContext.destination); oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(500, audioContext.currentTime); oscillator.frequency.exponentialRampToValueAtTime(1000, audioContext.currentTime + 0.1); gainNode.gain.setValueAtTime(0.1, audioContext.currentTime); gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.1); oscillator.start(); oscillator.stop(audioContext.currentTime + 0.1); }