// Enhanced Popup with Testing Interface
let logContainer = document.getElementById("log");
let statusIndicator = document.getElementById("statusIndicator");
let statusText = document.getElementById("statusText");
let toolCount = document.getElementById("toolCount");
let currentPage = document.getElementById("currentPage");
let resultArea = document.getElementById("results");
let resultMeta = document.getElementById("result-meta");
let resultContent = document.getElementById("result-content");
let dataSizeInfo = document.getElementById("data-size");
let expandButton = document.getElementById("expand-results");
let jsonViewer = document.getElementById("json-viewer");
// Get initial tool count and page info
const tools = 8; // 6 core automation + 2 essential legacy tools
toolCount.textContent = tools;
// Check connection status and get page info
function checkStatus() {
if (chrome.runtime?.id) {
chrome.runtime.sendMessage({ action: "getStatus" }, (response) => {
if (chrome.runtime.lastError) {
updateStatus(false);
addLog("Extension background script not responding", "error");
} else {
updateStatus(response?.connected || false);
}
});
// Get current page info
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
if (tabs[0]) {
const url = new URL(tabs[0].url);
currentPage.textContent = url.hostname;
}
});
} else {
updateStatus(false);
addLog("Extension context invalid", "error");
}
}
// Check status on load and periodically
checkStatus();
setInterval(checkStatus, 2000);
// Update UI based on connection status
function updateStatus(connected) {
if (connected) {
statusIndicator.className = "status-indicator connected";
statusText.textContent = "Connected to MCP server";
} else {
statusIndicator.className = "status-indicator disconnected";
statusText.textContent = "Disconnected from MCP server";
}
}
// Reconnect button
document.getElementById("reconnectBtn").addEventListener("click", () => {
if (chrome.runtime?.id) {
chrome.runtime.sendMessage({ action: "reconnect" }, (response) => {
if (chrome.runtime.lastError) {
addLog(chrome.runtime.lastError.message, "error");
} else {
addLog("Attempting to reconnect...", "info");
setTimeout(checkStatus, 1000);
}
});
}
});
// Test button
document.getElementById("testBtn").addEventListener("click", () => {
if (chrome.runtime?.id) {
chrome.runtime.sendMessage({ action: "test" }, (response) => {
if (chrome.runtime.lastError) {
addLog(chrome.runtime.lastError.message, "error");
} else {
addLog("Sending test message...", "info");
}
});
}
});
// Testing Interface Functions
class TestingInterface {
constructor() {
this.setupEventListeners();
}
setupEventListeners() {
document.getElementById('test-extract').addEventListener('click', () => this.testExtraction());
document.getElementById('test-analyze').addEventListener('click', () => this.testAnalysis());
document.getElementById('highlight-elements').addEventListener('click', () => this.highlightElements());
expandButton.addEventListener('click', () => this.toggleJsonViewer());
}
async testExtraction() {
const contentType = document.getElementById('content-type').value;
addLog(`🔍 Testing content extraction: ${contentType}`, "info");
try {
const result = await this.sendToContentScript({
action: 'extract_content',
data: { content_type: contentType }
});
this.displayResults(result, 'Content Extraction');
addLog(`Extraction completed in ${result.execution_time}ms`, "success");
} catch (error) {
addLog(`Extraction failed: ${error.message}`, "error");
}
}
async testAnalysis() {
const intentHint = document.getElementById('intent-hint').value;
if (!intentHint.trim()) {
addLog('Please enter an intent hint', "error");
return;
}
addLog(`🎯 Testing page analysis: ${intentHint}`, "info");
try {
const result = await this.sendToContentScript({
action: 'analyze',
data: { intent_hint: intentHint }
});
this.displayResults(result, 'Page Analysis');
addLog(`Analysis completed in ${result.execution_time}ms`, "success");
} catch (error) {
addLog(`Analysis failed: ${error.message}`, "error");
}
}
async highlightElements() {
const intentHint = document.getElementById('intent-hint').value;
if (!intentHint.trim()) {
addLog('Please enter an intent hint to highlight elements', "error");
return;
}
try {
const result = await this.sendToContentScript({
action: 'analyze',
data: { intent_hint: intentHint }
});
if (result.success && result.data.elements?.length > 0) {
// Inject highlighting script
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
chrome.scripting.executeScript({
target: { tabId: tabs[0].id },
func: this.highlightElementsOnPage,
args: [result.data.elements]
});
});
addLog(`🎯 Highlighted ${result.data.elements.length} elements`, "success");
} else {
addLog('No elements found to highlight', "error");
}
} catch (error) {
addLog(`Highlighting failed: ${error.message}`, "error");
}
}
highlightElementsOnPage(elements) {
// Remove existing highlights
document.querySelectorAll('.opendia-highlight').forEach(el => {
el.classList.remove('opendia-highlight');
el.style.removeProperty('outline');
});
// Add new highlights
elements.forEach((elementData, index) => {
try {
const element = document.querySelector(elementData.selector);
if (element) {
element.classList.add('opendia-highlight');
element.style.outline = `3px solid ${this.getHighlightColor(elementData.confidence)}`;
element.style.outlineOffset = '2px';
// Add tooltip
element.title = `OpenDia: ${elementData.name} (${Math.round(elementData.confidence * 100)}%)`;
}
} catch (error) {
console.warn('Failed to highlight element:', elementData.selector, error);
}
});
// Auto-remove highlights after 10 seconds
setTimeout(() => {
document.querySelectorAll('.opendia-highlight').forEach(el => {
el.classList.remove('opendia-highlight');
el.style.removeProperty('outline');
el.style.removeProperty('outline-offset');
el.removeAttribute('title');
});
}, 10000);
}
getHighlightColor(confidence) {
if (confidence > 0.8) return '#22c55e'; // Green for high confidence
if (confidence > 0.6) return '#f59e0b'; // Orange for medium confidence
return '#ef4444'; // Red for low confidence
}
async sendToContentScript(message) {
return new Promise((resolve, reject) => {
chrome.tabs.query({active: true, currentWindow: true}, (tabs) => {
if (tabs[0]) {
chrome.tabs.sendMessage(tabs[0].id, message, (response) => {
if (chrome.runtime.lastError) {
reject(new Error(chrome.runtime.lastError.message));
} else if (response.success) {
resolve(response);
} else {
reject(new Error(response.error || 'Unknown error'));
}
});
} else {
reject(new Error('No active tab found'));
}
});
});
}
displayResults(result, testType) {
resultArea.classList.add('show');
this.lastResult = result; // Store for JSON viewer
// Display metadata with better formatting
const method = result.data.method || 'N/A';
const confidence = result.data.confidence ? Math.round(result.data.confidence * 100) + '%' : 'N/A';
const elementsCount = result.data.elements ? result.data.elements.length : 0;
resultMeta.innerHTML = `
✅ ${testType}
📊 Method: ${method} |
⏱️ Time: ${result.execution_time}ms |
🎯 Confidence: ${confidence}
${elementsCount > 0 ? ` | 🔍 Elements: ${elementsCount}` : ''}
`;
// Display enhanced content preview
const preview = this.createEnhancedPreview(result.data, testType);
resultContent.innerHTML = preview;
// Display size info
this.displayDataSize(result);
// Store full JSON for viewer
this.updateJsonViewer(result);
}
createEnhancedPreview(data, testType) {
if (testType === 'Page Analysis' && data.elements?.length > 0) {
return this.createElementsPreview(data.elements);
} else if (testType === 'Content Extraction' && data.content) {
return this.createContentPreview(data.content, data.content_type);
} else {
return `