// DIDI Analysis Tool - Popup Script (OIDC auth + URL/text analysis) console.log('[POPUP] Script loaded'); document.addEventListener('DOMContentLoaded', async () => { console.log('[POPUP] DOM loaded'); const loginSection = document.getElementById('loginSection'); const mainSection = document.getElementById('mainSection'); const authStatusEl = document.getElementById('authStatus'); const loginBtn = document.getElementById('loginBtn'); const loginStatus = document.getElementById('loginStatus'); const activateSnippingBtn = document.getElementById('activateSnipping'); const activateVideoSnippingBtn = document.getElementById('activateVideoSnipping'); const urlInput = document.getElementById('urlInput'); const analyzeUrlBtn = document.getElementById('analyzeUrlBtn'); const analyzeCurrentTabBtn = document.getElementById('analyzeCurrentTab'); const textInput = document.getElementById('textInput'); const analyzeTextBtn = document.getElementById('analyzeText'); const charCount = document.getElementById('charCount'); const statusDiv = document.getElementById('status'); const viewHistoryBtn = document.getElementById('viewHistory'); const disconnectBtn = document.getElementById('disconnectBtn'); // === AUTH UI === function showLogin() { loginSection.style.display = 'block'; mainSection.style.display = 'none'; const dot = authStatusEl.querySelector('.auth-dot'); const text = authStatusEl.querySelector('.auth-text'); dot.className = 'auth-dot disconnected'; text.textContent = 'Neconectat'; } function showMain(email) { loginSection.style.display = 'none'; mainSection.style.display = 'block'; const dot = authStatusEl.querySelector('.auth-dot'); const text = authStatusEl.querySelector('.auth-text'); dot.className = 'auth-dot connected'; text.textContent = email || 'Conectat'; } // Check auth on load chrome.runtime.sendMessage({ action: 'getAuthStatus' }, (response) => { if (response?.authenticated) { showMain(response.email); prefillFromActiveTab(); } else { showLogin(); } }); // === LOGIN (OIDC/PKCE prin Keycloak) === loginBtn.addEventListener('click', () => { loginBtn.disabled = true; loginBtn.textContent = 'Se deschide autentificarea…'; loginStatus.textContent = ''; chrome.runtime.sendMessage({ action: 'login' }, (response) => { if (response?.success) { loginStatus.className = 'login-status success'; loginStatus.textContent = 'Autentificat!'; setTimeout(() => { showMain(response.email); prefillFromActiveTab(); }, 400); } else { loginStatus.className = 'login-status error'; loginStatus.textContent = 'Autentificare eșuată: ' + (response?.error || 'eroare necunoscută'); } loginBtn.disabled = false; loginBtn.innerHTML = ` Autentificare`; }); }); // === DISCONNECT === disconnectBtn.addEventListener('click', () => { chrome.runtime.sendMessage({ action: 'logout' }, () => { showLogin(); }); }); // === PREFILL: URL-ul tabului activ + textul selectat în pagină === async function prefillFromActiveTab() { try { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab) return; if (tab.url && /^https?:/i.test(tab.url)) { urlInput.value = tab.url; analyzeUrlBtn.disabled = false; } // Selected text from the page → prefill the textarea (cerință caiet 2a) try { const results = await chrome.scripting.executeScript({ target: { tabId: tab.id }, func: () => window.getSelection().toString(), }); const selected = (results?.[0]?.result || '').trim(); if (selected && !textInput.value) { textInput.value = selected.substring(0, 5000); textInput.dispatchEvent(new Event('input')); showStatus('Textul selectat în pagină a fost preluat.', 'info'); } } catch { /* restricted page (chrome://, PDF) — nothing to prefill */ } } catch (e) { console.warn('[POPUP] prefill failed:', e.message); } } // === SCREENSHOT === activateSnippingBtn.addEventListener('click', async () => { try { showStatus('Se activează modul captură…', 'info'); const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab) { showStatus('Nu există tab activ', 'error'); return; } try { // Inject render.js BEFORE content.js so window.DidiRender exists when // content.js's 'showAnalysis' handler tries to render the modal. Required // for tabs opened before the extension was last reloaded — manifest's // content_scripts only inject on fresh page loads. await chrome.scripting.executeScript({ target: { tabId: tab.id }, files: ['render.js', 'content.js'] }); } catch (e) { /* already injected */ } await new Promise(r => setTimeout(r, 100)); chrome.tabs.sendMessage(tab.id, { action: 'activateSnipping' }, (response) => { if (chrome.runtime.lastError) { showStatus('Activare eșuată. Reîncarcă pagina.', 'error'); return; } if (response?.success) { showStatus('Mod captură activ!', 'success'); setTimeout(() => window.close(), 800); } else { showStatus('Captura necesită consimțământul pentru trimiterea imaginii.', 'error'); } }); } catch (error) { showStatus('Eroare: ' + error.message, 'error'); } }); // === VIDEO REGION RECORDING === activateVideoSnippingBtn.addEventListener('click', async () => { try { showStatus('Se activează modul video…', 'info'); const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab) { showStatus('Nu există tab activ', 'error'); return; } try { // Same injection ordering rationale as the screenshot flow above. await chrome.scripting.executeScript({ target: { tabId: tab.id }, files: ['render.js', 'content.js'] }); } catch (e) { /* already injected */ } await new Promise(r => setTimeout(r, 100)); chrome.tabs.sendMessage(tab.id, { action: 'activateVideoSnipping' }, (response) => { if (chrome.runtime.lastError) { showStatus('Activare eșuată. Reîncarcă pagina.', 'error'); return; } if (response?.success) { showStatus('Mod video activ!', 'success'); setTimeout(() => window.close(), 800); } else { showStatus('Înregistrarea necesită consimțământul pentru trimiterea capturii.', 'error'); } }); } catch (error) { showStatus('Eroare: ' + error.message, 'error'); } }); // === SOCIAL POST SELECTION (extractoare Facebook / Twitter-X) === const selectSocialPostBtn = document.getElementById('selectSocialPost'); function socialPlatformFor(url) { if (/https?:\/\/([a-z0-9-]+\.)?facebook\.com\//i.test(url)) return 'facebook'; if (/https?:\/\/([a-z0-9-]+\.)?(twitter|x)\.com\//i.test(url)) return 'twitter'; return null; } (async () => { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (tab?.url && socialPlatformFor(tab.url)) { selectSocialPostBtn.style.display = ''; } })(); selectSocialPostBtn.addEventListener('click', async () => { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); const platform = tab?.url ? socialPlatformFor(tab.url) : null; if (!platform) { showStatus('Deschide o pagină Facebook sau X/Twitter.', 'error'); return; } try { await chrome.scripting.executeScript({ target: { tabId: tab.id }, files: ['render.js', 'content.js'] }); } catch (e) { /* already injected */ } await new Promise(r => setTimeout(r, 100)); chrome.tabs.sendMessage(tab.id, { action: 'activateSelection', platform }, (response) => { if (chrome.runtime.lastError) { showStatus('Activare eșuată. Reîncarcă pagina.', 'error'); return; } if (response?.success) { showStatus('Mod selecție activ — dă click pe o postare.', 'success'); setTimeout(() => window.close(), 800); } }); }); // === URL ANALYSIS (cerință caiet 1a/1b) === function isValidHttpUrl(value) { try { const u = new URL(/^www\./i.test(value) ? `https://${value}` : value); return u.protocol === 'http:' || u.protocol === 'https:'; } catch { return false; } } urlInput.addEventListener('input', () => { analyzeUrlBtn.disabled = !isValidHttpUrl(urlInput.value.trim()); }); analyzeCurrentTabBtn.addEventListener('click', async () => { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab?.url || !/^https?:/i.test(tab.url)) { showStatus('Pagina curentă nu are un URL analizabil.', 'error'); return; } urlInput.value = tab.url; analyzeUrlBtn.disabled = false; submitUrl(tab.url); }); analyzeUrlBtn.addEventListener('click', () => { const url = urlInput.value.trim(); if (!isValidHttpUrl(url)) { showStatus('Introdu un URL valid (http/https).', 'error'); return; } submitUrl(url); }); function submitUrl(url) { analyzeUrlBtn.disabled = true; showStatus('Trimis către DiDi… rezultatul se deschide într-un tab nou în 30–90s.', 'info'); chrome.runtime.sendMessage({ action: 'analyzeUrl', url }, (response) => { analyzeUrlBtn.disabled = false; if (response?.success) { showStatus('Trimis! Rezultatul se va deschide când e gata.', 'success'); setTimeout(() => window.close(), 1500); } else { showStatus('Eroare: ' + (response?.error || 'necunoscută'), 'error'); } }); } // === TEXT ANALYSIS === textInput.addEventListener('input', () => { const len = textInput.value.trim().length; charCount.textContent = len; analyzeTextBtn.disabled = len === 0 || len > 5000; }); analyzeTextBtn.addEventListener('click', () => { const text = textInput.value.trim(); if (!text) return; analyzeTextBtn.disabled = true; analyzeTextBtn.textContent = 'Se trimite…'; showStatus('Trimis către DiDi… rezultatul se deschide într-un tab nou în 30–90s.', 'info'); // Background acks immediately, then runs the polling in the service worker // and opens a new tab with the rendered standalone result page when done. chrome.runtime.sendMessage({ action: 'analyzeText', text }, (response) => { analyzeTextBtn.innerHTML = ` Analizează text`; analyzeTextBtn.disabled = false; if (response?.success) { showStatus('Trimis! Rezultatul se va deschide când e gata.', 'success'); textInput.value = ''; charCount.textContent = '0'; setTimeout(() => window.close(), 1500); } else { showStatus('Eroare: ' + (response?.error || 'necunoscută'), 'error'); } }); }); // === HISTORY === viewHistoryBtn.addEventListener('click', () => { chrome.tabs.create({ url: chrome.runtime.getURL('history.html') }); }); // === STATUS === function showStatus(message, type) { statusDiv.textContent = message; statusDiv.className = `status ${type}`; statusDiv.style.display = 'block'; setTimeout(() => { statusDiv.style.display = 'none'; }, 3000); } });