first commit
This commit is contained in:
372
content.js
Normal file
372
content.js
Normal file
@@ -0,0 +1,372 @@
|
||||
// content.js - 核心功能实现
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
console.log('[BlurText] Content script loaded');
|
||||
|
||||
let isBlurMode = false;
|
||||
let blurMode = 'element'; // 'element' or 'selection'
|
||||
let blurIntensity = 10;
|
||||
let blurredElements = new Set();
|
||||
let hintElement = null;
|
||||
let blurButton = null; // 浮动模糊按钮
|
||||
|
||||
// 初始化:从存储中加载配置
|
||||
chrome.storage.local.get(['blurIntensity'], (result) => {
|
||||
if (result.blurIntensity) {
|
||||
blurIntensity = result.blurIntensity;
|
||||
console.log('[BlurText] Loaded blur intensity:', blurIntensity);
|
||||
}
|
||||
});
|
||||
|
||||
// 监听来自 popup 的消息
|
||||
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
||||
console.log('[BlurText] Received message:', request);
|
||||
|
||||
if (request.action === 'toggleBlurMode') {
|
||||
isBlurMode = request.enabled;
|
||||
blurMode = request.mode || 'element';
|
||||
blurIntensity = request.intensity || 10;
|
||||
|
||||
console.log('[BlurText] Toggle blur mode:', isBlurMode, 'mode:', blurMode, 'intensity:', blurIntensity);
|
||||
|
||||
if (isBlurMode) {
|
||||
enableBlurMode();
|
||||
} else {
|
||||
disableBlurMode();
|
||||
}
|
||||
} else if (request.action === 'clearAll') {
|
||||
console.log('[BlurText] Clear all blurs');
|
||||
clearAllBlurs();
|
||||
} else if (request.action === 'updateIntensity') {
|
||||
blurIntensity = request.intensity;
|
||||
console.log('[BlurText] Update intensity:', blurIntensity);
|
||||
updateAllBlurIntensity();
|
||||
} else if (request.action === 'switchMode') {
|
||||
blurMode = request.mode;
|
||||
console.log('[BlurText] Switch mode:', blurMode);
|
||||
updateModeUI();
|
||||
}
|
||||
});
|
||||
|
||||
// 启用模糊模式
|
||||
function enableBlurMode() {
|
||||
console.log('[BlurText] Enabling blur mode, mode:', blurMode);
|
||||
|
||||
const modeText = blurMode === 'selection' ? '文本选择模式 - 拖动选择文字后点击模糊按钮' : '元素模式 - 点击元素进行模糊';
|
||||
showHint(`模糊模式已开启 - ${modeText},按 ESC 退出`);
|
||||
|
||||
// 根据模式添加对应的样式和事件
|
||||
if (blurMode === 'element') {
|
||||
document.body.classList.add('blurtext-mode');
|
||||
document.addEventListener('click', handleClick, true);
|
||||
document.addEventListener('mouseover', handleMouseOver, true);
|
||||
document.addEventListener('mouseout', handleMouseOut, true);
|
||||
} else if (blurMode === 'selection') {
|
||||
// 文本选择模式不需要 crosshair 光标
|
||||
document.addEventListener('mouseup', handleTextSelection, true);
|
||||
}
|
||||
|
||||
// 键盘事件对两种模式都需要
|
||||
document.addEventListener('keydown', handleKeydown, true);
|
||||
|
||||
console.log('[BlurText] Event listeners attached');
|
||||
}
|
||||
|
||||
// 禁用模糊模式
|
||||
function disableBlurMode() {
|
||||
document.body.classList.remove('blurtext-mode');
|
||||
hideHint();
|
||||
hideBlurButton();
|
||||
|
||||
// 移除所有事件监听
|
||||
document.removeEventListener('click', handleClick, true);
|
||||
document.removeEventListener('keydown', handleKeydown, true);
|
||||
document.removeEventListener('mouseover', handleMouseOver, true);
|
||||
document.removeEventListener('mouseout', handleMouseOut, true);
|
||||
document.removeEventListener('mouseup', handleTextSelection, true);
|
||||
|
||||
// 清除所有高亮和预览
|
||||
removeAllHighlights();
|
||||
}
|
||||
|
||||
// 更新模式UI
|
||||
function updateModeUI() {
|
||||
if (!isBlurMode) return;
|
||||
|
||||
console.log('[BlurText] Switching mode to:', blurMode);
|
||||
|
||||
// 先移除所有旧的事件监听和样式
|
||||
document.body.classList.remove('blurtext-mode');
|
||||
document.removeEventListener('click', handleClick, true);
|
||||
document.removeEventListener('mouseover', handleMouseOver, true);
|
||||
document.removeEventListener('mouseout', handleMouseOut, true);
|
||||
document.removeEventListener('mouseup', handleTextSelection, true);
|
||||
|
||||
// 清除旧模式的UI元素
|
||||
hideBlurButton();
|
||||
removeAllHighlights();
|
||||
|
||||
// 根据新模式添加事件监听和样式
|
||||
if (blurMode === 'element') {
|
||||
document.body.classList.add('blurtext-mode');
|
||||
document.addEventListener('click', handleClick, true);
|
||||
document.addEventListener('mouseover', handleMouseOver, true);
|
||||
document.addEventListener('mouseout', handleMouseOut, true);
|
||||
showHint('已切换到元素模式 - 点击元素进行模糊', 3000);
|
||||
} else if (blurMode === 'selection') {
|
||||
// 文本选择模式不需要 crosshair 光标
|
||||
document.addEventListener('mouseup', handleTextSelection, true);
|
||||
showHint('已切换到文本选择模式 - 拖动选择文字后点击模糊按钮', 3000);
|
||||
}
|
||||
|
||||
console.log('[BlurText] Mode switched successfully');
|
||||
}
|
||||
|
||||
// 处理点击事件
|
||||
function handleClick(e) {
|
||||
console.log('[BlurText] Click detected, isBlurMode:', isBlurMode, 'blurMode:', blurMode);
|
||||
|
||||
if (!isBlurMode || blurMode !== 'element') return;
|
||||
|
||||
// 阻止默认行为
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
let target = e.target;
|
||||
console.log('[BlurText] Target element:', target.tagName, target.className, 'text:', target.textContent?.substring(0, 20));
|
||||
|
||||
// 如果是提示元素,忽略
|
||||
if (target.classList.contains('blurtext-hint')) {
|
||||
console.log('[BlurText] Ignored hint element');
|
||||
return;
|
||||
}
|
||||
|
||||
// 切换模糊状态
|
||||
toggleBlur(target);
|
||||
}
|
||||
|
||||
// 处理键盘事件(ESC 退出)
|
||||
function handleKeydown(e) {
|
||||
if (e.key === 'Escape' && isBlurMode) {
|
||||
isBlurMode = false;
|
||||
disableBlurMode();
|
||||
|
||||
// 通知 popup
|
||||
chrome.runtime.sendMessage({ action: 'blurModeDisabled' });
|
||||
}
|
||||
}
|
||||
|
||||
// 处理文本选择(文本选择模式)
|
||||
function handleTextSelection(e) {
|
||||
if (!isBlurMode || blurMode !== 'selection') return;
|
||||
|
||||
// 避免点击模糊按钮时触发
|
||||
if (e.target.classList.contains('blurtext-blur-button')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const selection = window.getSelection();
|
||||
const selectedText = selection.toString().trim();
|
||||
|
||||
console.log('[BlurText] Text selection:', selectedText);
|
||||
|
||||
if (selectedText.length > 0) {
|
||||
// 显示模糊按钮
|
||||
showBlurButton(selection);
|
||||
} else {
|
||||
// 没有选中文本,隐藏按钮
|
||||
hideBlurButton();
|
||||
}
|
||||
}
|
||||
|
||||
// 显示模糊按钮
|
||||
function showBlurButton(selection) {
|
||||
// 移除旧按钮
|
||||
hideBlurButton();
|
||||
|
||||
// 获取选区的位置
|
||||
const range = selection.getRangeAt(0);
|
||||
const rect = range.getBoundingClientRect();
|
||||
|
||||
// 创建模糊按钮
|
||||
blurButton = document.createElement('div');
|
||||
blurButton.className = 'blurtext-blur-button';
|
||||
blurButton.textContent = '🔒 模糊选中文本';
|
||||
blurButton.style.position = 'fixed';
|
||||
blurButton.style.left = `${rect.left + rect.width / 2}px`;
|
||||
blurButton.style.top = `${rect.bottom + 10}px`;
|
||||
blurButton.style.transform = 'translateX(-50%)';
|
||||
blurButton.style.zIndex = '2147483647';
|
||||
|
||||
// 点击按钮模糊文本
|
||||
blurButton.addEventListener('click', (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
blurSelectedText();
|
||||
});
|
||||
|
||||
document.body.appendChild(blurButton);
|
||||
}
|
||||
|
||||
// 隐藏模糊按钮
|
||||
function hideBlurButton() {
|
||||
if (blurButton && blurButton.parentNode) {
|
||||
blurButton.parentNode.removeChild(blurButton);
|
||||
blurButton = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 模糊选中的文本
|
||||
function blurSelectedText() {
|
||||
const selection = window.getSelection();
|
||||
if (!selection.rangeCount) return;
|
||||
|
||||
try {
|
||||
const range = selection.getRangeAt(0);
|
||||
|
||||
// 创建 span 包裹选中的文本
|
||||
const span = document.createElement('span');
|
||||
span.className = 'blurtext-blurred blurtext-selection-wrapped';
|
||||
span.style.setProperty('--blur-intensity', `${blurIntensity}px`);
|
||||
|
||||
// 包裹选中的内容
|
||||
range.surroundContents(span);
|
||||
|
||||
// 添加到模糊元素集合
|
||||
blurredElements.add(span);
|
||||
|
||||
console.log('[BlurText] Text selection blurred, total elements:', blurredElements.size);
|
||||
|
||||
// 清除选择
|
||||
selection.removeAllRanges();
|
||||
|
||||
// 隐藏按钮
|
||||
hideBlurButton();
|
||||
|
||||
// 显示提示
|
||||
showHint('文本已模糊', 2000);
|
||||
} catch (error) {
|
||||
console.error('[BlurText] Error blurring selection:', error);
|
||||
showHint('无法模糊该选区(可能包含复杂的HTML结构)', 3000);
|
||||
hideBlurButton();
|
||||
}
|
||||
}
|
||||
|
||||
// 鼠标悬停高亮
|
||||
function handleMouseOver(e) {
|
||||
if (!isBlurMode || blurMode !== 'element') return;
|
||||
|
||||
const target = e.target;
|
||||
if (target.classList.contains('blurtext-hint') ||
|
||||
target.classList.contains('blurtext-blurred')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 移除之前的高亮
|
||||
removeAllHighlights();
|
||||
|
||||
// 直接高亮元素
|
||||
target.classList.add('blurtext-highlight');
|
||||
}
|
||||
|
||||
// 移除所有高亮
|
||||
function removeAllHighlights() {
|
||||
const highlighted = document.querySelectorAll('.blurtext-highlight');
|
||||
highlighted.forEach(el => {
|
||||
el.classList.remove('blurtext-highlight');
|
||||
});
|
||||
}
|
||||
|
||||
// 鼠标移出取消高亮
|
||||
function handleMouseOut(e) {
|
||||
if (!isBlurMode || blurMode !== 'element') return;
|
||||
|
||||
// 延迟移除,避免在元素间移动时闪烁
|
||||
setTimeout(() => {
|
||||
// 检查鼠标是否还在模糊模式下的元素上
|
||||
const hoveredElement = document.elementFromPoint(e.clientX, e.clientY);
|
||||
if (!hoveredElement ||
|
||||
hoveredElement.classList.contains('blurtext-hint') ||
|
||||
hoveredElement.classList.contains('blurtext-blurred')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 如果鼠标不在任何高亮元素上,清除所有高亮
|
||||
const highlighted = document.querySelector('.blurtext-highlight:hover');
|
||||
if (!highlighted) {
|
||||
removeAllHighlights();
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
// 切换元素模糊状态
|
||||
function toggleBlur(element) {
|
||||
if (blurredElements.has(element)) {
|
||||
// 取消模糊
|
||||
console.log('[BlurText] Removing blur from element');
|
||||
element.classList.remove('blurtext-blurred');
|
||||
element.style.removeProperty('--blur-intensity');
|
||||
blurredElements.delete(element);
|
||||
} else {
|
||||
// 添加模糊
|
||||
console.log('[BlurText] Adding blur to element, intensity:', blurIntensity);
|
||||
element.classList.add('blurtext-blurred');
|
||||
element.style.setProperty('--blur-intensity', `${blurIntensity}px`);
|
||||
blurredElements.add(element);
|
||||
}
|
||||
console.log('[BlurText] Total blurred elements:', blurredElements.size);
|
||||
}
|
||||
|
||||
// 清除所有模糊
|
||||
function clearAllBlurs() {
|
||||
blurredElements.forEach(element => {
|
||||
element.classList.remove('blurtext-blurred');
|
||||
element.style.removeProperty('--blur-intensity');
|
||||
});
|
||||
blurredElements.clear();
|
||||
|
||||
// 如果在模糊模式下,显示提示
|
||||
if (isBlurMode) {
|
||||
showHint('已清除所有模糊效果', 2000);
|
||||
}
|
||||
}
|
||||
|
||||
// 更新所有已模糊元素的强度
|
||||
function updateAllBlurIntensity() {
|
||||
blurredElements.forEach(element => {
|
||||
element.style.setProperty('--blur-intensity', `${blurIntensity}px`);
|
||||
});
|
||||
}
|
||||
|
||||
// 显示提示
|
||||
function showHint(message, duration = null) {
|
||||
// 移除旧提示
|
||||
hideHint();
|
||||
|
||||
// 创建新提示
|
||||
hintElement = document.createElement('div');
|
||||
hintElement.className = 'blurtext-hint';
|
||||
hintElement.textContent = message;
|
||||
document.body.appendChild(hintElement);
|
||||
|
||||
// 如果指定了持续时间,自动隐藏
|
||||
if (duration) {
|
||||
setTimeout(() => {
|
||||
hideHint();
|
||||
}, duration);
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏提示
|
||||
function hideHint() {
|
||||
if (hintElement && hintElement.parentNode) {
|
||||
hintElement.parentNode.removeChild(hintElement);
|
||||
hintElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
// 页面加载完成后,恢复之前的模糊状态(未来功能)
|
||||
// 这里可以添加持久化存储功能
|
||||
|
||||
})();
|
||||
Reference in New Issue
Block a user