// Popup script for DocuElevate browser extension // DOM elements const configSection = document.getElementById('config-section'); const modeSection = document.getElementById('mode-section'); const sendSection = document.getElementById('send-section'); const clipSection = document.getElementById('clip-section'); const statusSection = document.getElementById('status-section'); const statusMessage = document.getElementById('status-message'); const serverUrlInput = document.getElementById('server-url'); const sessionCookieInput = document.getElementById('session-cookie'); const filenameInput = document.getElementById('filename'); const clipFilenameInput = document.getElementById('clip-filename'); const currentUrlDisplay = document.getElementById('current-url'); const pageTitleDisplay = document.getElementById('page-title'); const saveConfigBtn = document.getElementById('save-config'); const sendFileBtn = document.getElementById('send-file'); const showConfigBtn = document.getElementById('show-config'); const showConfigFromClipBtn = document.getElementById('show-config-from-clip'); const modeUrlBtn = document.getElementById('mode-url'); const modeClipBtn = document.getElementById('mode-clip'); const clipFullPageBtn = document.getElementById('clip-full-page'); const clipSelectionBtn = document.getElementById('clip-selection'); let currentMode = 'url'; // 'url' or 'clip' // Load configuration and current tab URL on popup open document.addEventListener('DOMContentLoaded', async () => { // Load saved configuration const config = await loadConfig(); if (config.serverUrl) { serverUrlInput.value = config.serverUrl; } if (config.sessionCookie) { sessionCookieInput.value = config.sessionCookie; } // Get current tab info const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); const currentUrl = tabs[0]?.url || ''; const pageTitle = tabs[0]?.title || ''; currentUrlDisplay.textContent = currentUrl; pageTitleDisplay.textContent = pageTitle; // Show appropriate section if (config.serverUrl) { showModeSection(); showUrlMode(); } else { showConfigSection(); } }); // Save configuration saveConfigBtn.addEventListener('click', async () => { const serverUrl = serverUrlInput.value.trim(); if (!serverUrl) { showStatus('Please enter a server URL', 'error'); return; } // Validate URL format try { new URL(serverUrl); } catch (e) { showStatus('Invalid server URL format', 'error'); return; } const config = { serverUrl: serverUrl, sessionCookie: sessionCookieInput.value.trim() }; await saveConfig(config); showStatus('Configuration saved successfully!', 'success'); setTimeout(() => { showModeSection(); showUrlMode(); }, 1000); }); // Mode selection modeUrlBtn.addEventListener('click', () => { showUrlMode(); }); modeClipBtn.addEventListener('click', () => { showClipMode(); }); // Send file URL to DocuElevate sendFileBtn.addEventListener('click', async () => { const config = await loadConfig(); const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); const currentUrl = tabs[0]?.url || ''; if (!currentUrl) { showStatus('No URL found in current tab', 'error'); return; } // Disable button and show loading sendFileBtn.disabled = true; sendFileBtn.classList.add('loading'); showStatus('Sending URL to DocuElevate...', 'info'); try { const payload = { url: currentUrl, filename: filenameInput.value.trim() || null }; const headers = { 'Content-Type': 'application/json' }; // Add session cookie if provided if (config.sessionCookie) { headers['Cookie'] = config.sessionCookie; } const response = await fetch(`${config.serverUrl}/api/process-url`, { method: 'POST', headers: headers, body: JSON.stringify(payload), credentials: 'include' }); if (response.ok) { const result = await response.json(); showStatus( `✓ URL sent successfully! Task ID: ${result.task_id}\nFilename: ${result.filename}`, 'success' ); } else { // Try to parse JSON error, fall back to status text let errorMessage = 'Failed to send URL'; try { const result = await response.json(); errorMessage = result.detail || errorMessage; } catch (jsonError) { // Server returned non-JSON error response errorMessage = `HTTP ${response.status}: ${response.statusText}`; } showStatus(`Error: ${errorMessage}`, 'error'); } } catch (error) { showStatus( `Error: ${error.message || 'Failed to connect to DocuElevate server'}`, 'error' ); } finally { sendFileBtn.disabled = false; sendFileBtn.classList.remove('loading'); } }); // Clip full page clipFullPageBtn.addEventListener('click', async () => { await handleClipPage('full'); }); // Clip selection clipSelectionBtn.addEventListener('click', async () => { await handleClipPage('selection'); }); // Handle clipping page async function handleClipPage(mode) { const config = await loadConfig(); const tabs = await chrome.tabs.query({ active: true, currentWindow: true }); const tab = tabs[0]; if (!tab) { showStatus('No active tab found', 'error'); return; } // Disable buttons and show loading const button = mode === 'full' ? clipFullPageBtn : clipSelectionBtn; button.disabled = true; button.classList.add('loading'); showStatus(`Clipping ${mode === 'full' ? 'full page' : 'selection'}...`, 'info'); try { // Capture page content using content script let captureFunc; if (mode === 'full') { captureFunc = () => { const styles = Array.from(document.styleSheets) .map(sheet => { try { return Array.from(sheet.cssRules) .map(rule => rule.cssText) .join('\n'); } catch (e) { return ''; } }) .join('\n'); return { html: `
Source: ${window.location.href}