-
Notifications
You must be signed in to change notification settings - Fork 1
API Reference
Complete API reference for the Web Guide Chrome Extension.
- [Content Script API](#content-script-api)
- [Message Passing API](#message-passing-api)
- [External APIs](#external-apis)
- [Configuration](#configuration)
The content script exposes two main objects: PageExtractor and VisualGuide.
Handles all DOM reading and data extraction.
Extracts comprehensive page data for AI processing.
Returns: Object
{
url: String, // Current page URL
title: String, // Page title
text: String, // Visible text content (truncated)
elements: Array, // Interactive elements
headings: Array, // Page headings (h1-h6)
navigation: Array // Navigation links
}Example:
const pageData = PageExtractor.extractPageData();
console.log(pageData.elements.length); // Number of interactive elementsFinds all interactive elements on the page.
Returns: Array<Object>
[
{
tag: String, // Element tag name (lowercase)
text: String, // Visible text or placeholder
selector: String, // Generated CSS selector
visible: Boolean, // Whether element is visible
type: String // Input type (for inputs)
}
]Example:
const buttons = PageExtractor.getInteractiveElements()
.filter(el => el.tag === 'button');Extracts visible text content from the page.
Returns: String (max 5000 characters)
Example:
const text = PageExtractor.getPageText();Extracts all heading elements (h1-h6).
Returns: Array<Object>
[
{
level: Number, // 1-6
text: String, // Heading text
selector: String // CSS selector
}
]Generates a stable CSS selector for any DOM element.
Parameters:
-
element(HTMLElement) - The DOM element
Returns: String - CSS selector
Strategy:
- ID if available (
#id) - First class name if available (
.classname) - Tag name as fallback
Example:
const button = document.querySelector('button');
const selector = PageExtractor.generateSelector(button);
// Returns: "#submit-btn" or ".btn-primary" or "button"Checks if an element is visible in the viewport.
Parameters:
-
element(HTMLElement) - Element to check
Returns: Boolean
Checks:
- Display is not 'none'
- Visibility is not 'hidden'
- Opacity is not 0
- Has dimensions (width/height > 0)
Handles all visual feedback rendering.
Highlights an element with arrow, tooltip, and overlay.
Parameters:
-
selector(String) - CSS selector for target element -
description(String) - Human-readable description
Returns: void
Actions:
- Scrolls element into view (smooth)
- Creates animated arrow above element
- Shows tooltip with description
- Adds pulsing highlight overlay
- Auto-removes after 5 seconds or on click
Example:
VisualGuide.highlightElement(
'#search-input',
'This is the search input field'
);Creates an animated arrow pointing to an element.
Parameters:
-
element(HTMLElement) - Target element
Returns: HTMLElement - The arrow element
Styling:
- Position: Fixed, above element
- Animation: Bounce
- Color: Red (#ea4335)
- Z-index: 1000000
Creates a tooltip next to an element.
Parameters:
-
element(HTMLElement) - Target element -
text(String) - Tooltip content
Returns: HTMLElement - The tooltip element
Positioning:
- Attempts to position above element
- Falls back to below if insufficient space
- Adjusts horizontally to stay in viewport
Creates a pulsing highlight overlay on an element.
Parameters:
-
element(HTMLElement) - Target element
Returns: HTMLElement - The highlight element
Features:
- Pulsing animation
- Semi-transparent background
- Colored border
- Click-to-dismiss
Removes all visual guide elements from the page.
Returns: void
Removes:
- All arrows (
.webguide-arrow) - All tooltips (
.webguide-tooltip) - All highlights (
.webguide-highlight)
Future feature for multi-step guidance.
Parameters:
-
steps(Array) - Array of step objects
Planned Structure:
[
{
selector: String,
action: String,
description: String
}
]Communication between popup and content scripts using Chrome's message passing.
Message:
chrome.tabs.sendMessage(tabId,
{ action: 'getPageData' },
(response) => {
console.log(response.data);
}
);Response:
{
data: {
url: String,
title: String,
text: String,
elements: Array,
headings: Array
}
}Message:
chrome.tabs.sendMessage(tabId, {
action: 'highlightElement',
selector: '#submit-button',
description: 'This is the submit button'
});Response: None (fire-and-forget)
Message:
chrome.tabs.sendMessage(tabId, {
action: 'clearHighlights'
});In content.js:
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
if (request.action === 'getPageData') {
const data = PageExtractor.extractPageData();
sendResponse({ data });
return true; // Async response
}
if (request.action === 'highlightElement') {
VisualGuide.highlightElement(request.selector, request.description);
}
if (request.action === 'clearHighlights') {
VisualGuide.clearHighlights();
}
});POST https://api.groq.com/openai/v1/chat/completions
{
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
}{
"model": "llama-3.3-70b-versatile",
"messages": [
{
"role": "user",
"content": "Your prompt with page context"
}
],
"temperature": 0.7,
"max_tokens": 1024,
"top_p": 1,
"stream": false
}{
"id": "chatcmpl-...",
"object": "chat.completion",
"created": 1234567890,
"model": "llama-3.3-70b-versatile",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Response text with optional [HIGHLIGHT_ELEMENT]{...}[/HIGHLIGHT_ELEMENT]"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 123,
"completion_tokens": 456,
"total_tokens": 579
}
}For element highlighting, responses include:
Regular response text here.
[HIGHLIGHT_ELEMENT]
{
"selector": "#search-input",
"description": "This is the search box"
}
[/HIGHLIGHT_ELEMENT]
Parsing:
const match = response.match(/\[HIGHLIGHT_ELEMENT\](.*?)\[\/HIGHLIGHT_ELEMENT\]/s);
if (match) {
const elementData = JSON.parse(match[1]);
// Use elementData.selector and elementData.description
}Currently not actively used. The extension uses browser's native speechSynthesis.
POST https://api.elevenlabs.io/v1/text-to-speech/{voice_id}
{
'xi-api-key': 'YOUR_ELEVENLABS_API_KEY',
'Content-Type': 'application/json'
}const recognition = new webkitSpeechRecognition();
recognition.continuous = false;
recognition.interimResults = false;
recognition.lang = 'en-US';
recognition.onresult = (event) => {
const transcript = event.results[0][0].transcript;
console.log('User said:', transcript);
};
recognition.start();const utterance = new SpeechSynthesisUtterance('Hello, I am Web Guide');
utterance.lang = 'en-US';
utterance.rate = 1.0;
utterance.pitch = 1.0;
utterance.volume = 1.0;
window.speechSynthesis.speak(utterance);Central configuration file for API keys and settings.
// API Keys
const GROQ_API_KEY = 'gsk_...';
const ELEVENLABS_API_KEY = 'your_key_here'; // Optional
// Feature Flags
const VOICE_INPUT = true;
const VOICE_OUTPUT = true;
// API Configuration
const GROQ_API_URL = 'https://api.groq.com/openai/v1/chat/completions';
const GROQ_MODEL = 'llama-3.3-70b-versatile';
// UI Configuration
const HIGHLIGHT_COLOR = '#4285f4';
const ARROW_COLOR = '#ea4335';
const TOOLTIP_BG = 'rgba(0, 0, 0, 0.8)';
// Timing
const HIGHLIGHT_DURATION = 5000; // milliseconds
const SCROLL_DELAY = 300; // milliseconds
// Text Limits
const MAX_PAGE_TEXT = 5000; // characters
const MAX_ELEMENTS = 100; // interactive elements to analyzechrome.storage.sync.set({
voiceInput: true,
voiceOutput: true,
highlightColor: '#4285f4'
}, () => {
console.log('Settings saved');
});chrome.storage.sync.get(['voiceInput', 'voiceOutput'], (result) => {
console.log('Voice input:', result.voiceInput);
console.log('Voice output:', result.voiceOutput);
});- sync: 100KB total, 8KB per item
- local: 5MB total (use for larger data)
try {
const response = await callGroqAPI(prompt);
if (!response.choices || !response.choices[0]) {
throw new Error('Invalid API response');
}
} catch (error) {
console.error('API Error:', error);
displayError('Failed to get response from AI');
}const element = document.querySelector(selector);
if (!element) {
console.warn('Element not found:', selector);
return null;
}recognition.onerror = (event) => {
if (event.error === 'not-allowed') {
displayError('Microphone permission denied');
}
};// In popup.js
async function processVoiceCommand(command) {
try {
// 1. Get page data
const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
const pageData = await new Promise((resolve) => {
chrome.tabs.sendMessage(tab.id, { action: 'getPageData' }, resolve);
});
// 2. Build prompt
const prompt = buildPrompt(command, pageData.data);
// 3. Call API
const response = await fetch(GROQ_API_URL, {
method: 'POST',
headers: {
'Authorization': `Bearer ${GROQ_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
model: GROQ_MODEL,
messages: [{ role: 'user', content: prompt }]
})
});
const data = await response.json();
const responseText = data.choices[0].message.content;
// 4. Display response
displayResponse(responseText);
// 5. Check for element highlight
const match = responseText.match(/\[HIGHLIGHT_ELEMENT\](.*?)\[\/HIGHLIGHT_ELEMENT\]/s);
if (match) {
const elementData = JSON.parse(match[1]);
chrome.tabs.sendMessage(tab.id, {
action: 'highlightElement',
selector: elementData.selector,
description: elementData.description
});
}
} catch (error) {
console.error('Error:', error);
displayError('Failed to process command');
}
}