也是卡饭有人求,因为我不会弄油猴脚本和Firefox扩展,只好组装一下UC脚本
// ==UserScript==
// @name AutoCopySelectionText.uc.js
// @description 自动复制选中文本(ScrLk 亮起时不复制)
// @author Ryan
// @version 2022.07.18
// @compatibility Firefox 87
// @charset UTF-8
// @system windows
// @license MIT License
// @include main
// @shutdown window.AutoCopySelectionText.destroy();
// @homepageURL https://github.com/benzBrake/FirefoxCustomize/tree/master/userChromeJS
// @version 2022.07.18 支持长按延时
// @version 2022.07.16 重写代码,支持热插拔,采用 异步消息,支持 Firefox 内置页面
// @version 2022.07.13 初始化版本
// ==/UserScript==
(function () {
class AutoCopySelectionText {
constructor() {
Components.utils.import("resource://gre/modules/ctypes.jsm");
let user32 = ctypes.open("user32.dll");
this.getKeyState = user32.declare('GetKeyState', ctypes.winapi_abi, ctypes.bool, ctypes.int);
this.TIMEOUT_ID = null;
this.WAIT_TIME = 0; // Change it to any number as you want
this.LONG_PRESS = false;
function frameScript() {
content.acst_Content = {
init: function () {
addMessageListener("acst_getSelectedText", this);
addMessageListener("acst_destroy", this);
},
receiveMessage: function (message) {
switch (message.name) {
case 'acst_getSelectedText':
let sel = content.getSelection();
let data = { text: sel.toString() }
sendSyncMessage("acst_selectionData", data);
break;
case 'acst_destroy':
content.acst_Content.destroy();
break;
}
},
destroy() {
removeMessageListener("acst_getSelectedText", this);
removeMessageListener("acst_destroy", this);
delete content.acst_Content;
}
}
content.acst_Content.init();
}
let frameScriptURI = 'data:application/javascript,'
+ encodeURIComponent('(' + frameScript.toString() + ')()');
window.messageManager.loadFrameScript(frameScriptURI, true);
window.messageManager.addMessageListener("acst_selectionData", this);
["mousemove", "mouseup"].forEach((t) => gBrowser.tabpanels.addEventListener(t, this, false))
}
trigger(browser) {
browser || (browser = gBrowser.selectedTab.linkedBrowser);
browser.messageManager.sendAsyncMessage("acst_getSelectedText");
}
receiveMessage(message) {
switch (message.name) {
case 'acst_selectionData':
if (message.data.text)
Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString(message.data.text);
break;
}
}
handleEvent(event) {
if (this.TIMEOUT_ID)
clearTimeout(this.TIMEOUT_ID);
if (this.getKeyState(0x91)) return;
switch (event.type) {
case 'mousemove':
this.TIMEOUT_ID = setTimeout(function () {
window.AutoCopySelectionText.LONG_PRESS = true;
}, this.WAIT_TIME)
case 'mouseup':
// 鼠标按键释放时读取选中文本
if (window.AutoCopySelectionText.LONG_PRESS) {
try {
gBrowser.selectedTab.linkedBrowser.messageManager.sendAsyncMessage("acst_getSelectedText");
} catch (e) { }
}
break;
}
this.LONG_PRESS = false;
}
destroy() {
window.messageManager.broadcastAsyncMessage("acst_destroy");
window.messageManager.removeMessageListener("acst_selectionData", this);
["mousemove", "mouseup"].forEach((t) => gBrowser.tabpanels.removeEventListener(t, this, false))
delete window.AutoCopySelectionText;
}
}
window.AutoCopySelectionText = new AutoCopySelectionText();
})()
有人求助内置页面不能复制,故更新了一下,这个需求硬生生把脚本弄长了几倍
// ==UserScript==
// @name AutoCopySelectionText.uc.js
// @description 自动复制选中文本(ScrLk 亮起时不复制)
// @author Ryan
// @version 2022.07.16
// @compatibility Firefox 87
// @charset UTF-8
// @system windows
// @license MIT License
// @include main
// @shutdown window.AutoCopySelectionText.destroy();
// @homepageURL https://github.com/benzBrake/FirefoxCustomize/tree/master/userChromeJS
// @version 2022.07.16 重写代码,支持热插拔,采用 异步消息,支持 Firefox 内置页面
// @version 2022.07.13 初始化版本
// ==/UserScript==
(function () {
class AutoCopySelectionText {
constructor() {
Components.utils.import("resource://gre/modules/ctypes.jsm");
let user32 = ctypes.open("user32.dll");
this.getKeyState = user32.declare('GetKeyState', ctypes.winapi_abi, ctypes.bool, ctypes.int);
// 调用 DLL 方法 第一个参数 方法名,第二个参数不懂照着写吧,第三个参数返回值类型,第三个参数以后是调用参数类型,有几个参数写几个
function frameScript() {
// e10s 后就得通过消息来获取内容进程
content.acst_Content = {
init: function () {
addMessageListener("acst_getSelectedText", this);
addMessageListener("acst_destroy", this);
},
receiveMessage: function (message) {
switch (message.name) {
case 'acst_getSelectedText':
let sel = content.getSelection();
let data = { text: sel.toString() }
sendSyncMessage("acst_selectionData", data); // 通过消息发回选中文本,不能直接发 content.getSelction(),安全原因不能发 XPCOM 对象
break;
case 'acst_destroy':
this.destroy();
break;
}
},
destroy() {
removeMessageListener("acst_getSelectedText", this);
removeMessageListener("acst_destroy", this);
delete content.acst_Content;
}
}
content.acst_Content.init();
}
let frameScriptURI = 'data:application/javascript,'
+ encodeURIComponent('(' + frameScript.toString() + ')()');
window.messageManager.loadFrameScript(frameScriptURI, true);
window.messageManager.addMessageListener("acst_selectionData", this);
gBrowser.tabpanels.addEventListener("mouseup", this, false);
}
trigger(browser) {
browser || (browser = gBrowser.selectedTab.linkedBrowser);
browser.messageManager.sendAsyncMessage("acst_getSelectedText");
}
receiveMessage(message) {
switch (message.name) {
case 'acst_selectionData':
if (message.data.text)
Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString(message.data.text);
break;
}
}
handleEvent(event) {
switch (event.type) {
case 'mouseup': // 鼠标按键释放时读取选中文本
if (this.getKeyState(0x91)) return; // 0x91 是 ScrLk 的按键码,ScrLk 灯亮起时不复制
try {
this.trigger();
} catch (e) { }
}
}
destroy() {
window.messageManager.broadcastAsyncMessage("acst_destroy");
window.messageManager.removeMessageListener("acst_selectionData", this);
delete window.AutoCopySelectionText;
}
}
window.AutoCopySelectionText = new AutoCopySelectionText();
})()
半夜肚子饿吃东西的时候看见了要开关功能,想尝试一下调用 dll,结果发现没什么问题。如果想要工具栏按钮就自己照我的代码尝试该改吧,我不想改了。
因此更新了 ScrLk 亮起时不复制,但是因为调用了 windows api 只能 windows 用
location.href.startsWith('chrome://browser/content/browser.x') && setTimeout(() => {
Components.utils.import("resource://gre/modules/ctypes.jsm");
var lib = ctypes.open("user32.dll");
const getKeyState = lib.declare('GetKeyState', ctypes.winapi_abi, ctypes.bool, ctypes.int);
// 调用 DLL 方法 第一个参数 方法名,第二个参数不懂照着写吧,第三个参数返回值类型,第三个参数以后是调用参数类型,有几个参数写几个
gBrowser.tabpanels.addEventListener("mouseup", function() {
try {
if (getKeyState(0x91)) return; // 0x91 是 ScrLk 的按键码,ScrLk 灯亮起时不复制
// if (!getKeyState(0x91)) return; // ScrLk 亮起时复制
gBrowser.selectedBrowser.finder.getInitialSelection().then((r) => {
if (r.selectedText) {
Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString(r.selectedText);
}
})
} catch (e) { }
}, false);
}, 1000);
感谢逗大分享!