Files
tools-app/extension/offscreen.js

85 lines
2.2 KiB
JavaScript

// 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
chrome.runtime.onMessage.addListener((message) => {
if (message.target === 'offscreen') {
// Handle commands
if (message.type === 'play-sound') {
playNotificationSound();
} else if (message.type === 'write-clipboard') {
try {
const text = message.data;
if (text) {
textEl.value = text;
textEl.select();
document.execCommand('copy');
lastText = text; // Update internal state to avoid re-triggering update
}
} catch (e) {
console.error('Failed to write clipboard:', e);
}
}
}
});
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);
}