UNPKG

open-web-inspector

Version:

The open source web element inspector - AI-controllable DOM inspection with live CSS editing, hover highlighting, and developer tools integration

232 lines (198 loc) • 9.04 kB
// Open Web Inspector Auto-Injector Content Script // Automatically injects Open Web Inspector into every webpage (function() { 'use strict'; // Configuration const CONFIG = { cdnUrl: 'https://cdn.jsdelivr.net/npm/open-web-inspector@latest/dist/open-web-inspector.min.js', localUrl: chrome.runtime.getURL('open-web-inspector.min.js'), autoEnable: false, // Set to true to auto-enable inspector on every page debugMode: true, useLocal: true // Use bundled version to avoid CSP issues }; // Debug logging function log(message, ...args) { if (CONFIG.debugMode) { console.log(`[Open Web Inspector Extension] ${message}`, ...args); } } // Check if already injected to avoid duplicates if (window.openWebInspectorInjected) { log('Already injected, skipping...'); return; } // Mark as injected window.openWebInspectorInjected = true; /** * Inject Open Web Inspector into the page */ function injectOpenWebInspector() { return new Promise((resolve, reject) => { // Check if already loaded if (typeof window.OpenWebInspector !== 'undefined') { log('Open Web Inspector already available'); resolve(window.OpenWebInspector); return; } log('Injecting Open Web Inspector...'); // Create script element const script = document.createElement('script'); script.src = CONFIG.useLocal ? CONFIG.localUrl : CONFIG.cdnUrl; script.async = true; log(`Loading from: ${script.src}`); // Handle successful load script.onload = () => { log('āœ… Open Web Inspector loaded successfully!'); // Wait a bit for global API setup setTimeout(() => { if (typeof window.OpenWebInspector !== 'undefined') { log('šŸŽÆ Global API ready!'); resolve(window.OpenWebInspector); // Auto-enable if configured if (CONFIG.autoEnable) { window.OpenWebInspector.enable(); log('šŸš€ Auto-enabled inspector'); } // Dispatch custom event for other scripts document.dispatchEvent(new CustomEvent('openWebInspectorReady', { detail: { api: window.OpenWebInspector } })); } else { reject(new Error('Global API not available after load')); } }, 100); }; // Handle load error script.onerror = (error) => { log('āŒ Failed to load Open Web Inspector:', error); reject(error); }; // Inject into page (document.head || document.documentElement).appendChild(script); }); } /** * Setup extension message listener for popup communication */ function setupMessageListener() { // Listen for messages from popup chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { log('Received message:', request); if (request.action === 'enable') { if (typeof window.OpenWebInspector !== 'undefined') { window.OpenWebInspector.enable(); sendResponse({ success: true, message: 'Inspector enabled' }); } else { sendResponse({ success: false, message: 'Inspector not loaded' }); } } else if (request.action === 'disable') { if (typeof window.OpenWebInspector !== 'undefined') { window.OpenWebInspector.disable(); sendResponse({ success: true, message: 'Inspector disabled' }); } else { sendResponse({ success: false, message: 'Inspector not loaded' }); } } else if (request.action === 'toggle') { if (typeof window.OpenWebInspector !== 'undefined') { window.OpenWebInspector.toggle(); const isActive = window.OpenWebInspector.isActive(); sendResponse({ success: true, message: `Inspector ${isActive ? 'enabled' : 'disabled'}`, isActive: isActive }); } else { sendResponse({ success: false, message: 'Inspector not loaded' }); } } else if (request.action === 'status') { const loaded = typeof window.OpenWebInspector !== 'undefined'; const active = loaded ? window.OpenWebInspector.isActive() : false; sendResponse({ success: true, loaded: loaded, active: active, version: loaded ? window.OpenWebInspector.getVersion() : null }); } else if (request.action === 'selectElement') { if (typeof window.OpenWebInspector !== 'undefined' && request.selector) { window.OpenWebInspector.selectElement(request.selector); sendResponse({ success: true, message: `Selected: ${request.selector}` }); } else { sendResponse({ success: false, message: 'Inspector not loaded or no selector provided' }); } } return true; // Keep message channel open for async response }); } /** * Add keyboard shortcut enhancement */ function setupKeyboardShortcuts() { document.addEventListener('keydown', (e) => { // Ctrl+Shift+I = Force enable inspector (in addition to built-in shortcuts) if (e.ctrlKey && e.shiftKey && e.key === 'I') { e.preventDefault(); if (typeof window.OpenWebInspector !== 'undefined') { window.OpenWebInspector.enable(); log('šŸŽÆ Inspector enabled via Ctrl+Shift+I'); } else { log('āš ļø Inspector not loaded yet'); } } }); } /** * Initialize the extension */ async function initialize() { try { log('šŸš€ Initializing Open Web Inspector Extension...'); log('Current page URL:', window.location.href); log('Document ready state:', document.readyState); // Inject the inspector await injectOpenWebInspector(); // Setup communication with popup setupMessageListener(); // Setup additional keyboard shortcuts setupKeyboardShortcuts(); log('āœ… Extension initialized successfully!'); log('OpenWebInspector available:', typeof window.OpenWebInspector); // Show a subtle notification (can be disabled) if (CONFIG.debugMode) { console.log( '%cšŸŽÆ Open Web Inspector Ready!', 'color: #4CAF50; font-weight: bold; font-size: 14px;', '\n• Press Ctrl+Shift+E to toggle inspector', '\n• Click extension icon for controls', '\n• Right-click → Inspect with Open Web Inspector' ); } } catch (error) { log('āŒ Extension initialization failed:', error); console.error('[Open Web Inspector Extension] Detailed error:', error); } } // Wait for DOM to be ready if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', initialize); } else { // DOM already ready initialize(); } // Expose a global helper for console use window.openWebInspectorExtension = { enable: () => window.OpenWebInspector?.enable(), disable: () => window.OpenWebInspector?.disable(), toggle: () => window.OpenWebInspector?.toggle(), status: () => ({ loaded: typeof window.OpenWebInspector !== 'undefined', active: window.OpenWebInspector?.isActive() || false, version: window.OpenWebInspector?.getVersion() || null }), select: (selector) => window.OpenWebInspector?.selectElement(selector) }; })();