-
-
Notifications
You must be signed in to change notification settings - Fork 58
Open
Description
一个很神奇的bug:
选中某个关键词,按下Ctrl+`快捷键用扩展高亮后,自动复制脚本就失效了
换其他页面就没这个问题
用Edge浏览器也没有这个问题
示例页面:https://mp.weixin.qq.com/s/pSY5rKVpuFxZokgFhPHf5g
Windows 11, Firefox 141 (至少13x以来都有这个问题)
我用的自动复制脚本
// ==UserScript==
// @name AutoCopy
// @name:zh-CN 自动复制
// @namespace https://github.com/YandLiu/
// @version 20250715
// @description 选中自动复制
// @author YandLiu
// @include *
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_addValueChangeListener
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAABpElEQVR4nO3Vv2uUQRDG8c/ebSMWqay0trATAxrUSi1S2AiWFoJYpNCgoBjURsHWJKeNRfAvsDgFixQqKdPZ2ViEiCJYBOQu8f1hEXO59713j7MUfLZ6d2a/O8vMO0OzDnin9Ku2Mjvuaw07xgSAYEVXe2indMhj92zpKJLnBhF8MDeye9hn6zbN70eRiqCw02Bra3up8BBLu1FEBxsBucXqW4csz0ULe4jorSCMuPU89boRELDMHiI6Y8V65bbCUTccc70RkaOwKLOg0IkyXa9qTjOu2LAs6NZuD86hrdTyxRNTkUqqdhXlHrngGRVEZsMpJwex9DxIZSHYclesIb65LCoHgIs66UJq6btDBZHZrPh8V6YBOX66LbOkTGckBYimBW2FVTNeuOZNyrFJ236Yl4NSy5SbVm1PDvhodqgyMledTdRlAtDzqfL9tfkwUtyaRkv9LwFj9B/w7wPycXOhqlJ0yZHKPChMi5MCiM47XhsopbVJAUHfrYbmN/EToN+02eLPfz9OYyZhFJzW1Jn3lTsxaKQjCkp52jy45r1ZvSbTb9M0d4PBozGZAAAAAElFTkSuQmCC
// ==/UserScript==
// (function () {
// 'use strict';
const STORAGE_KEY = '__autoCopyEnabled';
let enabled = GM_getValue(STORAGE_KEY, true);
// 创建悬浮按钮
var button = document.createElement('button');
button.textContent = '📋';
Object.assign(button.style, {
position: 'fixed',
bottom: '10px',
right: '10px',
zIndex: 9999,
padding: '5px 5px',
fontSize: '14px',
backgroundColor: enabled ? 'rgba(76, 175, 80, 0.3)' : 'rgba(244, 67, 54, 0.3)',
color: 'white',
border: 'none',
borderRadius: '10px',
cursor: 'pointer',
});
// 阻止在iframe中显示
if (window.top !== window.self) return;
else document.body.appendChild(button);
// 监听按钮点击
button.addEventListener('click', async () => {
enabled = !enabled;
await GM_setValue(STORAGE_KEY, enabled);
updateButton();
});
// 跨标签页同步
GM_addValueChangeListener(STORAGE_KEY, (name, oldVal, newVal) => {
enabled = newVal;
updateButton();
});
function updateButton () {
button.style.backgroundColor = enabled ? 'rgba(76, 175, 80, 0.3)' : 'rgba(244, 67, 54, 0.3)';
}
let mouseDownTarget;
window.onmousedown = function (e) {
mouseDownTarget = e.target;
};
// 记录双击事件
let lastClickTime = 0;
let doubleClickThreshold = 300; // 双击阈值(毫秒)
window.addEventListener('mouseup', (e) => {
const now = Date.now();
const isDoubleClick = (now - lastClickTime) < doubleClickThreshold;
lastClickTime = now;
// 延迟处理,给浏览器时间更新选中范围
setTimeout(() => {
if (!inTextBox() && enabled) {
copySelection(isDoubleClick);
}
}, isDoubleClick ? 50 : 0); // 双击时增加延迟
});
function copySelection (isDoubleClick) {
try {
// 获取用户当前选中的HTML内容
const selection = document.getSelection();
// 检查是否有选中内容
if (!selection || selection.isCollapsed || selection.rangeCount === 0) return;
const range = selection.getRangeAt(0);
// 创建临时容器
const tempDiv = document.createElement('div');
tempDiv.appendChild(range.cloneContents());
// 清理临时容器中的脚本和事件
sanitizeContent(tempDiv);
// 获取选中内容的 HTML 代码和文本
const htmlContent = tempDiv.innerHTML;
const textContent = selection.toString();
// 检查内容是否有效
if (!htmlContent.trim() || !textContent.trim()) return;
// 创建剪贴板项
const htmlBlob = new Blob([htmlContent], {type: 'text/html'});
const textBlob = new Blob([textContent], {type: 'text/plain'});
const clipboardItem = new ClipboardItem({
'text/html': htmlBlob,
'text/plain': textBlob
});
// 写入剪贴板
navigator.clipboard.write([clipboardItem]).catch(err => {
console.error('自动复制失败:', err);
// 回退方案
document.execCommand('copy');
});
} catch (error) {
console.error('自动复制过程出错:', error);
}
}
// 清理临时容器中的潜在危险内容
function sanitizeContent (element) {
// 移除所有脚本标签
const scripts = element.querySelectorAll('script');
scripts.forEach(script => script.remove());
// 移除所有事件属性
const allElements = element.querySelectorAll('*');
allElements.forEach(el => {
for (let attr of el.attributes) {
if (attr.name.startsWith('on')) {
el.removeAttribute(attr.name);
}
}
});
}
// 检测是否在文本框/编辑器中
function inTextBox () {
const generalElements = ['textarea, input, *[contenteditable="true"]'];
let targets = [];
// 收集常规文本输入元素
generalElements.forEach(selector => {
document.querySelectorAll(selector).forEach(el => {
targets.push(el);
});
});
// 特定网站的特殊处理
const siteSpecificRules = {
'mail.google.com': 'div[aria-label= "Message Body"]',
'outlook.live.com': '#editorParent_1'
};
for (const [hostname, selector] of Object.entries(siteSpecificRules)) {
if (document.location.hostname.includes(hostname)) {
document.querySelectorAll(selector).forEach(el => {
targets.push(el);
});
}
}
// 检查点击目标是否在这些元素内
return targets.some(target => target.contains(mouseDownTarget));
}
// })();
Metadata
Metadata
Assignees
Labels
No labels