diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..f1701de --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,72 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +这是一个Chrome浏览器扩展,为flomo笔记应用的Markdown代码块提供语法高亮功能。该插件基于Manifest V3规范,主要作用是解析和美化flomo中的代码内容,支持多种编程语言的语法高亮。 + +## Project Architecture + +### Core Components + +**Manifest V3 Extension Structure**: +- `manifest.json`: 扩展配置文件,定义权限和功能 +- `service-worker.js`: 后台脚本,处理主题切换和内容脚本注册 +- `scripts/content.js`: 内容脚本,在flomo页面中执行代码高亮逻辑 + +**Key Functionality**: +- **代码解析**: 识别```包围的代码块并提取语言类型 +- **语法高亮**: 使用highlight.js库对代码进行语法着色 +- **主题系统**: 支持明亮和暗黑两种代码高亮主题 +- **复制功能**: 为每个代码块添加复制按钮 + +### Target Websites +该扩展专门为以下网站设计: +- `https://v.flomoapp.com/*` +- `https://flomoapp.com/*` +- `https://h5.udrig.com/*` + +### Code Processing Logic + +**代码块识别流程**: +1. 扫描页面中的`.richText`元素 +2. 查找以```开头的段落作为代码块标记 +3. 提取语言类型(如`javascript`, `python`等) +4. 收集代码内容直到遇到结束的``` +5. 创建`
`元素并应用语法高亮
+
+**特殊处理**:
+- URL链接转换:代码块中的``标签会被转换为纯文本URL
+- HTML解码:确保代码内容正确显示
+
+## Development Commands
+
+### Loading Extension for Development
+1. 打开Chrome浏览器,访问`chrome://extensions/`
+2. 开启"开发者模式"
+3. 点击"加载已解压的扩展程序"
+4. 选择项目根目录
+
+### Testing
+- 访问flomo网站测试代码高亮功能
+- 使用开发者工具检查console日志输出
+- 测试主题切换功能是否正常工作
+
+## Key Files and Their Purposes
+
+- `include/highlight.min.js`: highlight.js库,负责语法高亮
+- `include/highlight.min.css`: 基础样式文件
+- `include/theme/`: 高亮主题CSS文件目录
+- `popup/`: 扩展弹窗界面,用于主题选择
+- `images/`: 图标资源文件
+
+## Architecture Notes
+
+**权限配置**: 扩展需要`storage`、`scripting`、`tabs`、`activeTab`、`webRequest`权限来实现完整功能。
+
+**动态CSS注入**: 主题切换通过动态注册和注销内容脚本实现,确保新样式能够立即生效。
+
+**消息传递**: 使用Chrome extension messaging API在service worker和content script之间通信,实现自动高亮功能。
+
+**代码清理**: 原始的```标记会被移除,替换为格式化的代码块元素。
\ No newline at end of file
diff --git a/README.md b/README.md
index cb101c6..147b565 100644
--- a/README.md
+++ b/README.md
@@ -5,3 +5,7 @@ feat: 仅新增复制按钮
 feat: 新增自动高亮
 
 fix: 网址形式的内容在高亮块显示不为 herf 问题
+
+feat: 新增两个新的代码块样式配色
+
+feat: 新增主区宽屏窄屏切换按钮
diff --git a/include/theme/modern-dark.css b/include/theme/modern-dark.css
new file mode 100644
index 0000000..7caa413
--- /dev/null
+++ b/include/theme/modern-dark.css
@@ -0,0 +1,187 @@
+/*!
+  Theme: Modern Dark Professional
+  Description: 现代专业暗色主题,适合代码展示
+  Author: Claude Code Enhancement
+  License: MIT
+  Updated: 2024
+*/
+
+/* 基础代码块样式 */
+pre code.hljs {
+  display: block;
+  overflow-x: auto;
+  padding: 1.25em 1.5em;
+  font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
+  font-size: 14px;
+  line-height: 1.5;
+  border-radius: 8px;
+  border: 1px solid #2d3748;
+  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+  background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%);
+  position: relative;
+}
+
+code.hljs {
+  padding: 0.25em 0.5em;
+  border-radius: 4px;
+  font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
+}
+
+/* 代码块容器增强 */
+pre {
+  margin: 1em 0;
+  position: relative;
+  background: transparent;
+}
+
+/* 主色彩方案 */
+.hljs {
+  color: #e2e8f0;
+  background: linear-gradient(135deg, #1a202c 0%, #2d3748 100%);
+}
+
+.hljs-subst {
+  color: #e2e8f0;
+}
+
+/* 注释 - 柔和灰色 */
+.hljs-comment {
+  color: #718096;
+  font-style: italic;
+}
+
+/* 关键字 - 蓝紫色系 */
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-meta .hljs-keyword,
+.hljs-doctag,
+.hljs-section {
+  color: #81c8ff;
+  font-weight: 600;
+}
+
+/* 属性 - 青色 */
+.hljs-attr {
+  color: #7dd3fc;
+}
+
+.hljs-attribute {
+  color: #c084fc;
+}
+
+/* 数字和命名空间 - 橙色 */
+.hljs-name,
+.hljs-type,
+.hljs-number,
+.hljs-selector-id,
+.hljs-quote,
+.hljs-template-tag {
+  color: #fbb865;
+}
+
+.hljs-selector-class {
+  color: #81c8ff;
+}
+
+/* 字符串和变量 - 绿色系 */
+.hljs-string,
+.hljs-regexp,
+.hljs-symbol,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-link,
+.hljs-selector-attr {
+  color: #7dd3fc;
+}
+
+/* 元数据 */
+.hljs-meta,
+.hljs-selector-pseudo {
+  color: #c084fc;
+}
+
+/* 内置函数 - 黄色 */
+.hljs-built_in,
+.hljs-title,
+.hljs-literal {
+  color: #fbb865;
+  font-weight: 500;
+}
+
+/* 标点符号 */
+.hljs-bullet,
+.hljs-code {
+  color: #94a3b8;
+}
+
+.hljs-meta .hljs-string {
+  color: #7dd3fc;
+}
+
+/* Git diff 样式 */
+.hljs-deletion {
+  color: #fca5a5;
+  background: rgba(252, 165, 165, 0.1);
+}
+
+.hljs-addition {
+  color: #86efac;
+  background: rgba(134, 239, 172, 0.1);
+}
+
+/* 强调样式 */
+.hljs-emphasis {
+  font-style: italic;
+}
+
+.hljs-strong {
+  font-weight: bold;
+  color: #f1f5f9;
+}
+
+/* 运算符和标签 */
+.hljs-formula,
+.hljs-operator,
+.hljs-params,
+.hljs-property,
+.hljs-punctuation,
+.hljs-tag {
+  color: #94a3b8;
+}
+
+/* 选择器增强 */
+.hljs-selector-class {
+  color: #fbbf24;
+}
+
+.hljs-selector-id {
+  color: #fb7185;
+}
+
+/* 语言特定增强 */
+.hljs-function {
+  color: #7dd3fc;
+}
+
+.hljs-class {
+  color: #fbbf24;
+}
+
+/* 滚动条美化 */
+pre code.hljs::-webkit-scrollbar {
+  height: 8px;
+}
+
+pre code.hljs::-webkit-scrollbar-track {
+  background: #2d3748;
+  border-radius: 4px;
+}
+
+pre code.hljs::-webkit-scrollbar-thumb {
+  background: #4a5568;
+  border-radius: 4px;
+}
+
+pre code.hljs::-webkit-scrollbar-thumb:hover {
+  background: #718096;
+}
\ No newline at end of file
diff --git a/include/theme/modern-light.css b/include/theme/modern-light.css
new file mode 100644
index 0000000..e47d954
--- /dev/null
+++ b/include/theme/modern-light.css
@@ -0,0 +1,188 @@
+/*!
+  Theme: Modern Light Professional
+  Description: 现代专业亮色主题,适合代码展示
+  Author: Claude Code Enhancement
+  License: MIT
+  Updated: 2024
+*/
+
+/* 基础代码块样式 */
+pre code.hljs {
+  display: block;
+  overflow-x: auto;
+  padding: 1.25em 1.5em;
+  font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
+  font-size: 14px;
+  line-height: 1.5;
+  border-radius: 8px;
+  border: 1px solid #e2e8f0;
+  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+  position: relative;
+}
+
+code.hljs {
+  padding: 0.25em 0.5em;
+  border-radius: 4px;
+  font-family: 'JetBrains Mono', 'Fira Code', 'SF Mono', Monaco, 'Cascadia Code', 'Roboto Mono', Consolas, 'Courier New', monospace;
+  background: #f1f5f9;
+}
+
+/* 代码块容器增强 */
+pre {
+  margin: 1em 0;
+  position: relative;
+  background: transparent;
+}
+
+/* 主色彩方案 */
+.hljs {
+  color: #334155;
+  background: linear-gradient(135deg, #ffffff 0%, #f8fafc 100%);
+}
+
+.hljs-subst {
+  color: #334155;
+}
+
+/* 注释 - 中性灰色 */
+.hljs-comment {
+  color: #64748b;
+  font-style: italic;
+}
+
+/* 关键字 - 蓝色系 */
+.hljs-keyword,
+.hljs-selector-tag,
+.hljs-meta .hljs-keyword,
+.hljs-doctag,
+.hljs-section {
+  color: #1e40af;
+  font-weight: 600;
+}
+
+/* 属性 - 青色 */
+.hljs-attr {
+  color: #0891b2;
+}
+
+.hljs-attribute {
+  color: #7c3aed;
+}
+
+/* 数字和命名空间 - 橙色 */
+.hljs-name,
+.hljs-type,
+.hljs-number,
+.hljs-selector-id,
+.hljs-quote,
+.hljs-template-tag {
+  color: #ea580c;
+}
+
+.hljs-selector-class {
+  color: #1e40af;
+}
+
+/* 字符串和变量 - 绿色系 */
+.hljs-string,
+.hljs-regexp,
+.hljs-symbol,
+.hljs-variable,
+.hljs-template-variable,
+.hljs-link,
+.hljs-selector-attr {
+  color: #059669;
+}
+
+/* 元数据 */
+.hljs-meta,
+.hljs-selector-pseudo {
+  color: #7c3aed;
+}
+
+/* 内置函数 - 深橙色 */
+.hljs-built_in,
+.hljs-title,
+.hljs-literal {
+  color: #dc2626;
+  font-weight: 500;
+}
+
+/* 标点符号 */
+.hljs-bullet,
+.hljs-code {
+  color: #64748b;
+}
+
+.hljs-meta .hljs-string {
+  color: #059669;
+}
+
+/* Git diff 样式 */
+.hljs-deletion {
+  color: #dc2626;
+  background: rgba(220, 38, 38, 0.1);
+}
+
+.hljs-addition {
+  color: #16a34a;
+  background: rgba(22, 163, 74, 0.1);
+}
+
+/* 强调样式 */
+.hljs-emphasis {
+  font-style: italic;
+}
+
+.hljs-strong {
+  font-weight: bold;
+  color: #1e293b;
+}
+
+/* 运算符和标签 */
+.hljs-formula,
+.hljs-operator,
+.hljs-params,
+.hljs-property,
+.hljs-punctuation,
+.hljs-tag {
+  color: #475569;
+}
+
+/* 选择器增强 */
+.hljs-selector-class {
+  color: #d97706;
+}
+
+.hljs-selector-id {
+  color: #e11d48;
+}
+
+/* 语言特定增强 */
+.hljs-function {
+  color: #0891b2;
+}
+
+.hljs-class {
+  color: #d97706;
+}
+
+/* 滚动条美化 */
+pre code.hljs::-webkit-scrollbar {
+  height: 8px;
+}
+
+pre code.hljs::-webkit-scrollbar-track {
+  background: #f1f5f9;
+  border-radius: 4px;
+}
+
+pre code.hljs::-webkit-scrollbar-thumb {
+  background: #cbd5e1;
+  border-radius: 4px;
+}
+
+pre code.hljs::-webkit-scrollbar-thumb:hover {
+  background: #94a3b8;
+}
\ No newline at end of file
diff --git a/popup/popup.html b/popup/popup.html
index 30f54a5..ae33b24 100644
--- a/popup/popup.html
+++ b/popup/popup.html
@@ -4,15 +4,75 @@
     
     
     Document
-    
+    
   
   
     

Choose Theme

- + diff --git a/scripts/content.js b/scripts/content.js index 749ffc5..ed5d3fa 100644 --- a/scripts/content.js +++ b/scripts/content.js @@ -1,32 +1,198 @@ +// 设置内容容器宽度的函数 +function setContentWidth(width = null) { + // 使用完整的XPath查找目标元素 + const xpath = "/html/body/div[1]/div[1]/section/div[1]/div[3]"; + const targetElement = document.evaluate( + xpath, + document, + null, + XPathResult.FIRST_ORDERED_NODE_TYPE, + null + ).singleNodeValue; + + if (targetElement) { + if (width) { + targetElement.style.width = width; + } else { + targetElement.style.width = ''; // 恢复原始宽度 + } + console.log(`已设置内容宽度为${width || '原始'}`); + } +} + +// 切换宽度模式 +function toggleWidth() { + chrome.storage.local.get(['isWideMode'], function(result) { + const newMode = !result.isWideMode; + chrome.storage.local.set({ isWideMode: newMode }); + + if (newMode) { + setContentWidth('900px'); + updateWidthButton(true); + } else { + setContentWidth(null); + updateWidthButton(false); + } + }); +} + +// 更新宽度切换按钮的样式 +function updateWidthButton(isWideMode) { + const widthBtn = document.getElementById('flomo-width-toggle'); + if (widthBtn) { + const icon = widthBtn.querySelector('svg'); + if (isWideMode) { + widthBtn.style.background = 'linear-gradient(135deg, #22c55e 0%, #16a34a 100%)'; + widthBtn.title = '切换到原始宽度'; + // 宽屏图标 + icon.innerHTML = ''; + } else { + widthBtn.style.background = 'linear-gradient(135deg, #6b7280 0%, #4b5563 100%)'; + widthBtn.title = '切换到宽屏模式'; + // 窄屏图标 + icon.innerHTML = ''; + } + } +} + +// 初始化宽度设置 +function initializeWidth() { + chrome.storage.local.get(['isWideMode'], function(result) { + if (result.isWideMode) { + setContentWidth('900px'); + updateWidthButton(true); + } else { + updateWidthButton(false); + } + }); +} + +// 使用MutationObserver监听DOM变化,确保在页面动态加载后也能应用样式 +function observeAndSetWidth() { + // 初始化设置 + setTimeout(initializeWidth, 100); + + const observer = new MutationObserver(function(mutations) { + let shouldCheck = false; + mutations.forEach(function(mutation) { + if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { + shouldCheck = true; + } + }); + + if (shouldCheck) { + setTimeout(initializeWidth, 100); // 延迟执行,确保DOM完全加载 + } + }); + + observer.observe(document.body, { + childList: true, + subtree: true + }); +} + window.onload = function () { + // 初始化宽度设置 + observeAndSetWidth(); + + // 创建代码高亮按钮 const hljsbtn = document.createElement('button'); const img = document.createElement('img'); img.src = chrome.runtime.getURL('images/code.svg'); - img.style.height = '20px'; - img.style.width = '20px'; + img.style.height = '22px'; + img.style.width = '22px'; + img.style.filter = 'brightness(0) invert(1)'; hljsbtn.appendChild(img); - // hljsbtn.innerHTML = "点击"; hljsbtn.type = 'button'; - hljsbtn.style.height = '36px'; - hljsbtn.style.width = '36px'; - hljsbtn.style.borderRadius = '36px'; + hljsbtn.style.height = '48px'; + hljsbtn.style.width = '48px'; + hljsbtn.style.borderRadius = '50%'; hljsbtn.style.border = 'none'; - hljsbtn.style.backgroundColor = '#397354'; + hljsbtn.style.background = 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)'; hljsbtn.style.color = '#fff'; hljsbtn.style.cursor = 'pointer'; hljsbtn.style.position = 'fixed'; hljsbtn.style.bottom = '80px'; - hljsbtn.style.right = '30px'; + hljsbtn.style.right = '24px'; hljsbtn.style.zIndex = '9999'; hljsbtn.style.display = 'flex'; hljsbtn.style.justifyContent = 'center'; hljsbtn.style.alignItems = 'center'; + hljsbtn.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1)'; + hljsbtn.style.transition = 'all 0.3s ease'; + hljsbtn.style.backdropFilter = 'blur(10px)'; + hljsbtn.title = '高亮代码块'; + + // 悬停效果 + hljsbtn.addEventListener('mouseenter', function() { + hljsbtn.style.transform = 'scale(1.1) translateY(-2px)'; + hljsbtn.style.boxShadow = '0 8px 24px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.15)'; + }); + + hljsbtn.addEventListener('mouseleave', function() { + hljsbtn.style.transform = 'scale(1) translateY(0)'; + hljsbtn.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1)'; + }); hljsbtn.addEventListener('click', highlightCodeBlocks); document.body.appendChild(hljsbtn); + + // 创建宽度切换按钮 + const widthBtn = document.createElement('button'); + widthBtn.id = 'flomo-width-toggle'; + + const widthIcon = document.createElementNS('http://www.w3.org/2000/svg', 'svg'); + widthIcon.setAttribute('width', '20'); + widthIcon.setAttribute('height', '20'); + widthIcon.setAttribute('viewBox', '0 0 24 24'); + widthIcon.setAttribute('fill', 'none'); + widthIcon.setAttribute('stroke', 'currentColor'); + widthIcon.setAttribute('stroke-width', '2'); + widthIcon.setAttribute('stroke-linecap', 'round'); + widthIcon.setAttribute('stroke-linejoin', 'round'); + + widthBtn.appendChild(widthIcon); + + widthBtn.type = 'button'; + widthBtn.style.height = '48px'; + widthBtn.style.width = '48px'; + widthBtn.style.borderRadius = '50%'; + widthBtn.style.border = 'none'; + widthBtn.style.background = 'linear-gradient(135deg, #6b7280 0%, #4b5563 100%)'; + widthBtn.style.color = '#fff'; + widthBtn.style.cursor = 'pointer'; + widthBtn.style.position = 'fixed'; + widthBtn.style.bottom = '140px'; // 在代码高亮按钮上方 + widthBtn.style.right = '24px'; + widthBtn.style.zIndex = '9999'; + widthBtn.style.display = 'flex'; + widthBtn.style.justifyContent = 'center'; + widthBtn.style.alignItems = 'center'; + widthBtn.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1)'; + widthBtn.style.transition = 'all 0.3s ease'; + widthBtn.style.backdropFilter = 'blur(10px)'; + widthBtn.title = '切换到宽屏模式'; + + // 悬停效果 + widthBtn.addEventListener('mouseenter', function() { + widthBtn.style.transform = 'scale(1.1) translateY(-2px)'; + widthBtn.style.boxShadow = '0 8px 24px rgba(0, 0, 0, 0.2), 0 4px 8px rgba(0, 0, 0, 0.15)'; + }); + + widthBtn.addEventListener('mouseleave', function() { + widthBtn.style.transform = 'scale(1) translateY(0)'; + widthBtn.style.boxShadow = '0 4px 12px rgba(0, 0, 0, 0.15), 0 2px 4px rgba(0, 0, 0, 0.1)'; + }); + + widthBtn.addEventListener('click', toggleWidth); + + document.body.appendChild(widthBtn); + + // 初始化按钮状态 + initializeWidth(); }; // 添加消息监听器 @@ -58,66 +224,134 @@ function highlightCodeBlocks() { // memo.removeChild(memo_p_array[i]); languageFlag = false; - // 保存代码内容的副本用于复制功能 - const codeForCopy = [...codeContentArr]; + // 保存原始代码内容用于复制(统一缩进为4空格) + const codeForCopy = codeContentArr.map(line => { + // 将制表符转换为4个空格 + return line.replace(/\t/g, ' '); + }); let pre = document.createElement('pre'); let code = document.createElement('code'); - code.innerHTML = codeContentArr.join('\n'); + + // 处理代码内容,统一缩进为4空格 + const processedContent = codeContentArr.map(line => { + return line.replace(/\t/g, ' '); + }).join('\n'); + + code.innerHTML = processedContent; code.className = languageType; let wrapper = document.createElement('div'); wrapper.style.position = 'relative'; + wrapper.style.marginBottom = '1em'; + wrapper.style.borderRadius = '8px'; + wrapper.style.overflow = 'hidden'; + + // 为代码块添加语言标签 + if (languageType && languageType !== 'language-') { + let langLabel = document.createElement('div'); + langLabel.textContent = languageType.replace('language-', '').toUpperCase(); + langLabel.style.position = 'absolute'; + langLabel.style.top = '6px'; + langLabel.style.left = '16px'; + langLabel.style.fontSize = '10px'; + langLabel.style.fontWeight = '600'; + langLabel.style.color = 'rgba(255, 255, 255, 0.6)'; + langLabel.style.backgroundColor = 'rgba(0, 0, 0, 0.2)'; + langLabel.style.padding = '2px 6px'; + langLabel.style.borderRadius = '3px'; + langLabel.style.fontFamily = 'monospace'; + langLabel.style.zIndex = '10'; + langLabel.style.backdropFilter = 'blur(4px)'; + langLabel.style.userSelect = 'none'; + langLabel.style.pointerEvents = 'none'; + wrapper.appendChild(langLabel); + } // 创建复制按钮 let copyBtn = document.createElement('button'); copyBtn.innerHTML = ''; copyBtn.style.position = 'absolute'; - copyBtn.style.top = '5px'; - copyBtn.style.right = '5px'; - copyBtn.style.zIndex = '100'; - copyBtn.style.fontSize = '12px'; - copyBtn.style.padding = '4px'; - copyBtn.style.background = 'rgba(240, 240, 240, 0.8)'; - copyBtn.style.border = '1px solid #ccc'; - copyBtn.style.borderRadius = '3px'; + copyBtn.style.top = '20px'; + copyBtn.style.right = '12px'; + copyBtn.style.zIndex = '20'; + copyBtn.style.width = '28px'; + copyBtn.style.height = '28px'; + copyBtn.style.padding = '0'; + copyBtn.style.background = 'rgba(255, 255, 255, 0.1)'; + copyBtn.style.border = '1px solid rgba(255, 255, 255, 0.2)'; + copyBtn.style.borderRadius = '6px'; copyBtn.style.cursor = 'pointer'; copyBtn.style.display = 'flex'; copyBtn.style.justifyContent = 'center'; copyBtn.style.alignItems = 'center'; + copyBtn.style.color = 'rgba(255, 255, 255, 0.7)'; + copyBtn.style.transition = 'all 0.2s ease'; + copyBtn.style.backdropFilter = 'blur(8px)'; copyBtn.title = '复制代码'; + // 悬停效果 + copyBtn.addEventListener('mouseenter', function() { + copyBtn.style.background = 'rgba(255, 255, 255, 0.2)'; + copyBtn.style.color = 'rgba(255, 255, 255, 0.9)'; + copyBtn.style.transform = 'scale(1.05)'; + }); + + copyBtn.addEventListener('mouseleave', function() { + copyBtn.style.background = 'rgba(255, 255, 255, 0.1)'; + copyBtn.style.color = 'rgba(255, 255, 255, 0.7)'; + copyBtn.style.transform = 'scale(1)'; + }); + copyBtn.addEventListener('click', function (e) { e.stopPropagation(); - // 创建临时元素解码HTML - const tempElement = document.createElement('div'); - - // 处理内容 + // 直接使用预处理的代码内容,已经转换为4空格缩进 let decodedContent = []; for (let i = 0; i < codeForCopy.length; i++) { + // 创建临时元素解码HTML + const tempElement = document.createElement('div'); tempElement.innerHTML = codeForCopy[i]; decodedContent.push(tempElement.textContent || tempElement.innerText); } - // 最终复制内容 + // 最终复制内容(4空格缩进) const codeText = decodedContent.join('\n'); // 复制到剪贴板 navigator.clipboard .writeText(codeText) .then(() => { - copyBtn.style.color = '#4CAF50'; + // 成功反馈 + copyBtn.innerHTML = ''; + copyBtn.style.background = 'rgba(34, 197, 94, 0.2)'; + copyBtn.style.color = '#22c55e'; + copyBtn.style.borderColor = 'rgba(34, 197, 94, 0.3)'; copyBtn.title = '已复制!'; setTimeout(() => { - copyBtn.style.color = ''; + copyBtn.innerHTML = ''; + copyBtn.style.background = 'rgba(255, 255, 255, 0.1)'; + copyBtn.style.color = 'rgba(255, 255, 255, 0.7)'; + copyBtn.style.borderColor = 'rgba(255, 255, 255, 0.2)'; copyBtn.title = '复制代码'; - }, 1500); + }, 2000); }) .catch((err) => { console.error('复制失败:', err); + // 错误反馈 + copyBtn.style.background = 'rgba(239, 68, 68, 0.2)'; + copyBtn.style.color = '#ef4444'; + copyBtn.style.borderColor = 'rgba(239, 68, 68, 0.3)'; + copyBtn.title = '复制失败'; + + setTimeout(() => { + copyBtn.style.background = 'rgba(255, 255, 255, 0.1)'; + copyBtn.style.color = 'rgba(255, 255, 255, 0.7)'; + copyBtn.style.borderColor = 'rgba(255, 255, 255, 0.2)'; + copyBtn.title = '复制代码'; + }, 2000); }); }); diff --git a/service-worker.js b/service-worker.js index 8bba919..987e761 100644 --- a/service-worker.js +++ b/service-worker.js @@ -31,7 +31,7 @@ chrome.storage.onChanged.addListener((changes, areaName) => { } }); -const DEFAULT_THEME = 'stackoverflow-dark.css'; +const DEFAULT_THEME = 'modern-dark.css'; chrome.runtime.onInstalled.addListener(() => { chrome.storage.sync.set({ chooseTheme: DEFAULT_THEME }, () => { console.log('保存成功');