UNPKG

browser-plugin-creator

Version:

A modern scaffolding tool for creating browser extensions with ease

196 lines (166 loc) 5.38 kB
// 内容脚本 - 在页面上下文中运行 // 检查是否已经注入 if (!window.contentScriptInjected) { window.contentScriptInjected = true; console.log('{{name}} content script loaded'); // 初始化扩展 initContentScript(); } function initContentScript() { // 添加扩展标识 const extensionIndicator = createExtensionIndicator(); document.body.appendChild(extensionIndicator); // 监听来自popup的消息 chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { console.log('Content script received message:', request); switch (request.type) { case 'GET_PAGE_INFO': handleGetPageInfo(sendResponse); break; case 'HIGHLIGHT_TEXT': handleHighlightText(request.data); sendResponse({ success: true }); break; case 'EXTRACT_LINKS': handleExtractLinks(sendResponse); break; default: sendResponse({ error: 'Unknown message type' }); } return true; // 保持消息通道开放 }); // 监听键盘快捷键 document.addEventListener('keydown', handleKeyboardShortcut); // 页面变化监听 observePageChanges(); } function createExtensionIndicator() { const indicator = document.createElement('div'); indicator.id = '{{name}}-indicator'; indicator.innerHTML = '🚀 {{name}} 已激活'; indicator.style.cssText = ` position: fixed; top: 10px; right: 10px; background: #007bff; color: white; padding: 8px 12px; border-radius: 4px; font-size: 12px; z-index: 9999; box-shadow: 0 2px 8px rgba(0,0,0,0.1); font-family: -apple-system, BlinkMacSystemFont, sans-serif; `; // 3秒后淡出 setTimeout(() => { indicator.style.transition = 'opacity 0.5s'; indicator.style.opacity = '0'; setTimeout(() => indicator.remove(), 500); }, 3000); return indicator; } function handleGetPageInfo(sendResponse) { const pageInfo = { title: document.title, url: window.location.href, domain: window.location.hostname, description: getMetaContent('description'), keywords: getMetaContent('keywords'), links: document.links.length, images: document.images.length, textLength: document.body.innerText.length }; sendResponse(pageInfo); } function handleHighlightText(data) { const { text, color = '#ffff00' } = data; // 移除之前的高亮 removeHighlights(); if (!text) return; // 创建正则表达式 const regex = new RegExp(text, 'gi'); // 遍历文本节点 const walker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, { acceptNode: (node) => { // 跳过脚本和样式 if (node.parentNode.tagName === 'SCRIPT' || node.parentNode.tagName === 'STYLE' || node.parentNode.tagName === 'NOSCRIPT') { return NodeFilter.FILTER_REJECT; } return regex.test(node.textContent) ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP; } } ); const textNodes = []; let node; while (node = walker.nextNode()) { textNodes.push(node); } // 应用高亮 textNodes.forEach(textNode => { const span = document.createElement('span'); span.className = '{{name}}-highlight'; span.style.backgroundColor = color; span.style.padding = '2px 4px'; span.style.borderRadius = '3px'; const highlightedText = textNode.textContent.replace( regex, match => `<span class="{{name}}-highlight" style="background-color: ${color}; padding: 2px 4px; border-radius: 3px;">${match}</span>` ); const wrapper = document.createElement('div'); wrapper.innerHTML = highlightedText; const parent = textNode.parentNode; while (wrapper.firstChild) { parent.insertBefore(wrapper.firstChild, textNode); } parent.removeChild(textNode); }); } function handleExtractLinks(sendResponse) { const links = Array.from(document.links).map(link => ({ text: link.textContent.trim(), href: link.href, external: !link.href.includes(window.location.hostname) })); sendResponse({ links }); } function removeHighlights() { const highlights = document.querySelectorAll('.{{name}}-highlight'); highlights.forEach(highlight => { const parent = highlight.parentNode; parent.replaceChild(document.createTextNode(highlight.textContent), highlight); parent.normalize(); }); } function getMetaContent(name) { const meta = document.querySelector(`meta[name="${name}"], meta[property="og:${name}"]`); return meta ? meta.getAttribute('content') : ''; } function handleKeyboardShortcut(event) { // Ctrl+Shift+H 高亮选中文本 if (event.ctrlKey && event.shiftKey && event.key === 'H') { event.preventDefault(); const selection = window.getSelection().toString(); if (selection) { handleHighlightText({ text: selection }); } } } function observePageChanges() { // 监听URL变化(单页应用) let lastUrl = location.href; new MutationObserver(() => { const url = location.href; if (url !== lastUrl) { lastUrl = url; console.log('URL changed to:', url); // 重新初始化内容脚本功能 setTimeout(initContentScript, 1000); } }).observe(document, { subtree: true, childList: true }); }