Files
OpenQode/qwen-automation-extension/content.js

201 lines
5.9 KiB
JavaScript

// Content script for Qwen AI Automation Extension
console.log('Qwen AI Automation content script loaded');
// Store extension state
let extensionState = {
isActive: false,
currentTask: null,
qwenToken: null
};
// Listen for messages from background script
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
switch (message.action) {
case 'getPageContent':
sendResponse(getPageContent());
break;
case 'getElementInfo':
sendResponse(getElementInfo(message.selector));
break;
case 'executeAction':
sendResponse(executeAction(message.action, message.params));
break;
default:
console.log('Unknown message action:', message.action);
}
return true; // Keep message channel open for async response
});
// Get page content for AI analysis
function getPageContent() {
return {
url: window.location.href,
title: document.title,
content: document.body.innerText.substring(0, 2000), // First 2000 chars
elements: Array.from(document.querySelectorAll('input, button, a, textarea, select'))
.map(el => ({
tag: el.tagName.toLowerCase(),
id: el.id || null,
className: el.className || null,
text: el.textContent?.substring(0, 100) || el.value || null,
name: el.name || null,
placeholder: el.placeholder || null,
role: el.getAttribute('role') || null
}))
};
}
// Get specific element information
function getElementInfo(selector) {
const element = document.querySelector(selector);
if (element) {
return {
exists: true,
tag: element.tagName.toLowerCase(),
id: element.id || null,
className: element.className || null,
text: element.textContent?.substring(0, 100) || element.value || null,
name: element.name || null,
placeholder: element.placeholder || null,
role: element.getAttribute('role') || null,
rect: element.getBoundingClientRect(),
isVisible: !!(element.offsetWidth || element.offsetHeight || element.getClientRects().length)
};
} else {
return { exists: false };
}
}
// Execute an action on the page
function executeAction(action, params) {
try {
switch (action) {
case 'click':
return clickElement(params.selector);
case 'fill':
return fillElement(params.selector, params.value);
case 'clickText':
return clickElementByText(params.text);
case 'waitForElement':
return waitForElement(params.selector, params.timeout || 5000);
case 'scrollToElement':
return scrollToElement(params.selector);
case 'extractText':
return extractTextFromElement(params.selector);
default:
return { success: false, error: `Unknown action: ${action}` };
}
} catch (error) {
return { success: false, error: error.message };
}
}
// Helper functions
function clickElement(selector) {
const element = document.querySelector(selector);
if (element) {
element.click();
return { success: true, message: `Clicked element: ${selector}` };
} else {
return { success: false, error: `Element not found: ${selector}` };
}
}
function fillElement(selector, value) {
const element = document.querySelector(selector);
if (element) {
element.value = value;
element.dispatchEvent(new Event('input', { bubbles: true }));
element.dispatchEvent(new Event('change', { bubbles: true }));
element.dispatchEvent(new Event('blur', { bubbles: true })); // Trigger any blur events
return { success: true, message: `Filled element: ${selector} with value: ${value}` };
} else {
return { success: false, error: `Element not found: ${selector}` };
}
}
function clickElementByText(text) {
const elements = Array.from(document.querySelectorAll('button, a, input, textarea, span, div'));
const element = elements.find(el =>
el.textContent?.trim().toLowerCase().includes(text.toLowerCase()) ||
el.value?.toLowerCase().includes(text.toLowerCase()) ||
el.placeholder?.toLowerCase().includes(text.toLowerCase())
);
if (element) {
element.click();
return { success: true, message: `Clicked element with text: ${text}` };
} else {
return { success: false, error: `Element with text not found: ${text}` };
}
}
function waitForElement(selector, timeout) {
return new Promise((resolve) => {
const element = document.querySelector(selector);
if (element) {
resolve({ success: true, message: `Element found immediately: ${selector}` });
return;
}
const observer = new MutationObserver(() => {
const element = document.querySelector(selector);
if (element) {
observer.disconnect();
resolve({ success: true, message: `Element found after waiting: ${selector}` });
}
});
observer.observe(document.body, {
childList: true,
subtree: true
});
setTimeout(() => {
observer.disconnect();
resolve({ success: false, error: `Element not found within timeout: ${selector}` });
}, timeout);
});
}
function scrollToElement(selector) {
const element = document.querySelector(selector);
if (element) {
element.scrollIntoView({ behavior: 'smooth', block: 'center' });
return { success: true, message: `Scrolled to element: ${selector}` };
} else {
return { success: false, error: `Element not found: ${selector}` };
}
}
function extractTextFromElement(selector) {
const element = document.querySelector(selector);
if (element) {
return {
success: true,
text: element.textContent || element.value || '',
message: `Extracted text from element: ${selector}`
};
} else {
return { success: false, error: `Element not found: ${selector}` };
}
}
// Expose functions to window for advanced usage if needed
window.qwenAutomation = {
getPageContent,
getElementInfo,
executeAction,
clickElement,
fillElement
};