UndoCloseTabBtn.uc.js和KeyChanger.uc.js问题

阅读:2927回复:9
2020-03-12 22:21
写私信
楼主#
@lonely_8

1、UndoCloseTabBtn.uc.js

65时候你有改过,后来68又有小变化,我简单改了下也能凑活用。但是我一直想问,为什么第二个窗口列表就是空的?能不能改成显示当前窗口已关闭的标签?
// ==UserScript==
// @Name                 UndoCloseTabBtn.uc.js
// @namespace         UndoCloseTab@gmail.com
// @description         可移动恢复已关闭标签按钮
// @author               defpt
// @charset              UTF-8
// @Compatibility        FF69+
// @version              v2018.12.05 更新兼容65+ by lonely_8
// @version              v2018.04.04 更新兼容57+ by runningcheese
// @version              v2014.09.15
// ==/UserScript==
(function() {
    if(document.getElementById('undoclosetab-button')) return;
          
    CustomizableUI.createWidget({
        id: 'undoclosetab-button',
        label: '恢复最后关闭的标签',
        tooltiptext: '左键:恢复最后关闭的标签\n右键:显示关闭标签菜单',
        defaultArea : CustomizableUI.AREA_NAVBAR,
        onCreated: (uCTBtn) => {
            uCTBtn.setAttribute('context', '_child'); //点击按钮恢复最后一次关闭的标签
                               //如果想左键恢复最后一次关闭的标签,右键打开已关闭标签列表,那么改为(context: "_child",)
                               //如果想改成菜单形式的,那么改为(type: "menu-button",)
            uCTBtn.setAttribute('command', 'History:UndoCloseTab');
          
            uCTBtn.appendChild($C('menupopup', {
                oncommand: 'event.stopPropagation();',
                onpopupshowing: 'this.parentNode.populateUndoSubmenu();',
                context: '',
                tooltip: 'bhTooltip',
                popupsinherittooltip: 'true'
            }));
            uCTBtn._getClosedTabCount = HistoryMenu.prototype._getClosedTabCount;
            uCTBtn.populateUndoSubmenu = eval('(' + HistoryMenu.prototype.populateUndoSubmenu.toString().replace(/\.undoTabMenu/g, '').replace(/\.menupopup/g, '.firstChild') + ')');
        }
    });
          
          
    document.insertBefore(document.createProcessingInstruction(
        'xml-stylesheet', 'type="text/css" href="data:text/css;utf-8,' + encodeURIComponent('\
            #undoclosetab-button menuitem {max-width: 240px;}\
            #undoclosetab-button .toolbarbutton-icon {list-style-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABuUlEQVRIib2VL08DQRDFKxANqahErijJte/N5pI2oQlNuA+AqEBUkHAJAkMIAhJERYNBICr4ABUIFKlEIBA4DAJRgUBUIJpgKioqitkry8H9CxcmmeQutzu/eTO5mULhP4xkA0Ar6ruIOCR3SZ4A6JrnRhaAR3JqQ5RSRQDHJMckFxE+JtlzXbccCwDQMRemAFpaa5J8jQkc9ncRaccBfOvw1HjwPhORvjnTAFAB0BGRfkjdXEQOo2rs/5YZgIGIbEUlJiKOAc3MnQ8Ae0kKlvUFsBZb2y9Qm+Tc3Jv86AnJo4ja3lar1fU0EJKXlvLz8MdeTAOHnuetJAFc1y1bPZlkASwAXKVU0bPuuN/ojuOoOE+jAsCOBfDTJJXJarXahqX8NHeA+UEDBd3cASJyYCnYzx0AYBAAtNbNvINvknwxgKd6vb6aK4DkfZB95EyysimJyBmAUprgZkcEwe+SDq8FUgG8kfSizppF9Gg1dpI4vwBUSI7sMUzy2YzsjvELkkNrwAVjfjuN4mCu3GRYOCOtNVMFD6lpkbwOLaDlIiL5AMBPM0ZiTSlVNPX2SHpa66ZSqvinoHnZJ3jLDwknYoRNAAAAAElFTkSuQmCC")}\
    ') + '"'), document.documentElement);
                        
    function $C(name, attr) {
        var el = document.createXULElement(name);
        if (attr) Object.keys(attr).forEach(function(n) { return el.setAttribute(n, attr[n]);});
        return el;
    }
})();



2、KeyChanger.uc.js经过多人修改和我自己瞎改后74还能凑活用,但是71开始无法覆盖浏览器默认快捷键了,比如F5/F6/CTRL+E之类的快捷键,怎么解决?
_keychanger.js
keys['Alt+E'] = "undoCloseTab();"
修复后脚本:
KeyChanger74+.uc.rar
2020-03-13 15:41
写私信
1楼#
// ==UserScript==
// @Name                 UndoCloseTabBtn.uc.js
// @namespace         UndoCloseTab@gmail.com
// @description         可移动恢复已关闭标签按钮
// @author               defpt
// @charset              UTF-8
// @Compatibility        FF69+
// @version              v2018.12.05 更新兼容65+ by lonely_8
// @version              v2018.04.04 更新兼容57+ by runningcheese
// @version              v2014.09.15
// ==/UserScript==
(function() {
    if(!document.getElementById('undoclosetab-button')) {
           
    CustomizableUI.createWidget({
        id: 'undoclosetab-button',
        label: '恢复最后关闭的标签',
        tooltiptext: '左键:恢复最后关闭的标签\n右键:显示关闭标签菜单',
        defaultArea : CustomizableUI.AREA_NAVBAR,
        onCreated: (uCTBtn) => {
            uCTBtn.setAttribute('context', '_child'); //点击按钮恢复最后一次关闭的标签
                               //如果想左键恢复最后一次关闭的标签,右键打开已关闭标签列表,那么改为(context: "_child",)
                               //如果想改成菜单形式的,那么改为(type: "menu-button",)
            uCTBtn.setAttribute('command', 'History:UndoCloseTab');
           
            uCTBtn.appendChild($C('menupopup', {
                oncommand: 'event.stopPropagation();',
                onpopupshowing: 'this.parentNode.populateUndoSubmenu();',
                context: '',
                tooltip: 'bhTooltip',
                popupsinherittooltip: 'true'
            }, uCTBtn.ownerDocument));
            uCTBtn._getClosedTabCount = HistoryMenu.prototype._getClosedTabCount;
            uCTBtn.populateUndoSubmenu = eval('(' + HistoryMenu.prototype.populateUndoSubmenu.toString().replace('window', 'this.ownerGlobal').replace(/\.undoTabMenu/g, '').replace(/\.menupopup/g, '.firstChild') + ')');
        }
    });
    }
           
           
    document.insertBefore(document.createProcessingInstruction(
        'xml-stylesheet', 'type="text/css" href="data:text/css;utf-8,' + encodeURIComponent('\
            #undoclosetab-button menuitem {max-width: 240px;}\
            #undoclosetab-button .toolbarbutton-icon {list-style-image:url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAABuUlEQVRIib2VL08DQRDFKxANqahErijJte/N5pI2oQlNuA+AqEBUkHAJAkMIAhJERYNBICr4ABUIFKlEIBA4DAJRgUBUIJpgKioqitkry8H9CxcmmeQutzu/eTO5mULhP4xkA0Ar6ruIOCR3SZ4A6JrnRhaAR3JqQ5RSRQDHJMckFxE+JtlzXbccCwDQMRemAFpaa5J8jQkc9ncRaccBfOvw1HjwPhORvjnTAFAB0BGRfkjdXEQOo2rs/5YZgIGIbEUlJiKOAc3MnQ8Ae0kKlvUFsBZb2y9Qm+Tc3Jv86AnJo4ja3lar1fU0EJKXlvLz8MdeTAOHnuetJAFc1y1bPZlkASwAXKVU0bPuuN/ojuOoOE+jAsCOBfDTJJXJarXahqX8NHeA+UEDBd3cASJyYCnYzx0AYBAAtNbNvINvknwxgKd6vb6aK4DkfZB95EyysimJyBmAUprgZkcEwe+SDq8FUgG8kfSizppF9Gg1dpI4vwBUSI7sMUzy2YzsjvELkkNrwAVjfjuN4mCu3GRYOCOtNVMFD6lpkbwOLaDlIiL5AMBPM0ZiTSlVNPX2SHpa66ZSqvinoHnZJ3jLDwknYoRNAAAAAElFTkSuQmCC")}\
    ') + '"'), document.documentElement);
                         
    function $C(name, attr, doc) {
        var el = (doc || document).createXULElement(name);
        if (attr) Object.keys(attr).forEach(function(n) { return el.setAttribute(n, attr[n]);});
        return el;
    }
})();





KeyChanger.uc.js 脚本
Array.prototype.slice
改为
Array.prototype.slice.call
至于有些快捷键无法覆盖的原因是,这些快捷键是通过 js 动态侦听按键事件实现的,自由度比较高,但很难控制。
而 KeyChanger 通过添加 dom 节点,再由浏览器调用某一接口间接实现,通用性较强,但优先度也比较低。
2020-03-13 22:14
写私信
2楼#
lonely_8:// ==UserScript==
// @Name                 UndoCloseTabBtn.uc.js
// @namespace         UndoCloseTab@gmail.com
// @des...
回到原帖
感谢 已解决
2020-03-14 01:03
写私信
3楼#
lonely_8:// ==UserScript==
// @Name                 UndoCloseTabBtn.uc.js
// @namespace         UndoCloseTab@gmail.com
// @des...
回到原帖
关于KeyChanger,添加
keys['Alt+F'] = function () { BrowserSearch.webSearch(); };//光标跳至搜索栏
在FF74无效,也根据你的方法修改了,同样无效。
2020-03-15 02:29
写私信
4楼#
这个可以正常使用。
// ==UserScript==
// @name           KeyChanger.uc.js
// @author         Griever
// @namespace      http://d.hatena.ne.jp/Griever/
// @include        main
// @description    为火狐添额外的快捷键
// @license        MIT License
// @charset        UTF-8
// @version        2019.09.18.1
// @note           0.0.2 メニューを右クリックで設定ファイルを開けるようにした
// @note           0.0.2 Meta キーを装飾キーに使えるようになったかもしれない(未テスト)
// @note           0.0.2 Windows キーを装飾キーに使えるようになったかもしれない(未テスト Firefox 17 以降)
// @note           2018.1.25.2 Firefox59+ 修复
// ==/UserScript==
 
location.href.startsWith('chrome://browser/content/browser.x') && (function () {
    var useScraptchpad = true;  // 如果不存在编辑器,则使用代码片段速记器,否则设置编辑器路径
    //let {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
    window.KeyChanger = {
        get file() {
            var aFile = FileUtils.getFile("UChrm", ["local", "_keychanger.js"], false);
            if (!aFile.exists()) {
                saveFile(aFile, '');
                alert('_keychanger配置为空,该文件在local目录下');
            }
            delete this.file;
            return this.file = aFile;
        },
        get FILE() {
            return this.file;
        },
        isBuilding: false,
        makeKeyset: function (isAlert) {
            KeyChanger.isBuilding = true;
            var s = new Date();
            var keys = this.makeKeys();
            if (!keys) {
                isBuilding = false;
                return this.alert('KeyChanger', 'Load error.');
            }
            var keyset = document.getElementById('keychanger-keyset');
            if (keyset)
                keyset.parentNode.removeChild(keyset);
            keyset = document.createXULElement('keyset');
            keyset.setAttribute('id', 'keychanger-keyset');
            keyset.appendChild(keys);
 
            var df = document.createDocumentFragment();
            Array.prototype.slice(document.getElementsByTagName('keyset')).forEach(function (elem) {
                df.appendChild(elem);
            });
            var insPos = document.getElementById('mainPopupSet');
            insPos.parentNode.insertBefore(keyset, insPos);
            insPos.parentNode.insertBefore(df, insPos);
            var e = new Date() - s;
            if (isAlert) {
                this.alert('KeyChanger: Loaded', e + 'ms');
            }
            setTimeout(function () {
                KeyChanger.isBuilding = false;
            }, 100);
 
        },
        makeKeys: function () {
            var str = this.loadText(this.file);
            if (!str)
                return null;
 
            var sandbox = new Components.utils.Sandbox(new XPCNativeWrapper(window));
            var keys = Components.utils.evalInSandbox('var keys = {};\n' + str + ';\nkeys;', sandbox);
            if (!keys)
                return null;
            var dFrag = document.createDocumentFragment();
 
            Object.keys(keys).forEach(function (n) {
                let keyString = n.toUpperCase().split("+");
                let modifiers = "", key, keycode, k;
 
                for (let i = 0, l = keyString.length; i < l; i++) {
                    k = keyString[i];
                    switch (k) {
                        case "CTRL":
                        case "CONTROL":
                        case "ACCEL":
                            modifiers += "accel,";
                            break;
                        case "SHIFT":
                            modifiers += "shift,";
                            break;
                        case "ALT":
                        case "OPTION":
                            modifiers += "alt,";
                            break;
                        case "META":
                        case "COMMAND":
                            modifiers += "meta,";
                            break;
                        case "OS":
                        case "WIN":
                        case "WINDOWS":
                        case "HYPER":
                        case "SUPER":
                            modifiers += "os,";
                            break;
                        case "":
                            key = "+";
                            break;
                        case "BACKSPACE":
                        case "BKSP":
                        case "BS":
                            keycode = "VK_BACK";
                            break;
                        case "RET":
                        case "ENTER":
                            keycode = "VK_RETURN";
                            break;
                        case "ESC":
                            keycode = "VK_ESCAPE";
                            break;
                        case "PAGEUP":
                        case "PAGE UP":
                        case "PGUP":
                        case "PUP":
                            keycode = "VK_PAGE_UP";
                            break;
                        case "PAGEDOWN":
                        case "PAGE DOWN":
                        case "PGDN":
                        case "PDN":
                            keycode = "VK_PAGE_DOWN";
                            break;
                        case "TOP":
                            keycode = "VK_UP";
                            break;
                        case "BOTTOM":
                            keycode = "VK_DOWN";
                            break;
                        case "INS":
                            keycode = "VK_INSERT";
                            break;
                        case "DEL":
                            keycode = "VK_DELETE";
                            break;
                        default:
                            if (k.length === 1) {
                                key = k;
                            } else if (k.indexOf("VK_") === -1) {
                                keycode = "VK_" + k;
                            } else {
                                keycode = k;
                            }
                            break;
                    }
                }
                let elem = document.createXULElement('key');
                if (modifiers !== '')
                    elem.setAttribute('modifiers', modifiers.slice(0, -1));
                if (key)
                    elem.setAttribute('key', key);
                else if (keycode)
                    elem.setAttribute('keycode', keycode);
 
                let cmd = keys[n];
                switch (typeof cmd) {
                    case 'function':
                        elem.setAttribute('oncommand', '(' + cmd.toString() + ').call(this, event);');
                        break;
                    case 'object':
                        Object.keys(cmd).forEach(function (a) {
                            elem.setAttribute(a, cmd[a]);
                        }, this);
                        break;
                    default:
                        elem.setAttribute('oncommand', cmd);
                }
                dFrag.appendChild(elem);
            }, this);
            return dFrag;
        },
        createMenuitem: function () {
            var menuitem = document.createXULElement('menuitem');
            menuitem.setAttribute('id', 'toolsbar_KeyChanger_rebuild');
            menuitem.setAttribute('label', 'KeyChanger');
            menuitem.setAttribute('tooltiptext', '左键:重载配置\n右键:编辑配置');
            menuitem.setAttribute('oncommand', 'setTimeout(function(){ KeyChanger.makeKeyset(true); }, 10);');
            menuitem.setAttribute('onclick', 'if (event.button == 2) { event.preventDefault();KeyChanger.edit(KeyChanger.file); }');
            var insPos = document.getElementById('devToolsSeparator');
            insPos.parentNode.insertBefore(menuitem, insPos);
        },
        loadText: function (aFile) {
            var fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
            var sstream = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream);
            fstream.init(aFile, -1, 0, 0);
            sstream.init(fstream);
 
            var data = sstream.read(sstream.available());
            try {
                data = decodeURIComponent(escape(data));
            } catch (e) {
            }
            sstream.close();
            fstream.close();
            return data;
        },
        alert: function (aMsg, aTitle, aCallback) {
            var callback = aCallback ? {
                observe: function (subject, topic, data) {
                    if ("alertclickcallback" != topic)
                        return;
                    aCallback.call(null);
                }
            } : null;
            var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
            alertsService.showAlertNotification(
                "chrome://global/skin/icons/information-32.png", aTitle || "addMenu",
                aMsg + "", !!callback, "", callback);
        },
        edit: function (aFile, aLineNumber) {
            if (KeyChanger.isBuilding) return;
            if (!aFile || !aFile.exists() || !aFile.isFile()) return;
 
            var editor;
            try {
                editor = Services.prefs.getComplexValue("view_source.editor.path", Ci.nsIFile);
            } catch (e) {
            }
 
            if (!editor || !editor.exists()) {
                if (useScraptchpad) {
                    this.openScriptInScratchpad(window, aFile);
                    return;
                } else {
                    alert("请先设置编辑器的路径!!!");
                    var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
                    fp.init(window, "设置全局脚本编辑器", fp.modeOpen);
                    fp.appendFilter("执行文件", "*.exe");
                    if (fp.show() == fp.returnCancel || !fp.file)
                        return;
                    else {
                        editor = fp.file;
                        Services.prefs.setCharPref("view_source.editor.path", editor.path);
                    }
                }
            }
 
            // 调用自带的
            if(typeof(userChrome) == 'undefined') { 
                this.openScriptInScratchpad(window, aFile);
                return;
            } else {            
            var aURL = userChrome.getURLSpecFromFile(aFile);
            var aDocument = null;
            var aCallBack = null;
            var aPageDescriptor = null;
            gViewSourceUtils.openInExternalEditor({
                URL: aURL,
                lineNumber: aLineNumber
            }, aPageDescriptor, aDocument, aLineNumber, aCallBack); 
            }
 
        },
        openScriptInScratchpad: function (parentWindow, file) {
            let spWin = window.openDialog("chrome://devtools/content/scratchpad/index.xul", "Toolkit:Scratchpad", "chrome,resizable=yes,centerscreen,dependent");
 
            spWin.addEventListener("load", function spWinLoaded() {
                spWin.removeEventListener("load", spWinLoaded, false);
 
                let Scratchpad = spWin.Scratchpad;
                Scratchpad.setFilename(file.path);
                Scratchpad.addObserver({
                    onReady: function () {
                        Scratchpad.removeObserver(this);
                        Scratchpad.importFromFile.call(Scratchpad, file);
                    }
                });
            }, false);
        },
        exec: function (path, arg) {
            var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
            var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess);
            try {
                var a = (typeof arg == 'string' || arg instanceof String) ? arg.split(/\s+/) : [arg];
                file.initWithPath(path);
                process.init(file);
                process.run(false, a, a.length);
            } catch (e) {
                this.log(e);
            }
        },
        log: function () {
            Services.console.logStringMessage("[KeyChanger] " + Array.prototype.slice(arguments));
        },
    };
 
    window.KeyChanger.createMenuitem();
    window.KeyChanger.makeKeyset();
 
})();
2020-03-15 21:41
写私信
5楼#
kidzgy:关于KeyChanger,添加 keys['Alt+F'] = function () { BrowserSearch.webSearch(); };//光标跳至搜索栏在FF74无效,也根据你的方法修改了,同样无效。回到原帖
原因有二:
  1. 一楼我已经解释过了。
  2. 楼主给的脚本粘贴时出错,被本论坛的高亮功能加入或替换成了一些 html 代码,80 行和 300 行。
2020-03-15 22:40
写私信
6楼#
确实顶楼不知道怎么把i识别成斜体了  用rar重新打包了
2022-11-10 10:37
写私信
7楼#
UndoCloseTabBtn.uc.js 在107又不能用了,求修复。
www.helup.com
2023-06-07 16:37
写私信
9楼#
逗妇乳:https://github.com/benzBrake/FirefoxCustomize/blob/master/userChromeJS/UndoCloseTabButtonN.uc.js回到原帖
收到,确实可用。谢谢。
www.helup.com