AutocopySelection2Clipboard貌似在Firefox扩展中心下架,有什么替代呢?

Firefox 2022-07-12 216℃ 0 0

也是卡饭有人求,因为我不会弄油猴脚本和Firefox扩展,只好组装一下UC脚本

后续更新请关注:https://github.com/benzBrake/FirefoxCustomize/blob/master/userChromeJS/87/AutoCopySelectionText.uc.js

// ==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);

评论 (0)

Top