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('保存成功');