feat: 优化提取功能和用户体验
- 复制/下载后自动关闭弹窗并显示提示 - 修复CSS隔离问题,避免影响页面样式 - 使用DOM克隆替代直接操作,避免修改原始页面HTML - 删除未使用的styles.css文件 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
c158ff28bd
commit
c8fad8c4b8
@ -6,26 +6,41 @@ import type { ChromeMessage, ContentScriptResponse, ExtractedContent } from '../
|
|||||||
// 调试:记录content script已加载
|
// 调试:记录content script已加载
|
||||||
console.log('ReadMD: Content script loaded on', window.location.href);
|
console.log('ReadMD: Content script loaded on', window.location.href);
|
||||||
|
|
||||||
// 注入高亮样式
|
// 注入高亮样式(使用shadow DOM隔离)
|
||||||
|
let highlightStyleElement: HTMLStyleElement | null = null;
|
||||||
|
|
||||||
function injectHighlightStyles(): void {
|
function injectHighlightStyles(): void {
|
||||||
const style = document.createElement('style');
|
if (highlightStyleElement) return; // 防止重复注入
|
||||||
style.id = 'readmd-highlight-styles';
|
|
||||||
style.textContent = `
|
highlightStyleElement = document.createElement('style');
|
||||||
|
highlightStyleElement.id = 'readmd-highlight-styles';
|
||||||
|
highlightStyleElement.textContent = `
|
||||||
.readmd-highlight {
|
.readmd-highlight {
|
||||||
outline: 2px solid #4CAF50 !important;
|
outline: 2px solid #4CAF50 !important;
|
||||||
background-color: rgba(76, 175, 80, 0.1) !important;
|
background-color: rgba(76, 175, 80, 0.1) !important;
|
||||||
}
|
}
|
||||||
.readmd-selection-mode {
|
|
||||||
cursor: crosshair !important;
|
|
||||||
}
|
|
||||||
`;
|
`;
|
||||||
document.head.appendChild(style);
|
document.head.appendChild(highlightStyleElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 使用Readability提取主要内容
|
// 清理高亮样式
|
||||||
|
function cleanupHighlightStyles(): void {
|
||||||
|
if (highlightStyleElement) {
|
||||||
|
highlightStyleElement.remove();
|
||||||
|
highlightStyleElement = null;
|
||||||
|
}
|
||||||
|
// 清除页面上的高亮元素
|
||||||
|
document.querySelectorAll('.readmd-highlight').forEach(el => {
|
||||||
|
el.classList.remove('readmd-highlight');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 使用Readability提取主要内容(不修改原始DOM)
|
||||||
function extractWithReadability(): ExtractedContent | null {
|
function extractWithReadability(): ExtractedContent | null {
|
||||||
try {
|
try {
|
||||||
const reader = new Readability(document);
|
// 创建文档的克隆副本,避免修改原始页面
|
||||||
|
const docClone = document.cloneNode(true);
|
||||||
|
const reader = new Readability(docClone as Document);
|
||||||
const article = reader.parse();
|
const article = reader.parse();
|
||||||
|
|
||||||
if (!article) {
|
if (!article) {
|
||||||
@ -114,6 +129,7 @@ function handleMessage(message: ChromeMessage, _sender: any, sendResponse: (resp
|
|||||||
// 自动提取页面主要内容
|
// 自动提取页面主要内容
|
||||||
const content = extractWithReadability();
|
const content = extractWithReadability();
|
||||||
if (content) {
|
if (content) {
|
||||||
|
cleanupHighlightStyles(); // 提取完成后清理样式
|
||||||
sendResponse({ success: true, data: content });
|
sendResponse({ success: true, data: content });
|
||||||
} else {
|
} else {
|
||||||
sendResponse({ success: false, error: '无法提取页面内容' });
|
sendResponse({ success: false, error: '无法提取页面内容' });
|
||||||
@ -124,6 +140,7 @@ function handleMessage(message: ChromeMessage, _sender: any, sendResponse: (resp
|
|||||||
// 提取用户选择的区域
|
// 提取用户选择的区域
|
||||||
const selectionContent = extractSelection();
|
const selectionContent = extractSelection();
|
||||||
if (selectionContent) {
|
if (selectionContent) {
|
||||||
|
cleanupHighlightStyles(); // 提取完成后清理样式
|
||||||
sendResponse({ success: true, data: selectionContent });
|
sendResponse({ success: true, data: selectionContent });
|
||||||
} else {
|
} else {
|
||||||
sendResponse({ success: false, error: '请先选择要提取的内容' });
|
sendResponse({ success: false, error: '请先选择要提取的内容' });
|
||||||
@ -134,6 +151,8 @@ function handleMessage(message: ChromeMessage, _sender: any, sendResponse: (resp
|
|||||||
// 高亮选中的区域
|
// 高亮选中的区域
|
||||||
highlightSelection();
|
highlightSelection();
|
||||||
const previewContent = extractSelection();
|
const previewContent = extractSelection();
|
||||||
|
// 预览完成后清理样式
|
||||||
|
cleanupHighlightStyles();
|
||||||
sendResponse({
|
sendResponse({
|
||||||
success: !!previewContent,
|
success: !!previewContent,
|
||||||
data: previewContent || undefined,
|
data: previewContent || undefined,
|
||||||
@ -141,6 +160,12 @@ function handleMessage(message: ChromeMessage, _sender: any, sendResponse: (resp
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'cleanup':
|
||||||
|
// 清理样式
|
||||||
|
cleanupHighlightStyles();
|
||||||
|
sendResponse({ success: true });
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
sendResponse({ success: false, error: '未知操作' });
|
sendResponse({ success: false, error: '未知操作' });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
/* Content Script Styles */
|
|
||||||
|
|
||||||
.readmd-highlight {
|
|
||||||
outline: 2px solid #4CAF50 !important;
|
|
||||||
background-color: rgba(76, 175, 80, 0.1) !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.readmd-selection-mode {
|
|
||||||
cursor: crosshair !important;
|
|
||||||
}
|
|
||||||
@ -68,6 +68,10 @@ export function Popup() {
|
|||||||
});
|
});
|
||||||
await copyToClipboard(markdown);
|
await copyToClipboard(markdown);
|
||||||
showStatus('success', '已复制到剪贴板!');
|
showStatus('success', '已复制到剪贴板!');
|
||||||
|
// 1秒后关闭弹窗
|
||||||
|
setTimeout(() => {
|
||||||
|
window.close();
|
||||||
|
}, 1000);
|
||||||
} catch {
|
} catch {
|
||||||
showStatus('error', '复制失败');
|
showStatus('error', '复制失败');
|
||||||
}
|
}
|
||||||
@ -95,7 +99,11 @@ export function Popup() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
URL.revokeObjectURL(url);
|
URL.revokeObjectURL(url);
|
||||||
showStatus('success', '下载完成!');
|
showStatus('success', '开始下载...');
|
||||||
|
// 1秒后关闭弹窗
|
||||||
|
setTimeout(() => {
|
||||||
|
window.close();
|
||||||
|
}, 1000);
|
||||||
} catch {
|
} catch {
|
||||||
showStatus('error', '下载失败');
|
showStatus('error', '下载失败');
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,7 +24,7 @@ export interface UserSettings {
|
|||||||
|
|
||||||
// Chrome消息类型
|
// Chrome消息类型
|
||||||
export interface ChromeMessage {
|
export interface ChromeMessage {
|
||||||
action: 'extract' | 'extractSelection' | 'preview' | 'copy' | 'download';
|
action: 'extract' | 'extractSelection' | 'preview' | 'cleanup' | 'copy' | 'download';
|
||||||
options?: ExtractOptions;
|
options?: ExtractOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user