1. Nachrichten
  2. Forum
    1. Unerledigte Themen
    2. Forenregeln
  3. Spenden
  • Anmelden
  • Registrieren
  • Suche
Alles
  • Alles
  • Artikel
  • Seiten
  • Forum
  • Erweiterte Suche
  1. camp-firefox.de
  2. jizz

Beiträge von jizz

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • jizz
    • 9. Juni 2025 um 14:00
    Zitat von Mira_Belle

    jizz Please complete your idea in a whole script.

    Because I can't really do much with the code snippet.

    JavaScript
    // ==UserScript==
    // @include       chrome://mozapps/content/downloads/unknownContentType.xhtml
    // @charset       UTF-8
    // @sandbox       true
    // @version       Fx139+
    // ==/UserScript==
    
    (function () {
    
        const { FileUtils } = ChromeUtils.importESModule('resource://gre/modules/FileUtils.sys.mjs');
        const { setTimeout } = ChromeUtils.importESModule('resource://gre/modules/Timer.sys.mjs');
    
        setTimeout(function () {
            saveTo()
        }, 200);
    
        function saveTo () {
            // config
            const dirArray = [
                ['C:\\', 'System'],
                ['D:\\', 'DATA'],
                ['D:\\Software', 'Software'],
                ['D:\\Downloads', 'herunterladen'],
                ['D:\\Video', 'Video'],
                ['' + FileUtils.getDir('UChrm', []).path + '', 'chrome'],
                //['' + FileUtils.getDir('UChrm', ['SubScript']).path + '', 'SubScript'],
    
                ['F:\\', 'F:'],
                ['G:\\', 'G:'],
                ['H:\\', 'H:'],
            ];
    
            const button = document.getElementById('unknownContentType').getButton('cancel');
            const saveTo = button.parentNode.insertBefore(createEl('button', {
                label: 'Speichern nach',
                class: 'dialog-button',
                type: 'menu'
            }), button);
            const saveToMenu = saveTo.appendChild(createEl('menupopup'));
            saveToMenu.appendChild(createEl("html:link", {
                rel: "stylesheet",
                href: "chrome://global/skin/global.css"
            }));
            saveToMenu.appendChild(createEl("html:link", {
                rel: "stylesheet",
                href: "chrome://global/content/elements/menupopup.css"
            }));
            dirArray.forEach(function (a) {
                const [dir, name] = [a[0], a[1]];
                saveToMenu.appendChild(createEl('menuitem', {
                    label: (name || (dir.match(/[^\\/]+$/) || [dir])[0]),
                    image: 'moz-icon:file:///' + dir + '\\',
                    class: 'menuitem-iconic',
                    dir: dir,
                    onclick: function () {
                        const locationtext = document.getElementById('locationtext');
                        const file = new FileUtils.File(this.getAttribute('dir') + '\\' + (locationtext ? locationtext.value : document.getElementById('location').value));
                        dialog.mLauncher.saveDestinationAvailable(file);
                        dialog.onCancel = function () { };
                        close();
    
                    }
                }));
            });
        }
    
        function createEl (type, attrs = {}, doc = document) {
            let el = type.startsWith('html:')
                ? doc.createElementNS('http://www.w3.org/1999/xhtml', type)
                : doc.createXULElement(type);
    
            for (let key of Object.keys(attrs)) {
                key.startsWith('on')
                    ? el.addEventListener(key.slice(2).toLocaleLowerCase(), attrs[key])
                    : el.setAttribute(key, attrs[key]);
            }
    
            return el;
        }
    }());
    Alles anzeigen
  • userChrome.js Scripte für den Fuchs (Diskussion)

    • jizz
    • 9. Juni 2025 um 11:24
    Zitat von Endor

    Hallo zusammen.
    Für das Script saveto.uc.js gibt es eine neue Version für Firefox 139
    Denkt daran eure Anpassungen - Änderungen zu übertragen.

    JavaScript
    // ==UserScript==
    // @include       chrome://mozapps/content/downloads/unknownContentType.xhtml
    // @charset       UTF-8
    // @sandbox       true
    // @version       Fx139+
    // ==/UserScript==
    
    (function() {
    
    	const {FileUtils} = ChromeUtils.importESModule('resource://gre/modules/FileUtils.sys.mjs');
    	const {setTimeout} = ChromeUtils.importESModule('resource://gre/modules/Timer.sys.mjs');
    
    	const css = `
    		hbox.dialog-button-box button.dialog-button menupopup {
    			background: #F0F0F0 !important;
    			border: 1px solid #CCCCCC !important;
    			padding: 2px !important;
    		}
    		hbox.dialog-button-box button.dialog-button menupopup menuitem.menuitem-iconic:hover {
    			background: #91C9F7 !important;
    		}
    		hbox.dialog-button-box button.dialog-button menupopup menuitem.menuitem-iconic hbox.menu-iconic {
    			padding: 3px !important;
    		}
    		hbox.dialog-button-box button.dialog-button menupopup menuitem.menuitem-iconic label.menu-iconic-text{
    			padding: 3px !important;
    			padding-left: 5px !important;
    			padding-right: 12px !important;
    		}`;
    	const sss = Cc['@mozilla.org/content/style-sheet-service;1'].getService(Ci.nsIStyleSheetService);
    	try {
    		const uri = Services.io.newURI('data:text/css,' + encodeURIComponent(css));
    		if(!sss.sheetRegistered(uri, sss.AGENT_SHEET))
    		sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET);
    	} catch (ex) {}
    	
    	setTimeout(function() {
    		saveTo()
    	}, 200);
    
    	function saveTo() {
    		// config
    		const dirArray = [
    			['C:\\', 'System'],
    			['D:\\', 'DATA'],
    			['D:\\Software', 'Software'],
    			['D:\\Downloads', 'herunterladen'],
    			['D:\\Video', 'Video'],
    			['' + FileUtils.getDir('UChrm', []).path + '', 'chrome'],
    			//['' + FileUtils.getDir('UChrm', ['SubScript']).path + '', 'SubScript'],
    
    			['F:\\', 'F:'],
    			['G:\\', 'G:'],
    			['H:\\', 'H:'],
    		];
    
    		const button = document.getElementById('unknownContentType').getButton('cancel');
    		const saveTo = button.parentNode.insertBefore(document.createXULElement('button'), button);
    		const saveToMenu = saveTo.appendChild(document.createXULElement('menupopup'));
    		saveTo.classList.toggle('dialog-button');
    		saveTo.label = 'Speichern nach';
    		saveTo.type = 'menu';
    		dirArray.forEach(function(dir) {
    			const name = dir[1];
    			dir = dir[0];
    			const mi = document.createXULElement('menuitem');
    			const item = saveToMenu.appendChild(mi);
    			item.setAttribute('label', (name || (dir.match(/[^\\/]+$/) || [dir])[0]));
    			item.setAttribute('image', 'moz-icon:file:///' + dir + '\\');
    			item.setAttribute('class', 'menuitem-iconic');
    			item.addEventListener('click', function() {
    				const locationtext = document.getElementById('locationtext');
    				const file = new FileUtils.File(dir + '\\' + (locationtext ? locationtext.value : document.getElementById('location').value));
    				dialog.mLauncher.saveDestinationAvailable(file);
    				dialog.onCancel = function() {};
    				close();
    			});
    		});
    	}
    }());
    Alles anzeigen

    Diese Version ist nun auch bei Github zu finden:
    https://github.com/Endor8/userChr…39/saveto.uc.js
    Mfg.
    Endor

    Zitat von bege
    Zitat von grisu2099

    Füge mal den folgenden Schnipsel zusätzlich in den CSS-Teil des Skriptes ein und teste:

    CSS
    hbox.dialog-button-box button.dialog-button menupopup menuitem:not([highlightable]) > .menu-highlightable-text,
    			menuitem[highlightable] > .menu-text {
    				display: none;
    			}

    👍Super, danke.

    Hast du eine Idee, warum auch das alte Skript plötzlich dieses Verhalten zeigt?

    It is more appropriate to use the CSS built into Firefox.

    JavaScript
    const saveToMenu = saveTo.appendChild(document.createXULElement('menupopup'));
    const link1 = document.createElementNS("http://www.w3.org/1999/xhtml", "html:link");
    link1.rel = "stylesheet";
    link1.href = "chrome://global/skin/global.css";
    saveToMenu.appendChild(link1);
    const link2 = document.createElementNS("http://www.w3.org/1999/xhtml", "html:link");
    link2.rel = "stylesheet";
    link2.href = "chrome://global/content/elements/menupopup.css";
    saveToMenu.appendChild(link2);
  • Seit FF139 geht das script nicht mehr: allow_search_oneoff_with_empty_text.uc.js

    • jizz
    • 6. Juni 2025 um 16:33
    Zitat von Mira_Belle

    Thanks jizz .
    Here's the original script.

    But with which loader should it work?

    GitHub - alice0775/userChrome.js
    Contribute to alice0775/userChrome.js development by creating an account on GitHub.
    github.com

    userchrome.jsのインストール方法 方法 その1:

  • Seit FF139 geht das script nicht mehr: allow_search_oneoff_with_empty_text.uc.js

    • jizz
    • 6. Juni 2025 um 09:44

    This script works fine with the original author's loader; the issue should be with your loader not supporting the @sandobx annotation.

  • AddBookmark here Script arbeitet nicht in Nightly

    • jizz
    • 5. April 2025 um 14:59
    Code
    // ==UserScript==
    // @name            Add Bookmark Here
    // @namespace       about:userchromejs/addbookmarkhere
    // @description     add "Add Bookmark Here" contextmenu in places menu
    // @include         chrome://browser/content/browser.xhtml
    // @include         chrome://browser/content/places/places.xhtml
    // @shutdown        window.AddBookmarkHere.uninit()
    // @author          Ryan, zbinlin
    // @homepage        http://mozcp.com
    // @version         0.0.3
    // ==/UserScript==
    
    /**
     * ******************************** Changelog ********************************
     * version: 0.0.3
     *  * Kompatibilitäts - Probleme mit neueren Firefox-Versionen behoben.
     *  * Achtung: nur in Firefox 100 getestet!
     * version: 0.0.2
     *  * Kompatibel mit Firefox 21+
     *
     * version: 0.0.1
     *  * Initialisierung
     * ***************************************************************************
     */
    
    "use strict";
    
    (function () {
        if (window.AddBookmarkHere) return;
        var AddBookmarkHere = {
            PARENT_NODE: "placesContext",
            REF_NODE: "",
            init: function () {
                var parentNode = document.getElementById(this.PARENT_NODE);
                if (!parentNode) return;
                var self = this;
                window.addEventListener("unload", function _ (e) {
                    window.removeEventListener("unload", _, false);
                    self.uninit();
                }, false);
                var refNode;
                if (this.REF_NODE !== "") {
                    var refNode = document.getElementById(this.REF_NODE);
                }
                this.addContextMenu(parentNode, refNode);
                /*
                var node = document.getElementById("placesContext_createBookmark");
                if (!node) return;
                node.removeAttribute("forcehideselection");
                node.setAttribute("selection", "any"); 
                node.removeAttribute("command");
                node.setAttribute("oncommand", "AddBookmarkHere.addBookmark(event);");
                */
            },
            addContextMenu: function (parentNode, afterNode) {
                var menuitem = document.createXULElement("menuitem");
                menuitem.id = "placesContext_add:bookmark";
                menuitem.setAttribute("label", Services.locale.appLocaleAsBCP47.includes("de") ? "Lesezeichen hier hinzufügen" : "Add Bookmark Here");
                menuitem.setAttribute("accesskey", "h");
                menuitem.setAttribute("selection", "any");
                menuitem.setAttribute("class", "menuitem-iconic");
                menuitem.setAttribute("style", "list-style-image: url(data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIHZpZXdCb3g9IjAgMCAxNiAxNiIgZmlsbD0iY29udGV4dC1maWxsIiBmaWxsLW9wYWNpdHk9ImNvbnRleHQtZmlsbC1vcGFjaXR5IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgo8cGF0aCBkPSJNOC44MDgwMiAyLjEwMTc5QzguNDc3ODkgMS40MzI4NyA3LjUyNDAzIDEuNDMyODcgNy4xOTM5IDIuMTAxNzlMNS42NzI4MSA1LjE4Mzg0TDIuMjcxNTYgNS42NzgwN0MxLjUzMzM2IDUuNzg1MzQgMS4yMzg2MSA2LjY5MjUxIDEuNzcyNzcgNy4yMTMyTDQuMjMzOTQgOS42MTIyNEwzLjY1Mjk0IDEyLjk5OTdDMy41MjY4NCAxMy43MzUgNC4yOTg1MyAxNC4yOTU2IDQuOTU4NzkgMTMuOTQ4NUw4LjAwMDk2IDEyLjM0OTFMOC40ODI5IDEyLjYwMjVDOC4xODU5NyAxMi4zMjg0IDggMTEuOTM1OSA4IDExLjVDOCAxMS40NDQ2IDguMDAzIDExLjM5IDguMDA4ODQgMTEuMzM2MkM3Ljg2MjM2IDExLjMzNDkgNy43MTU2NCAxMS4zNjk0IDcuNTgyMTUgMTEuNDM5NUw0LjY3MjggMTIuOTY5MUw1LjIyODQzIDkuNzI5NDdDNS4yNzg1MSA5LjQzNzUxIDUuMTgxNzEgOS4xMzk2MSA0Ljk2OTYgOC45MzI4NUwyLjYxNTg4IDYuNjM4NTRMNS44Njg2NCA2LjE2NTg5QzYuMTYxNzggNi4xMjMyOSA2LjQxNTE5IDUuOTM5MTggNi41NDYyOCA1LjY3MzU1TDguMDAwOTYgMi43MjYwNUw4LjczMzUxIDQuMjEwMzZDOC45NTc4MiA0LjA3Njc1IDkuMjE5OTUgNCA5LjUgNEg5Ljc0NDg1TDguODA4MDIgMi4xMDE3OVpNOS41IDVDOS4yMjM4NiA1IDkgNS4yMjM4NiA5IDUuNUM5IDUuNzc2MTQgOS4yMjM4NiA2IDkuNSA2SDE0LjVDMTQuNzc2MSA2IDE1IDUuNzc2MTQgMTUgNS41QzE1IDUuMjIzODYgMTQuNzc2MSA1IDE0LjUgNUg5LjVaTTkuNSA4QzkuMjIzODYgOCA5IDguMjIzODYgOSA4LjVDOSA4Ljc3NjE0IDkuMjIzODYgOSA5LjUgOUgxNC41QzE0Ljc3NjEgOSAxNSA4Ljc3NjE0IDE1IDguNUMxNSA4LjIyMzg2IDE0Ljc3NjEgOCAxNC41IDhIOS41Wk05LjUgMTFDOS4yMjM4NiAxMSA5IDExLjIyMzkgOSAxMS41QzkgMTEuNzc2MSA5LjIyMzg2IDEyIDkuNSAxMkgxNC41QzE0Ljc3NjEgMTIgMTUgMTEuNzc2MSAxNSAxMS41QzE1IDExLjIyMzkgMTQuNzc2MSAxMSAxNC41IDExSDkuNVoiLz4KPC9zdmc+Cg==)");
                menuitem.addEventListener("command", this, false);
                if (typeof refNode !== "undefined") {
                    parentNode.insertBefore(menuitem, afterNode);
                } else {
                    parentNode.appendChild(menuitem);
                }
            },
            handleEvent: function (e) {
                var popupNode = e.currentTarget.parentNode.triggerNode;
                if (!popupNode) return;
                var view = PlacesUIUtils.getViewForNode(popupNode);
                if (!view) return;
                var bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].getService(Ci.nsINavBookmarksService);
                var selectedNode = view.selectedNode;
                var iid, aid;
                if (selectedNode) {
                    if (PlacesUtils.nodeIsFolderOrShortcut(selectedNode)/* Bug 1904909 PlacesUtils.nodeIsFolder(selectedNode) /* Firefox 21+ inkompatibel && !PlacesUtils.nodeIsLivemarkContainer(selectedNode) && !PlacesUtils.isReadonlyFolder(selectedNode) */) {
                        iid = selectedNode.itemId;
                        aid = e.shiftKey ? 0 : bookmarks.DEFAULT_INDEX;
                    } else {
                        iid = bookmarks.getFolderIdForItem(selectedNode.itemId);
                        var id = bookmarks.getItemIndex(selectedNode.itemId);
                        aid = e.shiftKey ? id : id + 1;
                    }
                } else {
                    iid = view.result.root.folderItemId;
                    aid = e.shiftKey ? 0 : bookmarks.DEFAULT_INDEX;
                };
                var uri = Services.io.newURI(gBrowser.currentURI.spec, null, null);
                var title = gBrowser.contentTitle
                bookmarks.insertBookmark(iid, uri, aid, title);
            },
            uninit: function () {
                var self = this;
                try {
                    var menuitem = document.getElementById("placesContext_add:bookmark");
                    menuitem.removeEventListener("command", self, false);
                    menuitem.remove();
                    delete window.AddBookmarkHere;
                } catch (ex) {
                }
            }
        };
        AddBookmarkHere.init();
        window.AddBookmarkHere = AddBookmarkHere;
    })();
    Alles anzeigen

    This script is not maintained for a long time, but it is recommended for use https://github.com/benzBrake/Fire…okmarkOpt.uc.js

  • Automatischer Screenshot

    • jizz
    • 14. Juni 2024 um 12:00
    Zitat von Endor

    Vielleicht hilft uns ja jizz .
    Please jizz can you help us fixing this Script?

    Beitrag

    Automatischer Screenshot

    Hallo zusammen,

    ich verwende folgendes Script, um Screenshots mit einem Klick zu erstellen:

    (Quelltext, 55 Zeilen)

    Leider funktioniert die Automatik seit heute mit FF 127 nicht mehr. Vielleicht kann mir wieder geholfen werden.

    Im Voraus schon vielen Dank.
    geldhuegel
    12. Juni 2024 um 02:11

    Thank You.

    Mfg.
    Endor

    Maybe it needs to be modified, you know, I use alice0775's loader

    FirefoxCustomize/userChromeJS/127/AutoSaveScreenshot.uc.js at master · benzBrake/FirefoxCustomize
    Ryan 收集的 Firefox 个性化相关资源. Contribute to benzBrake/FirefoxCustomize development by creating an account on GitHub.
    github.com
  • userChrome.js Scripte für den Fuchs (Diskussion)

    • jizz
    • 8. Mai 2024 um 03:50
    Zitat von pleassssse

    firefox126hint: TypeError : reloadTab.getAttribute(...) is null

    Please help me fix it

        location.href.startsWith('chrome://browser/content/browser.x') && (() => {
           const reloadTab = document.getElementById('context_reloadTab');
           if(!reloadTab) return;
           const menuitem = document.createXULElement('menuitem');
           menuitem.setAttribute('accesskey', 'A');
           menuitem.setAttribute('label', reloadTab.getAttribute('label')
               .startsWith('Reload') ? 'Reload All Tabs' : '刷新所有标签页'
           );
           menuitem.addEventListener('command', () => {
               gBrowser.visibleTabs.forEach(tab => {
                   try {
                       gBrowser.getBrowserForTab(tab).reload();
                   } catch (e) {}
               });
           });
           reloadTab.after(menuitem);
       })();

    Alles anzeigen
    Code
    location.href.startsWith('chrome://browser/content/browser.x') && (() => {
        document.getElementById('tabContextMenu').addEventListener('popupshowing', function () {
            const reloadTab = document.getElementById('context_reloadTab');
            if (!reloadTab) return;
            const menuitem = document.createXULElement('menuitem');
            menuitem.setAttribute('accesskey', 'A');
            menuitem.setAttribute('label', reloadTab.getAttribute('label')
                .startsWith('Reload') ? 'Reload All Tabs' : '刷新所有标签页'
            );
            menuitem.addEventListener('command', () => {
                gBrowser.visibleTabs.forEach(tab => {
                    try {
                        gBrowser.getBrowserForTab(tab).reload();
                    } catch (e) { }
                });
            });
            reloadTab.after(menuitem);
        }, { once: true })
    })();
    Alles anzeigen
  • userChrome.js Scripte für den Fuchs (Diskussion)

    • jizz
    • 28. April 2024 um 17:34

    It was my fault. Using gBrowser.reload() / gBrower.stop() / gBrowser.reloadWithFlags(Ci.nsIWebNavigation.LOAD_FLAGS_BYPASS_CACHE) to be compatible with firefox57+

  • userChrome.js Scripte für den Fuchs (Diskussion)

    • jizz
    • 28. April 2024 um 13:15
    Zitat von Endor

    Hallo zusammen.
    Habe hier ein Script, welches die Neuladen Schaltfläche in die Adressleiste verschiebt.
    Bei Linksklick wird der Tab neu geladen, bei Rechtsklick wird der Tab neu geladen ohne
    den Cache zu berücksichtigen. Habe einige Anpassungen wie weiter oben erwähnt gemacht,
    aber bei klick tut sich nichts. Habt Ihr eine Idee?
    Hier das Script:

    JavaScript
    // ==UserScript==
    // @name           moveReloadIntoUrl.uc.js
    // @description    Neuladen Schaltfläche in Adressleiste verschieben
    // @compatibility  Firefox 103+
    // @author         Ryan, GOLF-AT
    // @include        main
    // @shutdown       window.moveReloadIntoURL.unload();
    // @homepageURL    https://github.com/benzBrake/FirefoxCustomize
    // @version        1.2.3
    // @note           1.2.3 Änderung wird in neuen Fenstern nicht wirksam und kann 
    // @note                 nicht verwendet werden, wenn Hot-Swapping stattfindet.
    // @note           1.2.2 Kompatibilität angepasst für Firefox 103
    // @note           1.2.0 Hot-Swap-fähig, kompatibel mit Nachtmodus 
    // @note                 und Bilder wurden ins Script integriert
    // @note           1.1 20220424 Fehler behoben, und Firefox 100 Kompatibel
    // @note           1.0 20171104
    // ==/UserScript==
    (function () {
      let { classes: Cc, interfaces: Ci, utils: Cu, results: Cr } = Components;
       const CustomizableUI = globalThis.CustomizableUI || Cu.import("resource:///modules/CustomizableUI.jsm").CustomizableUI;
        const Services = globalThis.Services || Cu.import("resource://gre/modules/Services.jsm").Services; 
    
        if (window.moveReloadIntoURL) {
            window.moveReloadIntoURL.unload();
            delete window.moveReloadIntoURL;
        }
    
        window.moveReloadIntoURL = {
            handleEvent: function (aEvent) {
                if (aEvent.type === "MoveReloadIntoUrlUnload") {
                    let win = aEvent.originalTarget,
                        doc = win.document;
                    let RELOADBTN = CustomizableUI.getWidget("reload-button").forWindow(win).node;
                    if (RELOADBTN)
                        RELOADBTN.removeEventListener('DOMAttrModified', this.reloadBtnAttr);
                    let BTN = doc.getElementById("new-stop-reload-button");
                    if (BTN)
                        BTN.parentNode.removeChild(BTN);
                    if (this.STYLE) {
                        this.sss.unregisterSheet(this.STYLE.url, this.STYLE.type);
                    }
                    win.removeEventListener('MoveReloadIntoUrlUnload', this);
                    if (win.moveReloadIntoURL)
                        delete win.moveReloadIntoURL;
                }
            },
            init: function (doc, win) {
                if (win.moveReloadIntoURL) {
                    this.sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService);
                    this.STYLE = {
                        url: Services.io.newURI('data:text/css;charset=UTF-8,' + encodeURIComponent(`
                    @-moz-document url('chrome://browser/content/browser.xhtml') {
                        #stop-reload-button {
                            display: none !important;
                        }
                        #new-stop-reload-button {
                            order: 999;
                        }
                    }
                  `)),
                        type: this.sss.AGENT_SHEET
                    };
                    this.sss.loadAndRegisterSheet(this.STYLE.url, this.STYLE.type);
                }
                let PABTN = CustomizableUI.getWidget("pageActionButton").forWindow(win).node;
                let RELOADBTN = CustomizableUI.getWidget("reload-button").forWindow(win).node;
                let BTN = $C(doc, 'hbox', {
                    id: "new-stop-reload-button",
                    class: "urlbar-page-action urlbar-addon-page-action",
                    "tooltiptext": Services.locale.appLocaleAsBCP47.includes("de") ? 'Linksklick: Seite neuladen\r\nRechtsklick: Neu laden erzwingen' : 'Left click: refresh page\nRight click: force refresh page',
                    style: "list-style-image: url('data:image/svg+xml;base64,PCEtLSBUaGlzIFNvdXJjZSBDb2RlIEZvcm0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhlIE1vemlsbGEgUHVibGljCiAgIC0gTGljZW5zZSwgdi4gMi4wLiBJZiBhIGNvcHkgb2YgdGhlIE1QTCB3YXMgbm90IGRpc3RyaWJ1dGVkIHdpdGggdGhpcwogICAtIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uIC0tPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDE2IDE2IiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9ImNvbnRleHQtZmlsbCIgZmlsbC1vcGFjaXR5PSJjb250ZXh0LWZpbGwtb3BhY2l0eSI+CiAgPHBhdGggZD0iTTEwLjcwNyA2IDE0LjcgNmwuMy0uMyAwLTMuOTkzYS41LjUgMCAwIDAtLjg1NC0uMzU0bC0xLjQ1OSAxLjQ1OUE2Ljk1IDYuOTUgMCAwIDAgOCAxQzQuMTQxIDEgMSA0LjE0MSAxIDhzMy4xNDEgNyA3IDdhNi45NyA2Ljk3IDAgMCAwIDYuOTY4LTYuMzIyLjYyNi42MjYgMCAwIDAtLjU2Mi0uNjgyLjYzNS42MzUgMCAwIDAtLjY4Mi41NjJBNS43MjYgNS43MjYgMCAwIDEgOCAxMy43NWMtMy4xNzEgMC01Ljc1LTIuNTc5LTUuNzUtNS43NVM0LjgyOSAyLjI1IDggMi4yNWE1LjcxIDUuNzEgMCAwIDEgMy44MDUgMS40NDVsLTEuNDUxIDEuNDUxYS41LjUgMCAwIDAgLjM1My44NTR6Ii8+Cjwvc3ZnPgo=",
                    onclick: function (e) {
                        let r = CustomizableUI.getWidget("reload-button").forWindow(window).node;
                        if (r && r.getAttribute('displaystop'))
                            e.target.ownerGlobal.BrowserCommands.Stop();
                        else
                            if (e.button == 2) {
                                e.target.ownerGlobal.BrowserCommands.ReloadSkipCache();
                            } else {
                                if (gBrowser.selectedBrowser._userTypedValue) {
                                    e.target.ownerGlobal.openTrustedLinkIn(gBrowser.selectedBrowser._userTypedValue, 'current', {
                                        postData: null,
                                        triggeringPrincipal: gBrowser.selectedBrowser.contentPrincipal
                                    });
                                } else {
                                    e.target.ownerGlobal.BrowserCommands.Reload();
                                }
                            }
                    }
                })
    
                BTN.appendChild($C(doc, 'image', {
                    class: 'urlbar-icon',
                }));
    
                PABTN.after(BTN);
                RELOADBTN.addEventListener('DOMAttrModified', this.reloadBtnAttr);
                this.reloadBtnAttr();
    
                win.addEventListener('MoveReloadIntoUrlUnload', this)
            },
            unload: function () {
                let windows = Services.wm.getEnumerator('navigator:browser');
                while (windows.hasMoreElements()) {
                    let win = windows.getNext();
                    win.dispatchEvent(new CustomEvent("MoveReloadIntoUrlUnload"));
                }
            },
            reloadBtnAttr: function (e) {
                let doc = e ? e.target.ownerDocument : document;
                btn = doc.getElementById('new-stop-reload-button');
                if (btn && (!e || e.attrName == 'displaystop')) {
                    var newVal = e ? e.newValue : doc.getElementById(
                        "reload-button").getAttribute('displaystop');
                    if (newVal)
                        btn.style.listStyleImage = "url('data:image/svg+xml;base64,PCEtLSBUaGlzIFNvdXJjZSBDb2RlIEZvcm0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhlIE1vemlsbGEgUHVibGljCiAgIC0gTGljZW5zZSwgdi4gMi4wLiBJZiBhIGNvcHkgb2YgdGhlIE1QTCB3YXMgbm90IGRpc3RyaWJ1dGVkIHdpdGggdGhpcwogICAtIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uIC0tPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDE2IDE2IiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9ImNvbnRleHQtZmlsbCIgZmlsbC1vcGFjaXR5PSJjb250ZXh0LWZpbGwtb3BhY2l0eSI+CiAgPHBhdGggZD0ibTkuMTA4IDcuNzc2IDQuNzA5LTQuNzA5YS42MjYuNjI2IDAgMCAwLS44ODQtLjg4NUw4LjI0NCA2Ljg3MWwtLjQ4OCAwLTQuNjg5LTQuNjg4YS42MjUuNjI1IDAgMSAwLS44ODQuODg1TDYuODcgNy43NTRsMCAuNDkxLTQuNjg3IDQuNjg3YS42MjYuNjI2IDAgMCAwIC44ODQuODg1TDcuNzU0IDkuMTNsLjQ5MSAwIDQuNjg3IDQuNjg3YS42MjcuNjI3IDAgMCAwIC44ODUgMCAuNjI2LjYyNiAwIDAgMCAwLS44ODVMOS4xMDggOC4yMjNsMC0uNDQ3eiIvPgo8L3N2Zz4K')";
                    else
                        btn.style.listStyleImage = "url('data:image/svg+xml;base64,PCEtLSBUaGlzIFNvdXJjZSBDb2RlIEZvcm0gaXMgc3ViamVjdCB0byB0aGUgdGVybXMgb2YgdGhlIE1vemlsbGEgUHVibGljCiAgIC0gTGljZW5zZSwgdi4gMi4wLiBJZiBhIGNvcHkgb2YgdGhlIE1QTCB3YXMgbm90IGRpc3RyaWJ1dGVkIHdpdGggdGhpcwogICAtIGZpbGUsIFlvdSBjYW4gb2J0YWluIG9uZSBhdCBodHRwOi8vbW96aWxsYS5vcmcvTVBMLzIuMC8uIC0tPgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgdmlld0JveD0iMCAwIDE2IDE2IiB3aWR0aD0iMTYiIGhlaWdodD0iMTYiIGZpbGw9ImNvbnRleHQtZmlsbCIgZmlsbC1vcGFjaXR5PSJjb250ZXh0LWZpbGwtb3BhY2l0eSI+CiAgPHBhdGggZD0iTTEwLjcwNyA2IDE0LjcgNmwuMy0uMyAwLTMuOTkzYS41LjUgMCAwIDAtLjg1NC0uMzU0bC0xLjQ1OSAxLjQ1OUE2Ljk1IDYuOTUgMCAwIDAgOCAxQzQuMTQxIDEgMSA0LjE0MSAxIDhzMy4xNDEgNyA3IDdhNi45NyA2Ljk3IDAgMCAwIDYuOTY4LTYuMzIyLjYyNi42MjYgMCAwIDAtLjU2Mi0uNjgyLjYzNS42MzUgMCAwIDAtLjY4Mi41NjJBNS43MjYgNS43MjYgMCAwIDEgOCAxMy43NWMtMy4xNzEgMC01Ljc1LTIuNTc5LTUuNzUtNS43NVM0LjgyOSAyLjI1IDggMi4yNWE1LjcxIDUuNzEgMCAwIDEgMy44MDUgMS40NDVsLTEuNDUxIDEuNDUxYS41LjUgMCAwIDAgLjM1My44NTR6Ii8+Cjwvc3ZnPgo=')";
                }
            },
        }
    
        function $C(aDoc, tag, attrs, skipAttrs) {
            attrs = attrs || {};
            skipAttrs = skipAttrs || [];
            var el = (aDoc || document).createXULElement(tag);
            return $A(el, attrs, skipAttrs);
        }
    
        function $A(el, obj, skipAttrs) {
            skipAttrs = skipAttrs || [];
            if (obj) Object.keys(obj).forEach(function (key) {
                if (!skipAttrs.includes(key)) {
                    if (typeof obj[key] === 'function') {
                        el.setAttribute(key, "(" + obj[key].toString() + ").call(this, event);");
                    } else {
                        el.setAttribute(key, obj[key]);
                    }
                }
            });
            return el;
        }
    
        if (gBrowserInit.delayedStartupFinished) window.moveReloadIntoURL.init(document, window)
        else {
            let delayedListener = (subject, topic) => {
                if (topic == "browser-delayed-startup-finished" && subject == window) {
                    Services.obs.removeObserver(delayedListener, topic);
                    window.moveReloadIntoURL.init(subject.document, subject);
                }
            };
            Services.obs.addObserver(delayedListener, "browser-delayed-startup-finished");
        }
    })();
    Alles anzeigen

    Konsole sagt folgendes:

    Code
    Uncaught ReferenceError: gBrowserInit is not defined
        <anonymous> file:///C:/Users/xxxx/AppData/Roaming/Mozilla/Firefox/Profiles/6ha62y8g/chrome/move_reload_into_url.uc.js:142
        <anonymous> file:///C:/Users/xxxx/AppData/Roaming/Mozilla/Firefox/Profiles/6ha62y8g/chrome/move_reload_into_url.uc.js:152
        loadScript file:///C:/Program Files/Mozilla Firefox/userChromeJS/utilities.js:114
    move_reload_into_url.uc.js:142:9
        <anonym> file:///C:/Users/xxxx/AppData/Roaming/Mozilla/Firefox/Profiles/6ha62y8g/chrome/move_reload_into_url.uc.js:142
        <anonym> file:///C:/Users/xxxx/AppData/Roaming/Mozilla/Firefox/Profiles/6ha62y8g/chrome/move_reload_into_url.uc.js:152
        loadScript file:///C:/Program Files/Mozilla Firefox/userChromeJS/utilities.js:114

    Zeile 142:
    if (gBrowserInit.delayedStartupFinished) window.moveReloadIntoURL.init(document, window)

    Zeile 152:
    })();

    Mfg.
    Endor

    Alles anzeigen
    FirefoxCustomize/userChromeJS/moveReloadIntoUrl.uc.js at master · benzBrake/FirefoxCustomize
    Ryan 收集的 Firefox 个性化相关资源. Contribute to benzBrake/FirefoxCustomize development by creating an account on GitHub.
    github.com

    I updated the script, but my script was only tested using alice0775's uc loader. If not work, you have to import PlacesUIUtils yourself

  • Firefox Portable

    • jizz
    • 21. November 2023 um 13:17

    Try this fake portable loader: https://github.com/benzBrake/RunFirefox

  • Das Script "RevertAddonBarStatusBar.uc.js" funktioniert nicht mehr

    • jizz
    • 24. Februar 2023 um 14:59

    FirefoxCustomize/StatusBar.uc.js at master · benzBrake/FirefoxCustomize
    Ryan 收集的 Firefox 个性化相关资源. Contribute to benzBrake/FirefoxCustomize development by creating an account on GitHub.
    github.com
  • userChrome.js Scripte für den Fuchs (Diskussion)

    • jizz
    • 5. Dezember 2022 um 12:11
    Zitat von Doesbaddel

    那是启动时,第一次点击:

    JavaScript
    (function () {
      if (location.href !== 'chrome://browser/content/browser.xhtml') 
      return;
       setTimeout(() => {
         const orig = document.getElementById('saveforreadlater_gmail_com-menuitem-_saveIt');
        const ref = document.getElementById('context-take-screenshot');
        contentAreaContextMenu.insertBefore(orig, ref.nextSibling);
                          }, 20000);
                  }
    )
    ();
    Alles anzeigen

    其子菜单中-Original后两个Element个的或要求的功能的Dropdowns的项目出现了位移。

    那是基本菜单的因素是延期还是存在,但是更多。

    因此,我的简单的因素就移。这个还不够。"难道(还有的部件clonen,它的功能形象,没有不和谐)(那是极度长的时间,然后超过)

    因此我首先感谢就在帮忙。

    JavaScript
    (function () {
        if (location.href !== 'chrome://browser/content/browser.xhtml')
            return;
    
        const ref = document.getElementById('context-take-screenshot');
        if (ref) {
            ref.after($C('menuitem', {
                label: "Save all pages for read them later",
                oncommand: 'event.target.parentNode.querySelector("#saveforreadlater_gmail_com-menuitem - _saveItAll").click(event);'
            }));
            ref.after($C('menuitem', {
                label: "Save this page for Read Later",
                oncommand: 'event.target.parentNode.querySelector("#saveforreadlater_gmail_com-menuitem-_saveIt").click(event);'
            }));
        }
        var style = "data:text/css;charset=utf-8," + encodeURIComponent(`
            #contentAreaContextMenu [id^="saveforreadlater_gmail_com-menuitem"] {
                display: none;
            }
        `);
    
        windowUtils.loadSheetUsingURIString(style, windowUtils.AUTHOR_SHEET);
    
        function $C(tag, attrs) {
            var el;
            if (!tag) return el;
            attrs = attrs || {};
            el = document.createXULElement(tag);
            if (attrs) Object.keys(attrs).forEach(function (key) {
                el.setAttribute(key, attrs[key]);
            });
            return el;
        }
    })()
    Alles anzeigen
  • DeepL Script

    • jizz
    • 12. November 2022 um 02:04
    Zitat von Mira_Belle
    Zitat von jizz

    Here's a powerful version

    Dieses JavaScript ist ja sehr nett, aber um eine kostenlosen "API key" zu bekommen

    müssen die Bankdaten angegeben werden!


    Das ist nicht wirklich prickelnd und ich bekomme da "Bauchweh"!

    Geht es auch irgendwie ohne?

    Und wer diese Japanische Schriftzeichen ändern möchte,

    Zeile 83

    menuItem.label = "Auswahl mit DeepL übersetzen";

    und

    Zeile 192

    logo.textContent = "DeepL Übersetzer";

    Wie ein Icon vor den Text des Menüs "gezaubert" wird, muss ich erst noch testen.

    Macht nur im Moment keinen Sinn, da ohne API-Key das Script nicht funktioniert.

    Und hier noch ein Mal der Code des JavaScripts im Original,

    da bei mir die Seite schon einige Male nicht geladen wurde

    JavaScript
    // ==UserScript==
    // @name           DeepL Translator
    // @include        main
    // @compatibility  Firefox 78+
    // @description    コンテクストメニューに選択テキストをDeepLで翻訳する機能を追加する
    // @note           DeepLのAPIキー (無料版で可) が必要
    // @charset        UTF-8
    // ==/UserScript==
    "use strict";
    if (typeof window === "undefined" || globalThis !== window) {
    /* --- 設定ここから --- */
    const apiKey = "Enter your API key here!";
    const apiEndpoint = "https://api-free.deepl.com/v2";
    const hotkey = {
    enabled: false,
    code:    "ControlLeft",
    repeat:  2,
    timeout: 500,
    };
    const defaultLang = "JA";
    const supportedLangs = {
    //"BG": "Bulgarian",
    //"CS": "Czech",
    //"DA": "Danish",
    "DE": "German",
    //"EL": "Greek",
    //"EN-GB": "English (British)",
    "EN-US": "English (American)",
    "ES": "Spanish",
    //"ET": "Estonian",
    //"FI": "Finnish",
    "FR": "French",
    //"HU": "Hungarian",
    "IT": "Italian",
    "JA": "Japanese",
    //"LT": "Lithuanian",
    //"LV": "Latvian",
    //"NL": "Dutch",
    //"PL": "Polish",
    //"PT-PT": "Portuguese",
    //"PT-BR": "Portuguese (Brazilian)",
    //"RO": "Romanian",
    //"RU": "Russian",
    //"SK": "Slovak",
    //"SL": "Slovenian",
    //"SV": "Swedish",
    //"ZH": "Chinese",
    };
    /* --- 設定ここまで --- */
    const {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
    ChromeUtils.defineModuleGetter(this, "ContentDOMReference", "resource://gre/modules/ContentDOMReference.jsm");
    ChromeUtils.defineModuleGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");
    if (!Services.appinfo.remoteType) {
    this.EXPORTED_SYMBOLS = ["DLTranslator", "DLTranslatorParent"];
    try {
    const actorParams = {
    parent: {
    moduleURI: __URI__,
    },
    child: {
    moduleURI: __URI__,
    events: {},
    },
    allFrames: true,
    messageManagerGroups: ["browsers"],
    matches: [`*://*/*`],
    };
    if (hotkey.enabled) {
    if (hotkey.repeat <= 0) hotkey.repeat = 2;
    if (hotkey.timeout <= 0) hotkey.timeout = 500;
    actorParams.child.events.keyup = {};
    }
    ChromeUtils.registerWindowActor("DLTranslator", actorParams);
    } catch(e) {Cu.reportError(e);}
    this.DLTranslator = new class {
    attachToWindow(win) {
    let menuPopup = win.document.getElementById("contentAreaContextMenu");
    let menuItem = win.document.createXULElement("menuitem");
    menuItem.label = "選択テキストを DeepL で翻訳";
    menuItem.id = "menu-deepl-translate";
    menuItem.addEventListener("command", this);
    menuPopup.appendChild(menuItem);
    menuPopup.addEventListener("popupshowing", this);
    win.addEventListener("unload", this, {once:true});
    }
    detachFromWindow(win) {
    win.removeEventListener("unload", this, {once:true}); // this might be unnecessary, but do anyway
    const menu = win.document.getElementById("menu-deepl-translate");
    menu.parentNode.removeEventListener("popupshowing", this);
    menu.parentNode.removeChild(menu);
    }
    handleEvent({type, target}) {
    switch(type) {
    case "popupshowing":
    this.handlePopup(target.ownerGlobal);
    break;
    case "command":
    this.beginTranslate(target.ownerGlobal.gContextMenu?.contentData);
    break;
    case "unload":
    this.detachFromWindow(target.ownerGlobal);
    break;
    }
    }
    handlePopup(win) {
    let selectionText = win.gContextMenu?.contentData?.selectionInfo?.text;
    win.document.getElementById("menu-deepl-translate").hidden = !selectionText;
    }
    beginTranslate(contextMenuContentData) {
    if (!contextMenuContentData) return;
    const win = contextMenuContentData.browser.ownerGlobal;
    const selectionText = contextMenuContentData.selectionInfo?.fullText;
    const targetIdentifier = contextMenuContentData.context?.targetIdentifier;
    const screenX = contextMenuContentData.context?.screenX ?? contextMenuContentData.context?.screenXDevPx / win.devicePixelRatio;
    const screenY = contextMenuContentData.context?.screenY ?? contextMenuContentData.context?.screenYDevPx / win.devicePixelRatio;
    const browser = contextMenuContentData.browser;
    const browserBoundingRect = browser.getBoundingClientRect();
    const fixupX = browser.ownerGlobal.outerWidth - browserBoundingRect.left - browserBoundingRect.width;
    const fixupY = 20 + browser.ownerGlobal.outerHeight - browserBoundingRect.top - browserBoundingRect.height;
    const actor = contextMenuContentData.frameBrowsingContext.currentWindowGlobal.getActor("DLTranslator");
    actor.sendAsyncMessage("DLT:CreatePopup", {
    targetIdentifier,
    screenX, screenY,
    fixupX, fixupY,
    fromLang: null,
    toLang: null,
    sourceText: selectionText,
    });
    }
    }();
    this.DLTranslatorParent = class extends JSWindowActorParent {
    receiveMessage({name, data}) {
    switch(name) {
    case "DLT:OpenTranlatorInTab":
    const win = this.browsingContext.top.embedderElement.ownerGlobal;
    win.openLinkIn(`https://www.deepl.com/translator#${data.sourceLang}/${data.targetLang}/${encodeURIComponent(data.sourceText)}`,
    "tab", {
    relatedToCurrent: true,
    triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(),
    }
    );
    break;
    }
    }
    }
    }
    else {
    Cu.importGlobalProperties(["fetch"]);
    this.EXPORTED_SYMBOLS = ["DLTranslatorChild"];
    this.DLPopupTranslator = class {
    constructor(win, x, y, sourceText) {
    this.sourceLang = "EN";
    this.targetLang = win.windowGlobalChild.getActor("DLTranslator").defaultLang;
    this.sourceText = sourceText.trim();
    const popup = this.popup = win.document.createElement("div");
    Object.assign(popup.style, {
    position: "absolute",
    top: `${win.scrollY + y}px`,
    left: `${win.scrollX + x}px`,
    width: "400px",
    maxHeight: "200px",
    fontFamily: "sans-serif",
    fontSize: "16px",
    color: "black",
    background: "floralwhite",
    border: "1px solid darkgray",
    borderRadius: "3px",
    boxShadow: "3px 3px 5px lightgray",
    transition: "opacity 0.2s ease",
    zIndex: "1000",
    });
    const flex = win.document.createElement("div");
    Object.assign(flex.style, {
    display: "flex",
    maxHeight: "200px",
    flexDirection: "column",
    });
    const header = win.document.createElement("div");
    Object.assign(header.style, {
    display: "flex",
    height: "auto",
    margin: "2px 5px 1px",
    fontSize: "smaller",
    alignItems: "center",
    });
    const logo = win.document.createElement("div");
    logo.textContent = "DeepL ほんやくくん";
    Object.assign(logo.style, {
    width: "auto",
    fontWeight: "bold",
    flexGrow: "1",
    });
    header.appendChild(logo);
    const langSelector = win.document.createElement("select");
    for (let [lang, desc] of Object.entries(supportedLangs)) {
    const option = win.document.createElement("option");
    option.value = lang;
    option.textContent = desc;
    langSelector.appendChild(option);
    }
    langSelector.value = this.targetLang;
    Object.assign(langSelector.style, {
    width: "auto",
    marginRight: "5px",
    });
    langSelector.addEventListener("change", this);
    header.appendChild(langSelector);
    const more = win.document.createElement("div");
    more.className = "deepl-translator-more";
    more.textContent = "more";
    Object.assign(more.style, {
    width: "auto",
    cursor: "pointer",
    });
    more.addEventListener("click", this);
    header.appendChild(more);
    flex.appendChild(header);
    const box = win.document.createElement("div");
    box.className = "deepl-translator-box";
    Object.assign(box.style, {
    height: "auto",
    overflow: "auto",
    background: "white",
    padding: "2px",
    margin: "1px 5px 5px",
    border: "1px solid darkgray",
    flexGrow: "1",
    whiteSpace: "pre-wrap",
    });
    flex.appendChild(box);
    this.popup.appendChild(flex);
    win.document.body.appendChild(popup);
    win.setTimeout(() => win.addEventListener("click", this), 0);
    }
    handleEvent(event) {
    const {type, target} = event;
    switch(type) {
    case "click":
    if (!this.popup.contains(target)) {
    target.ownerGlobal.removeEventListener("click", this);
    this.popup.addEventListener("transitionend", ({target}) => {
    target.parentNode.removeChild(target);
    }, {once:true});
    this.popup.style.opacity = 0;
    }
    else if (target.className === "deepl-translator-more") {
    const actor = target.ownerGlobal.windowGlobalChild.getActor("DLTranslator");
    actor.sendAsyncMessage("DLT:OpenTranlatorInTab", {
    sourceText: this.sourceText,
    sourceLang: this.sourceLang,
    targetLang: this.targetLang,
    });
    event.stopPropagation();
    }
    break;
    case "change":
    this.targetLang = target.value;
    this.translate(null, this.targetLang);
    break;
    }
    }
    setText(text, color) {
    let box = this.popup.querySelector(".deepl-translator-box");
    if (color) box.style.color = color;
    else box.style.color = null;
    box.textContent = text;
    }
    fetchWithPrivilege(url, request) {
    return new Promise((resolve, reject) => {
    const {method, headers, body, referrer} = request;
    let origin = referrer ? referrer : url;
    const channel = NetUtil.newChannel({
    uri: NetUtil.newURI(url),
    loadingPrincipal: Services.scriptSecurityManager.createContentPrincipal(NetUtil.newURI(origin), {}),
    contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
    securityFlags: Ci.nsILoadInfo.SEC_REQUIRE_CORS_INHERITS_SEC_CONTEXT || Ci.nsILoadInfo.SEC_REQUIRE_CORS_DATA_INHERITS,
    });
    channel.QueryInterface(Ci.nsIHttpChannel);
    channel.loadFlags |= Ci.nsIRequest.LOAD_ANONYMOUS;
    channel.requestMethod = method || "GET";
    if (headers) {
    for (const [name, value] of Object.entries(headers)) {
    if (channel.setNewReferrerInfo && name.toLowerCase() === "referer") {
    channel.setNewReferrerInfo(
    value,
    Ci.nsIReferrerInfo.UNSAFE_URL,
    true
    );
    }
    else {
    channel.setRequestHeader(name, value, false);
    }
    }
    }
    if (body) {
    channel.QueryInterface(Ci.nsIUploadChannel2);
    const converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
    converter.charset = "UTF-8";
    channel.explicitSetUploadStream(converter.convertToInputStream(body), null, -1, method, false);
    }
    NetUtil.asyncFetch(channel, (stream, status) => {
    if (!Components.isSuccessCode(status)) {
    let e = Components.Exception("", status);
    reject(new Error(`Error while loading ${url}: ${e.name}`));
    }
    let text = NetUtil.readInputStreamToString(stream, stream.available());
    stream.close();
    resolve({
    ok: channel.requestSucceeded,
    status: channel.responseStatus,
    statusText: channel.responseStatusText,
    contentType: channel.getResponseHeader("content-type"),
    text
    });
    });
    });
    }
    translateUsingBackdoor(from, to) {
    const getTimestamp = text => {
    let now = new Date().getTime();
    let count = 1;
    let match = text.match(/i/g);
    if (match) {
    count += match.length;
    }
    return now + count - now % count;
    };
    this.fetchWithPrivilege("https://www2.deepl.com/jsonrpc", {
    method: "POST",
    referrer: "https://www.deepl.com/translator",
    headers: {
    "Content-Type": "application/json",
    Referer: "https://www.deepl.com/translator",
    },
    body: JSON.stringify({
    jsonrpc: "2.0",
    method: "LMT_handle_texts",
    params: {
    texts: [{text: this.sourceText}],
    splitting: "newlines",
    lang: {
    target_lang: to.slice(0, 2),
    source_lang_user_selected: from ? from : "auto",
    },
    timestamp: getTimestamp(this.sourceText),
    },
    id: 1000000+Math.floor(Math.random()*99000000),
    }, null, 4),
    }).then(resp => {
    if (!resp.ok && !resp.contentType.startsWith("application/json")) {
    throw new Error(`Server returned ${resp.status} ${resp.statusText}`);
    }
    return JSON.parse(resp.text);
    }).then(json => {
    if (json.error) throw new Error(`Error code ${json.error.code}: ${json.error.message}`);
    if (!json.result?.texts) throw new Error("Unknown error occurred");
    this.setText(json.result.texts[0].text);
    this.sourceLang = json.result.lang;
    }).catch(e => {
    this.setText(e.message, "red");
    Cu.reportError(e);
    });
    }
    translate(from, to) {
    this.setText("翻訳中...", "lightgray");
    if (to) {
    this.popup.querySelector("select").value = this.targetLang = to;
    this.popup.ownerGlobal.windowGlobalChild.getActor("DLTranslator").defaultLang = to;
    }
    if (!apiKey) return this.translateUsingBackdoor(from, this.targetLang);
    const body = new FormData();
    body.append("text", this.sourceText);
    body.append("target_lang", this.targetLang);
    body.append("auth_key", apiKey);
    if (from) body.append("source_lang", from);
    return fetch(`${apiEndpoint}/translate`, {
    method: "POST",
    referrerPolicy: "no-referrer",
    credentials: "omit",
    body,
    }).then(resp => {
    if (!resp.ok && resp.status != 400) {
    throw new Error(`Server returned ${resp.status} ${resp.statusText}`);
    }
    return resp.json();
    }).then(json => {
    if (!json.translations) throw new Error(`${json.message}: ${json.detail}`);
    this.setText(json.translations[0].text);
    this.sourceLang = json.translations[0].detected_source_language;
    fetch(`${apiEndpoint}/usage`, {
    referrerPolicy: "no-referrer",
    credentials: "omit",
    headers: {
    Authorization: `DeepL-Auth-Key ${apiKey}`,
    },
    }).then(resp => {
    if (!resp.ok) throw new Error();
    return resp.json();
    }).then(json => {
    this.popup.title = `Quota: ${(100*json.character_count/json.character_limit).toPrecision(2)}% (${json.character_count} / ${json.character_limit})`;
    }).catch(()=>{});
    }).catch(e => {
    this.setText(e.message, "red");
    Cu.reportError(e);
    });
    }
    }
    this.DLTranslatorChild = class extends JSWindowActorChild {
    actorCreated() {
    this.defaultLang = defaultLang;
    this.keyRepeat = 0;
    }
    createPopupWithScreenCoordinate(screenX, screenY, sourceText) {
    let x = screenX - this.contentWindow.screenX - this.contentWindow.outerWidth + this.contentWindow.innerWidth;
    let y = screenY - this.contentWindow.screenY - this.contentWindow.outerHeight + this.contentWindow.innerHeight;
    return this.createPopupWithClientCoordinate(x, y, sourceText);
    }
    createPopupWithClientCoordinate(clientX, clientY, sourceText) {
    let x = clientX;
    let y = clientY;
    let clientWidth = this.contentWindow.document.documentElement.clientWidth;
    let clientHeight = this.contentWindow.document.documentElement.clientHeight;
    if (x + 400 > clientWidth) x = clientWidth - 400;
    if (y + 200 > clientHeight) y = clientHeight - 200;
    x = Math.max(x, 0);
    y = Math.max(y, 0);
    return new DLPopupTranslator(this.contentWindow, x, y, sourceText);
    }
    createPopupWithSelection() {
    const selection = this.contentWindow.getSelection();
    const text = selection.toString().trim();
    if (text) {
    let rect = selection.getRangeAt(0).getBoundingClientRect();
    return this.createPopupWithClientCoordinate(rect.left, rect.top+rect.height, text);
    }
    return null;
    }
    receiveMessage({name, data}) {
    switch(name) {
    case "DLT:CreatePopup":
    let fixupX = 0;
    let fixupY = 0;
    if (data.fixupX) fixupX = data.fixupX;
    if (data.fixupY) fixupY = data.fixupY;
    this.createPopupWithScreenCoordinate(data.screenX+fixupX, data.screenY+fixupY, data.sourceText).translate(data.fromLang, data.toLang);
    break;
    case "DLT:CreatePopupWithClientCoordinate":
    this.createPopupWithClientCoordinate(data.clientX, data.clientY, data.sourceText).translate(data.fromLang, data.toLang);
    break;
    }
    }
    handleEvent(event) {
    switch (event.type) {
    case "keyup":
    if (event.code === hotkey.code && this.contentWindow.getSelection()?.toString()) {
    if (!this.keyRepeat) {
    new Promise((resolve, reject) => {
    this.hotkeyResolver = resolve;
    this.hotkeyRejector = reject;
    this.contentWindow.setTimeout(() => reject(), hotkey.timeout);
    }).then(() => {
    this.keyRepeat = 0;
    this.hotkeyResolver = null;
    this.hotkeyRejector = null;
    this.createPopupWithSelection()?.translate(null, this.defaultLang);
    }).catch(() => {
    this.keyRepeat = 0;
    this.hotkeyResolver = null;
    this.hotkeyRejector = null;
    });
    }
    if (++this.keyRepeat === hotkey.repeat) {
    this.hotkeyResolver();
    }
    }
    else if (this.keyRepeat) {
    this.hotkeyRejector();
    }
    break;
    }
    }
    }
    }
    }
    else {
    try {
    if (parseInt(Services.appinfo.version) < 101) {
    ChromeUtils.import(Components.stack.filename).DLTranslator.attachToWindow(window);
    } else {
    const fileHandler = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);
    const scriptFile = fileHandler.getFileFromURLSpec(Components.stack.filename);
    const resourceHandler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);
    if (!resourceHandler.hasSubstitution("deepl-ucjs")) {
    resourceHandler.setSubstitution("deepl-ucjs", Services.io.newFileURI(scriptFile.parent));
    }
    ChromeUtils.import(`resource://deepl-ucjs/${encodeURIComponent(scriptFile.leafName)}?${scriptFile.lastModifiedTime}`).DLTranslator.attachToWindow(window);
    }
    } catch(e) {}
    }
    Alles anzeigen
    Alles anzeigen

    Without apikey, the script would translate text through backdoor, there will be some restrictions.

  • DeepL Script

    • jizz
    • 11. November 2022 um 17:21

    Due to Deepl unsuitable Chinese service, I modified the script to use Baidu translation API

    Code
    // ==UserScript==// @name           Baidu Translator// @author         Ryan, BSTweaker// @include        main// @compatibility  Firefox 78+// @homepageURL	   https://github.com/benzBrake/FirefoxCustomize/tree/master/userChromeJS// @description    在上下文菜单中添加使用百度翻译所选文本的功能// @note           从 DLTranslator (https://bitbucket.org/BSTweaker/userchromejs/src/master/DeepLTranslator.uc.js)修改而来// @charset        UTF-8// ==/UserScript==const BDT_OPTIONS = {    defaultLang: "zh",    enableContextMenu: true,    hotkey: {        enabled: true,        code: "AltLeft",        repeat: 2,        timeout: 500,    },    supportedLangs: {        //"ara": "Arabic",        //"bul": "Bulgarian",        //"cs": "Czech",        //"dan": "Danish",        "de": "German",        //"el": "Greek",        "en": "English",        //"est": "Estonian",        //"fin": "Finnish",        //"fra": "French",        //"hu": "Hungarian",        //"it": "Italian",        //"jp": "Japanese",        //"lit": "Lithuanian",        //"lav": "Latvian",        //"nl": "Dutch",        //"pl": "Polish",        "pt": "Portuguese",        "pot": "Portuguese (Brazilian)",        //"rom": "Romanian",        //"ru": "Russian",        //"sk": "Slovak",        //"slo": "Slovenian",        "spa": "Spanish",        //"swe": "Swedish",        "th": "Thai",        "vie": "Vietnamese",        "zh": "简体中文",        "cht": "繁體中文",        "wyw": "文言文",    }}if (typeof window === "undefined" || globalThis !== window) {    const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");    ChromeUtils.defineModuleGetter(this, "ContentDOMReference", "resource://gre/modules/ContentDOMReference.jsm");    ChromeUtils.defineModuleGetter(this, "NetUtil", "resource://gre/modules/NetUtil.jsm");    if (!Services.appinfo.remoteType) {        this.EXPORTED_SYMBOLS = ["BDTranslator", "BDTranslatorParent"];        try {            const actorParams = {                parent: {                    moduleURI: __URI__,                },                child: {                    moduleURI: __URI__,                    events: {},                },                allFrames: true,                messageManagerGroups: ["browsers"],                matches: [`*://*/*`],            };            if (BDT_OPTIONS.hotkey.enabled) {                if (BDT_OPTIONS.hotkey.repeat <= 0) BDT_OPTIONS.hotkey.repeat = 2;                if (BDT_OPTIONS.hotkey.timeout <= 0) BDT_OPTIONS.hotkey.timeout = 500;                actorParams.child.events.keyup = {};            }            ChromeUtils.registerWindowActor("BDTranslator", actorParams);        } catch (e) { Cu.reportError(e); }        this.BDTranslatorParent = class extends JSWindowActorParent {            receiveMessage({ name, data }) {                // https://searchfox.org/mozilla-central/rev/43ee5e789b079e94837a21336e9ce2420658fd19/browser/actors/ContextMenuParent.sys.mjs#60-63                let browser = this.browsingContext.top.embedderElement;                let win = browser.ownerGlobal;                const { BDTranslator } = win;                switch (name) {                    case "BDT:OpenTranlatorInTab":                        BDTranslator.translateTextInNewTab(data.sourceText, data.from, data.to);                        break;                    case "BDT:TranslateText":                        BDTranslator.translateText(data.sourceText, data.from, data.to).then(result => {                            this.sendAsyncMessage("BDT:TranslateReulult", {                                ...data,                                resultObject: result                            })                        })                        break;                }            }        }    }    else {        Cu.importGlobalProperties(["fetch"]);        this.EXPORTED_SYMBOLS = ["BDTranslatorChild"];        const BDPopupTranslator = {            popup: null,            show(win, x, y, sourceText, resultObject) {                const options = BDT_OPTIONS;                if (resultObject && "trans_result" in resultObject) {                    this.fromLang = resultObject["trans_result"].from || "auto";                    this.targetLang = resultObject["trans_result"].to || options.defaultLang                } else {                    this.fromLang = "auto";                    this.targetLang = options.defaultLang;                }                this.sourceText = sourceText.trim();                if (!win.document.getElementById("baidu-translator")) {                    this.popup = win.document.createElement("div");                    this.popup.id = "baidu-translator"                    Object.assign(this.popup.style, {                        position: "absolute",                        top: `${win.scrollY + y}px`,                        left: `${win.scrollX + x}px`,                        width: "400px",                        maxHeight: "200px",                        fontFamily: "sans-serif",                        fontSize: "16px",                        color: "black",                        background: "floralwhite",                        border: "1px solid darkgray",                        borderRadius: "3px",                        boxShadow: "3px 3px 5px lightgray",                        transition: "opacity 0.2s ease",                        zIndex: "1000",                    });                    const flex = win.document.createElement("div");                    Object.assign(flex.style, {                        display: "flex",                        maxHeight: "200px",                        flexDirection: "column",                    });                    const header = win.document.createElement("div");                    Object.assign(header.style, {                        display: "flex",                        height: "auto",                        margin: "2px 5px 1px",                        fontSize: "smaller",                        alignItems: "center",                    });                    const logo = win.document.createElement("div");                    logo.textContent = "翻译结果";                    Object.assign(logo.style, {                        width: "auto",                        fontWeight: "bold",                        flexGrow: "1",                    });                    header.appendChild(logo);                    const langSelector = win.document.createElement("select");                    for (let [lang, desc] of Object.entries(options.supportedLangs)) {                        const option = win.document.createElement("option");                        option.value = lang;                        option.textContent = desc;                        langSelector.appendChild(option);                    }                    langSelector.value = this.targetLang;                    Object.assign(langSelector.style, {                        width: "auto",                        marginRight: "5px",                    });                    langSelector.addEventListener("change", this);                    header.appendChild(langSelector);                    const more = win.document.createElement("div");                    more.className = "baidu-translator-more";                    more.textContent = "更多";                    Object.assign(more.style, {                        width: "auto",                        cursor: "pointer",                    });                    more.addEventListener("click", this);                    header.appendChild(more);                    flex.appendChild(header);                    const box = win.document.createElement("div");                    box.className = "baidu-translator-box";                    Object.assign(box.style, {                        height: "auto",                        overflow: "auto",                        background: "white",                        padding: "2px",                        margin: "1px 5px 5px",                        border: "1px solid darkgray",                        flexGrow: "1",                        whiteSpace: "pre-wrap",                    });                    flex.appendChild(box);                    this.popup.appendChild(flex);                    win.document.body.appendChild(this.popup);                    win.setTimeout(() => win.addEventListener("click", this), 0);                } else {                    this.setPos(x, y);                }                if (resultObject && "trans_result" in resultObject) {                    let data = resultObject.trans_result.data;                    this.setText(data.map(el => el.dst).join("\n"));                }            },            handleEvent(event) {                const { type, target } = event;                const actor = target.ownerGlobal.windowGlobalChild.getActor("BDTranslator");                switch (type) {                    case "click":                        if (!this.popup.contains(target)) {                            target.ownerGlobal.removeEventListener("click", this);                            this.popup.addEventListener("transitionend", ({ target }) => {                                target.parentNode.removeChild(target);                            }, { once: true });                            this.popup.style.opacity = 0;                        }                        else if (target.className === "baidu-translator-more") {                            actor.sendAsyncMessage("BDT:OpenTranlatorInTab", {                                sourceText: this.sourceText,                                from: this.fromLang,                                to: this.targetLang,                            });                            event.stopPropagation();                        }                        break;                    case "change":                        this.targetLang = target.value;                        this.translate(actor, this.sourceText, this.fromLang, this.targetLang);                        break;                }            },            setPos(x, y) {                Object.assign(this.popup.style, {                    top: `${win.scrollY + y}px`,                    left: `${win.scrollX + x}px`,                    opacity: 1                });            },            setText(text, color) {                let box = this.popup.querySelector(".baidu-translator-box");                if (color) box.style.color = color;                else box.style.color = null;                box.textContent = text;            },            translate(actor, text, from, to) {                this.setText("正在翻译中...", "lightgray");                actor.sendAsyncMessage("BDT:TranslateText", {                    sourceText: text,                    from: from || this.fromLang,                    to: to || this.targetLang                });            }        }        this.BDTranslatorChild = class extends JSWindowActorChild {            actorCreated() {                this.keyRepeat = 0;            }            createPopupWithScreenCoordinate(screenX, screenY, sourceText, resultObject) {                let x = screenX - this.contentWindow.screenX - this.contentWindow.outerWidth + this.contentWindow.innerWidth;                let y = screenY - this.contentWindow.screenY - this.contentWindow.outerHeight + this.contentWindow.innerHeight;                this.createPopupWithClientCoordinate(x, y, sourceText, resultObject);            }            createPopupWithClientCoordinate(clientX, clientY, sourceText, resultObject) {                let x = clientX;                let y = clientY;                let clientWidth = this.contentWindow.document.documentElement.clientWidth;                let clientHeight = this.contentWindow.document.documentElement.clientHeight;                if (x + 400 > clientWidth) x = clientWidth - 400;                if (y + 200 > clientHeight) y = clientHeight - 200;                x = Math.max(x, 0);                y = Math.max(y, 0);                if (resultObject) {                    BDPopupTranslator.show(this.contentWindow, x, y, sourceText, resultObject);                } else {                    BDPopupTranslator.show(this.contentWindow, x, y, sourceText);                    BDPopupTranslator.translate(this.contentWindow.windowGlobalChild.getActor("BDTranslator"), sourceText);                }            }            createPopupWithSelection() {                const selection = this.contentWindow.getSelection();                const text = selection.toString().trim();                if (text) {                    let rect = selection.getRangeAt(0).getBoundingClientRect();                    return this.createPopupWithClientCoordinate(rect.left, rect.top + rect.height, text);                }                return null;            }            receiveMessage({ name, data }) {                switch (name) {                    case "BDT:CreatePopup":                        let fixupX = 0;                        let fixupY = 0;                        if (data.fixupX) fixupX = data.fixupX;                        if (data.fixupY) fixupY = data.fixupY;                        this.createPopupWithScreenCoordinate(data.screenX + fixupX, data.screenY + fixupY, data.sourceText, data.resultObject);                        break;                    case "BDT:TranslateReulult":                        let resultObject = data.resultObject;                        if (resultObject && "trans_result" in resultObject) {                            let data = resultObject.trans_result.data;                            BDPopupTranslator.setText(data.map(el => el.dst).join("\n"));                        } else {                            BDPopupTranslator.setText("翻译失败!", "red");                        }                        break;                    case "BDT:CreatePopupWithClientCoordinate":                        this.createPopupWithClientCoordinate(data.clientX, data.clientY, data.sourceText).translate(data.fromLang, data.toLang);                        break;                }            }            handleEvent(event) {                switch (event.type) {                    case "keyup":                        if (event.code === BDT_OPTIONS.hotkey.code && this.contentWindow.getSelection()?.toString()) {                            if (!this.keyRepeat) {                                new Promise((resolve, reject) => {                                    this.hotkeyResolver = resolve;                                    this.hotkeyRejector = reject;                                    this.contentWindow.setTimeout(() => reject(), BDT_OPTIONS.hotkey.timeout);                                }).then(() => {                                    this.keyRepeat = 0;                                    this.hotkeyResolver = null;                                    this.hotkeyRejector = null;                                    this.createPopupWithSelection();                                }).catch(() => {                                    this.keyRepeat = 0;                                    this.hotkeyResolver = null;                                    this.hotkeyRejector = null;                                });                            }                            if (++this.keyRepeat === BDT_OPTIONS.hotkey.repeat) {                                this.hotkeyResolver();                            }                        }                        else if (this.keyRepeat) {                            this.hotkeyRejector();                        }                        break;                }            }        }    }} else {    try {        if (parseInt(Services.appinfo.version) < 101) {            ChromeUtils.import(Components.stack.filename);        } else {            let fileHandler = Services.io.getProtocolHandler("file").QueryInterface(Ci.nsIFileProtocolHandler);            let scriptPath = Components.stack.filename;            if (scriptPath.startsWith("chrome")) {                scriptPath = resolveChromeURL(scriptPath);                function resolveChromeURL(str) {                    const registry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry);                    try {                        return registry.convertChromeURL(Services.io.newURI(str.replace(/\\/g, "/"))).spec                    } catch (e) {                        console.error(e);                        return ""                    }                }            }            let scriptFile = fileHandler.getFileFromURLSpec(scriptPath);            let resourceHandler = Services.io.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler);            if (!resourceHandler.hasSubstitution("bdt-ucjs")) {                resourceHandler.setSubstitution("bdt-ucjs", Services.io.newFileURI(scriptFile.parent));            }            ChromeUtils.import(`resource://bdt-ucjs/${encodeURIComponent(scriptFile.leafName)}?${scriptFile.lastModifiedTime}`);        }    } catch (e) { console.error(e) }    (function () {        window.BDTranslator = {            get appVersion() {                delete this.appVersion;                return this.appVersion = parseFloat(Services.appinfo.version);            },            init: async function () {                window.addEventListener('unload', this, false);                /**                 * 获取必备头                 */                let respText = await (await fetch("https://fanyi.baidu.com")).text();                this.gtk = /window\.gtk = ('|")(.*?)('|")/.exec(respText)[2];                this.token = /token: ('|")(.*?)('|")/.exec(respText)[2];                if (BDT_OPTIONS.enableContextMenu)                    this.addContextMenuitem();            },            /**             * 添加右键菜单             */            addContextMenuitem() {                const menuitem = $C("menuitem", {                    id: 'menu-translate-selected',                    label: "翻译选中文本"                });                menuitem.addEventListener('command', this, false);                this.menuitem = $('contentAreaContextMenu').appendChild(menuitem);                $('contentAreaContextMenu').addEventListener('popupshowing', this);            },            /**             * 通过 API 获取语言             * @param {string} text 待检测文本             * @returns              */            checkLang: async function (text) {                const rawText = text.replace(/[\uD800-\uDBFF]$/, "").slice(0, 50);                const data = new URLSearchParams();                data.append('query', rawText);                const options = {                    method: "POST",                    headers: {                        "Content-Type": "application/x-www-form-urlencoded",                    },                    body: data,                };                try {                    const response = await fetch('https://fanyi.baidu.com/langdetect', options);                    const { lan } = await response.json();                    return lan;                } catch (error) {                    console.log(error);                    return;                }            },            /**             * 网页翻译接口             *              * @param {string} text 带翻译文本             * @param {string} from 源语言,不提供此参数则自动检测             * @param {string} to 目标语言,不提供则默认翻译为默认语言             * @returns              */            translateText: async function (text, from, to) {                if (!from) {                    from = await this.checkLang(text);                }                to || (to = BDT_OPTIONS.defaultLang);                const processedText = text.length > 30 ? (text.substring(0, 10) + text.substring(~~(text.length / 2) - 5, ~~(text.length / 2) + 5) + text.substring(text.length - 10)) : text;                const data = new URLSearchParams();                data.append('from', from);                data.append('to', to);                data.append('query', text);                data.append('simple_means_flag', '3');                data.append('sign', calcTk(processedText, this.gtk));                data.append('token', this.token);                data.append('domain', 'common');                const options = {                    method: 'POST',                    headers: {                        'referer': 'https://fanyi.baidu.com',                        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',                    },                    body: data,                };                try {                    const response = await fetch('https://fanyi.baidu.com/v2transapi', options);                    const res = await response.json();                    return res;                    // Process the response as needed                } catch (error) {                    console.log(error);                    return;                }            },            /**             * 打开翻译网页             * @param {string} text 待翻译文本             * @param {string} from 源语言             * @param {string} to 目标语言             */            translateTextInNewTab: function (text, from, to) {                const urlTemplate = "https://fanyi.baidu.com/#{sourceLang}/{targetLang}/{sourceText}";                const url = urlTemplate.replace("{sourceLang}", from).replace("{targetLang}", to).replace("{sourceText}", text)                if (this.appVersion < 78) {                    openUILinkIn(url, 'tab', false, null);                } else {                    openWebLinkIn(url, 'tab', {                        postData: null,                        triggeringPrincipal:                            Services.scriptSecurityManager.createNullPrincipal({                                userContextId: gBrowser.selectedBrowser.getAttribute(                                    "userContextId"                                )                            })                    });                }            },            /**             * 事件处理             * @param {*} event              */            handleEvent: function (event) {                switch (event.type) {                    case "unload":                        this.uninit();                        break;                    case "command":                        this.beginTranslate(event.target.ownerGlobal.gContextMenu?.contentData);                        break;                    case "popupshowing":                        this.popupshowing(event.target.ownerGlobal);                        break;                }            },            /**             * 点击菜单开始翻译             *              * @param {*} contextMenuContentData              * @returns              */            beginTranslate: async function (contextMenuContentData) {                if (!contextMenuContentData) return;                const win = contextMenuContentData.browser.ownerGlobal;                const selectionText = contextMenuContentData.selectionInfo?.fullText;                const targetIdentifier = contextMenuContentData.context?.targetIdentifier;                const screenX = contextMenuContentData.context?.screenX ?? contextMenuContentData.context?.screenXDevPx / win.devicePixelRatio;                const screenY = contextMenuContentData.context?.screenY ?? contextMenuContentData.context?.screenYDevPx / win.devicePixelRatio;                const browser = contextMenuContentData.browser;                const browserBoundingRect = browser.getBoundingClientRect();                const fixupX = browser.ownerGlobal.outerWidth - browserBoundingRect.left - browserBoundingRect.width;                const fixupY = 20 + browser.ownerGlobal.outerHeight - browserBoundingRect.top - browserBoundingRect.height;                const actor = contextMenuContentData.frameBrowsingContext.currentWindowGlobal.getActor("BDTranslator");                let translatedResult = await this.translateText(selectionText);                actor.sendAsyncMessage("BDT:CreatePopup", {                    targetIdentifier,                    screenX, screenY,                    fixupX, fixupY,                    sourceText: selectionText,                    resultObject: translatedResult                });            },            /**             * 没有选中文本的时候隐藏右键菜单             * @param {ChromeWindow} win              */            popupshowing(win) {                let selectionText = win.gContextMenu?.contentData?.selectionInfo?.text;                this.menuitem.hidden = !selectionText;            },            uninit: async function () {                window.removeEventListener('unload', this, false);                $('contentAreaContextMenu').removeEventListener('popupshowing', this);                if (this.menuitem) this.menuitem.parentNode.removeChild(this.menuitem);                delete window.BDTranslator;            }        }        function $(id) {            return document.getElementById(id);        }        function $C(tag, attrs, skipAttrs) {            var el;            if (!tag) return el;            attrs = attrs || {};            skipAttrs = skipAttrs || [];            if (tag.startsWith('html:'))                el = document.createElement(tag);            else                el = document.createXULElement(tag);            return $A(el, attrs, skipAttrs);        }        function $A(el, attrs, skipAttrs) {            skipAttrs = skipAttrs || [];            if (attrs) Object.keys(attrs).forEach(function (key) {                if (!skipAttrs.includes(key)) {                    if (typeof attrs[key] === 'function')                        el.setAttribute(key, "(" + attrs[key].toString() + ").call(this, event);");                    else                        el.setAttribute(key, attrs[key]);                }            });            return el;        }        /** 签名计算 */        function calcTk(a, b) {            var d = b.split(".");            b = Number(d[0]) || 0;            for (var e = [], f = 0, g = 0; g < a.length; g++) {                var k = a.charCodeAt(g);                128 > k ? e[f++] = k : (2048 > k ? e[f++] = k >> 6 | 192 : (55296 == (k & 64512) && g + 1 < a.length && 56320 == (a.charCodeAt(g + 1) & 64512) ? (k = 65536 + ((k & 1023) << 10) + (a.charCodeAt(++g) & 1023),                    e[f++] = k >> 18 | 240,                    e[f++] = k >> 12 & 63 | 128) : e[f++] = k >> 12 | 224,                    e[f++] = k >> 6 & 63 | 128),                    e[f++] = k & 63 | 128)            }            a = b;            for (f = 0; f < e.length; f++)a = Fo(a + e[f], "+-a^+6");            a = Fo(a, "+-3^+b+-f");            a ^= Number(d[1]) || 0;            0 > a && (a = (a & 2147483647) + 2147483648);            a %= 1E6;            return a.toString() + "." + (a ^ b)        }        function Fo(a, b) {            for (var c = 0; c < b.length - 2; c += 3) {                var d = b.charAt(c + 2);                d = "a" <= d ? d.charCodeAt(0) - 87 : Number(d);                d = "+" == b.charAt(c + 1) ? a >>> d : a << d;                a = "+" == b.charAt(c) ? a + d & 4294967295 : a ^ d            }            return a        }        window.BDTranslator.init();    })()}
  • DeepL Script

    • jizz
    • 10. November 2022 um 15:01

    Here's a powerful version

  • Ersatz für "autocopyselection2clipboard" Erweiterung gesucht

    • jizz
    • 21. August 2022 um 14:55

    You can try this userchrome.js script

    JavaScript: AutoCopySelectionText.uc.js
    // ==UserScript==
    // @name            AutoCopySelectionText.uc.js
    // @description     自动复制选中文本(ScrLk 亮起时不复制)
    // @author          Ryan
    // @version         2022.07.28
    // @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.28 网页支持文本框
    // @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");
                // will be transfered to control by toolbar button
                let user32 = ctypes.open("user32.dll");
                this.getKeyState = user32.declare('GetKeyState', ctypes.winapi_abi, ctypes.bool, ctypes.int);
                function frameScript() {
                    const { Services } = Components.utils.import(
                        "resource://gre/modules/Services.jsm"
                    );
    
                    // implement read from about:config preferences in future
                    var WAIT_TIME = 0; // Change it to any number as you want
                    var TRIM_SELECTION = true; // remove spaces before and after the string
    
                    // Do not modify below ------------------------------------------
                    var LONG_PRESS = false;
                    var TIMEOUT_ID = null;
                    function handleEvent(event) {
                        if (event.button !== 0) return; // only trigger when left button up
                        if (TIMEOUT_ID)
                            content.clearTimeout(TIMEOUT_ID);
                        const focusedElement =
                            Services.focus.focusedElement ||
                            event.originalTarget.ownerDocument?.activeElement;
    
                        switch (event.type) {
                            case 'mousemove':
                                TIMEOUT_ID = content.setTimeout(function () {
                                    LONG_PRESS = true;
                                }, WAIT_TIME);
                            case 'mouseup':
                                // copy text on mouse button up
                                if (LONG_PRESS) {
                                    let data = { text: getSelection(content, focusedElement) }
                                    sendSyncMessage("acst_selectionData", data);
                                }
                                break;
                        }
                        LONG_PRESS = false;
                    }
    
                    // From addMenuPlus.uc.js
                    function getSelection(win, focusedElement) {
                        win || (win = content);
                        var selection = win.getSelection().toString();
                        if (!selection) {
                            let element = focusedElement;
                            let isOnTextInput = function (elem) {
                                return elem instanceof HTMLTextAreaElement ||
                                    (elem instanceof HTMLInputElement && elem.mozIsTextField(true));
                            };
    
                            if (isOnTextInput(element)) {
                                selection = element.value.substring(element.selectionStart,
                                    element.selectionEnd);
                            }
                        }
    
                        if (TRIM_SELECTION && selection) {
                            selection = selection.replace(/^\s+/, "")
                                .replace(/\s+$/, "")
                                .replace(/\s+/g, " ");
                        }
                        return selection;
                    }
    
                    ["mousemove", "mouseup"].forEach((t) => addEventListener(t, handleEvent, false));
    
                    function receiveMessage(message) {
                        switch (message.name) {
                            case 'acst_destroy':
                                ["mousemove", "mouseup"].forEach((t) => removeEventListener(t, handleEvent, false));
                                removeMessageListener("acst_destroy", receiveMessage);
                                handleEvent = null;
                                receiveMessage = null;
                                break;
                        }
                    }
                    addMessageListener("acst_destroy", receiveMessage);
                }
                let frameScriptURI = 'data:application/javascript,'
                    + encodeURIComponent('(' + frameScript.toString() + ')()');
                window.messageManager.loadFrameScript(frameScriptURI, true);
                window.messageManager.addMessageListener("acst_selectionData", this);
            }
            receiveMessage(message) {
                switch (message.name) {
                    case 'acst_selectionData':
                        if (this.getKeyState(0x91)) return;
                        if (message.data.text)
                            Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper).copyString(message.data.text);
                        break;
                }
            }
            destroy() {
                window.messageManager.broadcastAsyncMessage("acst_destroy");
                window.messageManager.removeMessageListener("acst_selectionData", this);
                delete window.AutoCopySelectionText;
            }
        }
    
        window.AutoCopySelectionText = new AutoCopySelectionText();
    })()
    Alles anzeigen
  • FireFox Portabel richtig nutzen, aber wie?

    • jizz
    • 23. Juni 2022 um 13:13

    You can use this firefox loader to run portable firefox

    GitHub - charygao/GreenFirefox: fix from Myfirefox
    fix from Myfirefox. Contribute to charygao/GreenFirefox development by creating an account on GitHub.
    github.com


    This loader allow to set firefox as default browser in firefox preferences directly

  • Kontextmenü sortieren

    • jizz
    • 29. Mai 2022 um 04:37
    Zitat von Dharkness
    Zitat von jizz
    CSS: userChrome.css
    #contentAreaContextMenu [label="Copy selected Links"] {
        -moz-box-ordinal-group: 0; // 1, 2, 3, 4, 5
    }

    Das würde so nicht funktionieren, der → // 1, 2, 3, 4, 5 Teil verhindert, das das CSS-Schnipsel funktioniert, das müsste als angehängter Kommentar so /* 1, 2, 3, 4, 5 */ aussehen.

    Sorry, that was my oversight

  • Kontextmenü sortieren

    • jizz
    • 28. Mai 2022 um 09:12
    CSS: userChrome.css
    #contentAreaContextMenu [label="Copy selected Links"] {
        -moz-box-ordinal-group: 0; /* 1, 2, 3, 4, 5 */
    }

Unterstütze uns!

Jährlich (2025)

91,4 %

91,4% (594,17 von 650 EUR)

Jetzt spenden
  1. Kontakt
  2. Datenschutz
  3. Impressum
Community-Software: WoltLab Suite™
Mastodon