Dumby
Вернул по старому и ошибок нет, а раньше была AboutNewTab is not defined. Теперь уже не знаю почему. Может Cu.import проходил с задержкой. Долго экспериментировал в стилях для установки фонового локального изображения для blanktab.html и about:blank. В итоге оставил только для blanktab.html.
Отсутствует
@Dumby
Большая просьба восстановить работоспособность скрипта. Скрипт от aborix создает кнопку для обновления закладки, перестал работать в v129 (в v115.14.0esr работает). В чем его удобство и преимущество, так в том, что с ним, в отличие от скрипта в контекстное меню, невозможно ошибочно обновить (заменить), например, закладку на эту тему на закладку погодного сайта, вкладка которого сейчас активна.
По умолчанию скрипт имеет большую цветную демо-кнопку, но это не проблема, я могу заменить ее на свою.
(function() { if (window.__SSi != 'window0') return; CustomizableUI.createWidget({ id: 'bookmark-update-button', label: 'Update Bookmark', tooltiptext: 'Update this Bookmark', defaultArea: CustomizableUI.AREA_NAVBAR, onCreated: button => { button.style.backgroundColor = 'hotpink'; // icon like a pink square }, onCommand: async (event) => { let window = event.target.ownerGlobal; let document = window.document; window.FillHistoryMenu(document.getElementById('backForwardMenu')); let bookmarkUrl = document.querySelector('#backForwardMenu > menuitem[historyindex="-1"]') ?.getAttribute('uri'); let bookmark = await window.PlacesUtils.bookmarks.fetch({url: bookmarkUrl}); if (bookmark) { window.PlacesUtils.bookmarks.update({ guid: bookmark.guid, url: window.gBrowser.currentURI }); } } }); })();
Отсутствует
перестал работать в v129
FillHistoryMenu() теперь хочет event
/* window.FillHistoryMenu(document.getElementById('backForwardMenu')); */ window.FillHistoryMenu({ preventDefault() {}, target: document.getElementById('backForwardMenu') });
Отсутствует
Как-то копаясь по сампу, я там тестирую переводчик. Нарвался на пост Mira-Belle. Оказывается они пытаются создать что-то на подобии рыжего меню, правда я про меню совсем не помню, ибо . Да ещё тут на форуме полетел шумок про main-menubar, Dumby его конечно же поправил. При всем уважении кому-то должно было стать стыдно, зачем нужно использовать три скрипта, да ещё перегруженных png,base64. В общем покопался и пересобрал рыжее меню для рыжего лиса, взял Endor8, прибавил Aris-t2 и конечно коды Dumby не прошел стороной.
// ==UserScript== // @name Appmenu.uc.js // @namespace Appmenu@gmail.com // @description Basiert auf dem Script externalFuncButtonM.uc.js, Wiederherstellung der Orangenen FF-Menü Schaltfläche // @include main // @version update für Firefox 129+ by bege // @author defpt // @charset UTF-8 // @version 2019.08.04 // @version 2020.05.27 // @version 2020.07.13 Weitere Menüs und Funktionen ergänzt by bege // @version 2024.08.10 alle Einstellungen im Abschnitt Konfiguration vornehmen // ==/UserScript== var Appmenu = { // Beginn der Konfiguration ------------------ // Editor mit angegebenem Pfad verwenden // editor: 'C:\\Program Files\\Notepad++\\notepad++.exe', // oder // in 'view_source.editor.path' eingetragenen Editor verwenden editor: Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch).getCharPref('view_source.editor.path'), // Dateimanager mit angegebenem Pfad verwenden oder leer ('') wenn System-Dateimanager verwenden fileManager: '', // fileManager: 'C:\\Program files\\FreeCommander XE\\FreeCommander.exe', // Parameter für Dateimanager oder leer ('') FMParameter: '/T', // Submenüs ohne Inhalt im Hauptmenü automatisch ausblenden autohideEmptySubDirs: true, // Submenüs im Hauptmenü nach unten verschieben moveSubDirstoBottom: false, // Ort und Aussehen des Menü-Buttons einstellen isUrlbar: 0, // 0: TabsToolbar, 1: navbar, 2: toolbar-menubar; isButton: 1, // 0: Hamburger, klein; 1: Firefox, groß isEditMenu: 1, // Move Main-Menubar // Hotkey zum Öffnen des Appmenüs oder leer ('') hotkey: 'x', hotkeyModifier: 'alt', // Ende der Konfiguration -------------------- isDElang: Cc["@mozilla.org/intl/localeservice;1"].getService(Ci.mozILocaleService).requestedLocale.includes("de"), // German Language style: ` /* appbutton */ #main-window[tabsintitlebar] #AppMenuButton { padding-inline-start: 1.6em !important; padding-inline-end: 2em !important; border-radius: 0 0 4px 4px !important; border-top: none !important; border-right: 1px solid !important; border-left: 1px solid !important; border-bottom: 1px solid !important; } #main-window[tabsintitlebar] #AppMenuButton .toolbarbutton-icon { display: none !important; } /* 'Firefox' title */ #main-window[tabsintitlebar] #AppMenuButton[label="Firefox"]::after, #main-window[tabsintitlebar] #AppMenuButton:not([label="Nightly"],[label="Firefox Nightly"],[label="Firefox Developer Edition"],[label="Firefox"],[label="Tor Browser"],[label="Tor-Browser"])::after { content: "Firefox" !important; } /* 'DevFox' title */ #main-window[tabsintitlebar] #AppMenuButton[label="Firefox Developer Edition"]::after { content: "DevFox" !important; } /* 'Nightly' title */ #main-window[tabsintitlebar] #AppMenuButton:is([label="Nightly"],[label="Firefox Nightly"])::after { content: "Nightly" !important; } /* 'Tor-Browser' title */ #main-window[tabsintitlebar] #AppMenuButton:-moz-any([label="Tor Browser"],[label="Tor-Browser"])::after { content: "TorFox" !important; } /* orange (default) */ #main-window[tabsintitlebar] #AppMenuButton { background-image: linear-gradient(rgb(247,182,82), rgb(215,98,10) 95%) !important; border-right-color:hsla(214,89%,21%,.5) !important; border-left-color: hsla(214,89%,21%,.5) !important; border-bottom-color: hsla(214,89%,21%,.5) !important; box-shadow: 0 1px 0 hsla(0,0%,100%,.2) inset, 0 0 2px 1px hsla(0,0%,100%,.25) inset, 0 1px 0 0px rgba(255,255,255,.6), 0 -1px 0 0px rgba(255,255,255,.6), 1px 0 0 0px rgba(255,255,255,.6), -1px 0 0 0px rgba(255,255,255,.6) !important; } #main-window[tabsintitlebar] #AppMenuButton:hover:not(:active):not([open]) { background-image: radial-gradient(farthest-side at center bottom, rgba(252,240,89,.5) 10%, rgba(252,240,89,0) 70%), radial-gradient(farthest-side at center bottom, rgb(236,133,0), rgba(255,229,172,0)), linear-gradient(rgb(246,170,69), rgb(209,74,0) 95%) !important; border-color: rgba(83,42,6,.9) !important; box-shadow: 0 1px 0 hsla(0,0%,100%,.15) inset, 0 0 2px 1px hsla(0,0%,100%,.5) inset, 0 -1px 0 hsla(0,0%,100%,.2), 0 1px 0 0px rgba(255,255,255,.6), 0 -1px 0 0px rgba(255,255,255,.6), 1px 0 0 0px rgba(255,255,255,.6), -1px 0 0 0px rgba(255,255,255,.6) !important; } #main-window[tabsintitlebar] #AppMenuButton:is(:hover:active,[open]) { background-image: linear-gradient(rgb(246,170,69), rgb(209,74,0) 95%) !important; box-shadow: 0 2px 3px rgba(0,0,0,.4) inset, 0 1px 1px rgba(0,0,0,.2) inset, 0 1px 0 0px rgba(255,255,255,.6), 0 -1px 0 0px rgba(255,255,255,.6), 1px 0 0 0px rgba(255,255,255,.6), -1px 0 0 0px rgba(255,255,255,.6) !important; } /* Aurora */ #main-window[tabsintitlebar] #AppMenuButton[label="Firefox Developer Edition"] { background-image: linear-gradient(hsl(208,99%,37%), hsl(214,90%,23%) 95%) !important; } #main-window[tabsintitlebar] #AppMenuButton[label="Firefox Developer Edition"]:hover:not(:active):not([open]){ background-image: radial-gradient(farthest-side at center bottom, hsla(202,100%,85%,.5) 10%, hsla(202,100%,85%,0) 70%), radial-gradient(farthest-side at center bottom, hsla(205,100%,72%,.7), hsla(205,100%,72%,0)), linear-gradient(hsl(208,98%,34%), hsl(213,87%,20%) 95%) !important; } #main-window[tabsintitlebar] #AppMenuButton[label="Firefox Developer Edition"]:is(:hover:active,[open]) { background-image: linear-gradient(hsl(208,95%,30%), hsl(214,85%,17%) 95%) !important; } /* Nightly */ #main-window[tabsintitlebar] #AppMenuButton:is([label="Nightly"],[label="Firefox Nightly"]) { background-image: linear-gradient(hsl(211,33%,32%), hsl(209,53%,10%) 95%) !important; } #main-window[tabsintitlebar] #AppMenuButton:is([label="Nightly"],[label="Firefox Nightly"]):hover:not(:active):not([open]){ background-image: radial-gradient(farthest-side at center bottom, hsla(210,48%,90%,.5) 10%, hsla(210,48%,90%,0) 70%), radial-gradient(farthest-side at center bottom, hsla(211,70%,83%,.5), hsla(211,70%,83%,0)), linear-gradient(hsl(211,33%,32%), hsl(209,53%,10%) 95%) !important; } #main-window[tabsintitlebar] #AppMenuButton:is([label="Nightly"],[label="Firefox Nightly"]):is(:hover:active,[open]) { background-image: linear-gradient(hsl(211,33%,26%), hsl(209,53%,6%) 95%) !important; } /* Tor-Browser */ #main-window[tabsintitlebar] #AppMenuButton:is([label="Tor Browser"],[label="Tor-Browser"]) { background-image: linear-gradient(rgb(153,38,211), rgb(105,19,163) 95%) !important; } #main-window[tabsintitlebar] #AppMenuButton:is([label="Tor Browser"],[label="Tor-Browser"]):hover:not(:active):not([open]){ background-image: radial-gradient(farthest-side at center bottom, rgba(240,193,255,.5) 10%, rgba(240,193,255,0) 70%), radial-gradient(farthest-side at center bottom, rgb(192,81,247), rgba(236,172,255,0)), linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%) !important; } #main-window[tabsintitlebar] #AppMenuButton:is([label="Tor Browser"],[label="Tor-Browser"]):is(:hover:active,[open]) { background-image: linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%) !important; } /*private browsing - purple */ #main-window[privatebrowsingmode=temporary][tabsintitlebar] #navigator-toolbox #AppMenuButton { background-image: linear-gradient(rgb(153,38,211), rgb(105,19,163) 95%) !important; } #main-window[privatebrowsingmode=temporary][tabsintitlebar] #navigator-toolbox #AppMenuButton:hover:not(:active):not([open]), #main-window[privatebrowsingmode=temporary][tabsintitlebar] #navigator-toolbox #PanelUI-button #PanelUI-menu-button:hover:not(:active):not([open]){ background-image: radial-gradient(farthest-side at center bottom, rgba(240,193,255,.5) 10%, rgba(240,193,255,0) 70%), radial-gradient(farthest-side at center bottom, rgb(192,81,247), rgba(236,172,255,0)), linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%) !important; } #main-window[privatebrowsingmode=temporary][tabsintitlebar] #navigator-toolbox #AppMenuButton:is(:hover:active,[open]) { background-image: linear-gradient(rgb(144,20,207), rgb(95,0,158) 95%) !important; } } `, sss: Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService), subdirPopupHash: [], subdirMenuHash: [], iconsMenu: { "file-menu": `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path fill-rule="evenodd" d="M1.25 10.255V14c0 .414.336.75.75.75h12a.75.75 0 0 0 .75-.75v-3.745h-3.534c-.46 0-.868.292-1.016.727-.716 2.1-3.684 2.1-4.4 0a1.074 1.074 0 0 0-1.016-.727H1.25Zm13.5-1.25h-3.534c-.995 0-1.879.633-2.2 1.574-.33.97-1.702.97-2.032 0a2.324 2.324 0 0 0-2.2-1.574H1.25V2A.75.75 0 0 1 2 1.25h12a.75.75 0 0 1 .75.75v7.005ZM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Z" clip-rule="evenodd"/><path d="M3 3.625C3 3.28 3.28 3 3.625 3h8.75a.625.625 0 1 1 0 1.25h-8.75A.625.625 0 0 1 3 3.625ZM3 6.625C3 6.28 3.28 6 3.625 6h8.75a.625.625 0 1 1 0 1.25h-8.75A.625.625 0 0 1 3 6.625Z"/></svg>')`, "edit-menu": 'url("chrome://global/skin/icons/edit.svg")', "view-menu": `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path fill-rule="evenodd" d="M14 1.25H2a.75.75 0 0 0-.75.75v12c0 .414.336.75.75.75h12a.75.75 0 0 0 .75-.75V2a.75.75 0 0 0-.75-.75ZM2 0a2 2 0 0 0-2 2v12a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V2a2 2 0 0 0-2-2H2Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M4.25 4.25v3.5h7.5v-3.5h-7.5ZM4 3a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4ZM10.25 11.25v.5h1.5v-.5h-1.5ZM10 10a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1h-2Z" clip-rule="evenodd"/><path d="M3 10.375c0-.345.28-.625.625-.625h3.75a.625.625 0 1 1 0 1.25h-3.75A.625.625 0 0 1 3 10.375ZM3 12.375c0-.345.28-.625.625-.625h3.75a.625.625 0 1 1 0 1.25h-3.75A.625.625 0 0 1 3 12.375Z"/></svg>')`, "history-menu": 'url("chrome://browser/skin/history.svg")', "bookmarksMenu": 'url("chrome://browser/skin/bookmark.svg")', "tools-menu": `url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path fill-rule="evenodd" d="M1 6a2 2 0 0 1 2-2h1V3a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v1h1a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V6Zm3-.75H3a.75.75 0 0 0-.75.75v2H4v-.375a.625.625 0 1 1 1.25 0V8h5.5v-.375a.625.625 0 1 1 1.25 0V8h1.75V6a.75.75 0 0 0-.75-.75H4ZM2.25 13c0 .414.336.75.75.75h10a.75.75 0 0 0 .75-.75V9.25H12v1.125a.625.625 0 1 1-1.25 0V9.25h-5.5v1.125a.625.625 0 1 1-1.25 0V9.25H2.25V13ZM10 2.25H6a.75.75 0 0 0-.75.75v1h5.5V3a.75.75 0 0 0-.75-.75Z" clip-rule="evenodd"/></svg>')`, "helpMenu": 'url("chrome://global/skin/icons/help.svg")', }, toolbar: { // Submenüs des Hauptmenüs definieren; Separator einfügen mit {name: 'separator'} subdirs: [{ name: this.isDElang ? 'Firefox Verzeichnisse' : 'Firefox Folders', id: 'AMfolders', image: "chrome://browser/skin/save.svg" }, { name: this.isDElang ? 'Firefox Profil-Dateien' : 'Firefox Profile', id: 'AMprofiles', image: "chrome://devtools/skin/images/folder.svg" }, { name: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', id: 'AMfeatures', image: "chrome://branding/content/about-logo.svg" }, { name: 'about:', id: 'AMabout', image: "chrome://global/skin/icons/developer.svg" }], apps: [{ // Untermenü Firefox Profil-Dateien name: 'userChrome.css', root: 'ProfD', path: '\\chrome\\userChrome.css', subdir: this.isDElang ? 'Firefox Profil-Dateien' : 'Firefox Profile', image: 'data:image/svg+xml;utf8,<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M725.333333 85.333333l213.333334 213.333334v170.666666h-85.333334v-135.253333L689.92 170.666667H170.666667v298.666666H85.333333V85.333333zM256 768v42.666667a42.666667 42.666667 0 0 1-85.333333 0v-170.666667a42.666667 42.666667 0 0 1 85.333333 0v42.666667h85.333333v-42.666667a128 128 0 0 0-256 0v170.666667a128 128 0 0 0 256 0v-42.666667z m256-85.333333a42.666667 42.666667 0 1 1 42.666667-42.666667h85.333333a128 128 0 1 0-128 128 42.666667 42.666667 0 1 1-42.666667 42.666667h-85.333333a128 128 0 1 0 128-128z m298.666667 0a42.666667 42.666667 0 1 1 42.666666-42.666667h85.333334a128 128 0 1 0-128 128 42.666667 42.666667 0 1 1-42.666667 42.666667h-85.333333a128 128 0 1 0 128-128z" p-id="7385"/></svg>' }, { name: 'userContent.css', root: 'ProfD', path: '\\chrome\\userContent.css', subdir: this.isDElang ? 'Firefox Profil-Dateien' : 'Firefox Profile', image: 'data:image/svg+xml;utf8,<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M725.333333 85.333333l213.333334 213.333334v170.666666h-85.333334v-135.253333L689.92 170.666667H170.666667v298.666666H85.333333V85.333333zM256 768v42.666667a42.666667 42.666667 0 0 1-85.333333 0v-170.666667a42.666667 42.666667 0 0 1 85.333333 0v42.666667h85.333333v-42.666667a128 128 0 0 0-256 0v170.666667a128 128 0 0 0 256 0v-42.666667z m256-85.333333a42.666667 42.666667 0 1 1 42.666667-42.666667h85.333333a128 128 0 1 0-128 128 42.666667 42.666667 0 1 1-42.666667 42.666667h-85.333333a128 128 0 1 0 128-128z m298.666667 0a42.666667 42.666667 0 1 1 42.666666-42.666667h85.333334a128 128 0 1 0-128 128 42.666667 42.666667 0 1 1-42.666667 42.666667h-85.333333a128 128 0 1 0 128-128z" p-id="7385"/></svg>' }, { name: 'userChrome.js', root: 'ProfD', path: '\\chrome\\userChrome.js', subdir: this.isDElang ? 'Firefox Profil-Dateien' : 'Firefox Profile', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M5 3.55h1.98v5.66c0 2.51-1.2 3.39-3.12 3.39-.47 0-1.07-.08-1.46-.21l.22-1.61c.28.1.64.16 1.02.16.84 0 1.36-.38 1.36-1.74V3.55zm3.7 6.87c.54.28 1.36.54 2.22.54.9 0 1.4-.37 1.4-.95 0-.54-.43-.87-1.49-1.24C9.37 8.24 8.4 7.44 8.4 6.15c0-1.5 1.27-2.65 3.33-2.65 1 0 1.73.21 2.26.46l-.45 1.58a4.13 4.13 0 00-1.83-.42c-.87 0-1.28.42-1.28.86 0 .56.49.81 1.63 1.26 1.56.57 2.28 1.37 2.28 2.63 0 1.48-1.13 2.73-3.55 2.73-1 0-1.99-.28-2.49-.55l.4-1.63z" /></svg>' }, { name: 'prefs.js', root: 'ProfD', path: '\\prefs.js', subdir: this.isDElang ? 'Firefox Profil-Dateien' : 'Firefox Profile', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M5 3.55h1.98v5.66c0 2.51-1.2 3.39-3.12 3.39-.47 0-1.07-.08-1.46-.21l.22-1.61c.28.1.64.16 1.02.16.84 0 1.36-.38 1.36-1.74V3.55zm3.7 6.87c.54.28 1.36.54 2.22.54.9 0 1.4-.37 1.4-.95 0-.54-.43-.87-1.49-1.24C9.37 8.24 8.4 7.44 8.4 6.15c0-1.5 1.27-2.65 3.33-2.65 1 0 1.73.21 2.26.46l-.45 1.58a4.13 4.13 0 00-1.83-.42c-.87 0-1.28.42-1.28.86 0 .56.49.81 1.63 1.26 1.56.57 2.28 1.37 2.28 2.63 0 1.48-1.13 2.73-3.55 2.73-1 0-1.99-.28-2.49-.55l.4-1.63z" /></svg>' }, { name: 'user.js', root: 'ProfD', path: '\\user.js', subdir: this.isDElang ? 'Firefox Profil-Dateien' : 'Firefox Profile', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M5 3.55h1.98v5.66c0 2.51-1.2 3.39-3.12 3.39-.47 0-1.07-.08-1.46-.21l.22-1.61c.28.1.64.16 1.02.16.84 0 1.36-.38 1.36-1.74V3.55zm3.7 6.87c.54.28 1.36.54 2.22.54.9 0 1.4-.37 1.4-.95 0-.54-.43-.87-1.49-1.24C9.37 8.24 8.4 7.44 8.4 6.15c0-1.5 1.27-2.65 3.33-2.65 1 0 1.73.21 2.26.46l-.45 1.58a4.13 4.13 0 00-1.83-.42c-.87 0-1.28.42-1.28.86 0 .56.49.81 1.63 1.26 1.56.57 2.28 1.37 2.28 2.63 0 1.48-1.13 2.73-3.55 2.73-1 0-1.99-.28-2.49-.55l.4-1.63z" /></svg>' }, // Untermenü Firefox Verzeichnisse { name: this.isDElang ? 'Profil' : 'Profile', root: 'ProfD', path: '\\', subdir: this.isDElang ? 'Firefox Profil-Dateien' : 'Firefox Profile', image: "chrome://devtools/skin/images/folder.svg" }, { name: 'chrome', root: 'ProfD', path: '\\chrome', subdir: this.isDElang ? 'Firefox Verzeichnisse' : 'Firefox Folders', image: 'chrome://devtools/skin/images/browsers/chrome.svg' }, { name: 'CSS', root: 'ProfD', path: '\\chrome\\CSS', subdir: this.isDElang ? 'Firefox Verzeichnisse' : 'Firefox Folders', image: 'data:image/svg+xml;utf8,<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M725.333333 85.333333l213.333334 213.333334v170.666666h-85.333334v-135.253333L689.92 170.666667H170.666667v298.666666H85.333333V85.333333zM256 768v42.666667a42.666667 42.666667 0 0 1-85.333333 0v-170.666667a42.666667 42.666667 0 0 1 85.333333 0v42.666667h85.333333v-42.666667a128 128 0 0 0-256 0v170.666667a128 128 0 0 0 256 0v-42.666667z m256-85.333333a42.666667 42.666667 0 1 1 42.666667-42.666667h85.333333a128 128 0 1 0-128 128 42.666667 42.666667 0 1 1-42.666667 42.666667h-85.333333a128 128 0 1 0 128-128z m298.666667 0a42.666667 42.666667 0 1 1 42.666666-42.666667h85.333334a128 128 0 1 0-128 128 42.666667 42.666667 0 1 1-42.666667 42.666667h-85.333333a128 128 0 1 0 128-128z" p-id="7385"/></svg>' }, { name: 'JS', root: 'ProfD', path: '\\chrome\\JS', subdir: this.isDElang ? 'Firefox Verzeichnisse' : 'Firefox Folders', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M5 3.55h1.98v5.66c0 2.51-1.2 3.39-3.12 3.39-.47 0-1.07-.08-1.46-.21l.22-1.61c.28.1.64.16 1.02.16.84 0 1.36-.38 1.36-1.74V3.55zm3.7 6.87c.54.28 1.36.54 2.22.54.9 0 1.4-.37 1.4-.95 0-.54-.43-.87-1.49-1.24C9.37 8.24 8.4 7.44 8.4 6.15c0-1.5 1.27-2.65 3.33-2.65 1 0 1.73.21 2.26.46l-.45 1.58a4.13 4.13 0 00-1.83-.42c-.87 0-1.28.42-1.28.86 0 .56.49.81 1.63 1.26 1.56.57 2.28 1.37 2.28 2.63 0 1.48-1.13 2.73-3.55 2.73-1 0-1.99-.28-2.49-.55l.4-1.63z" /></svg>' }, { name: 'Addons', root: 'ProfD', path: '\\extensions', subdir: this.isDElang ? 'Firefox Verzeichnisse' : 'Firefox Folders', image: 'chrome://mozapps/skin/extensions/category-extensions.svg' }, { name: this.isDElang ? 'Programm' : "core/browser", root: 'CurProcD', path: '\\', subdir: this.isDElang ? 'Firefox Verzeichnisse' : 'Firefox Folders', image: 'chrome://branding/content/about-logo.svg' }, { name: 'Startup Cache', root: 'ProfLD', path: '\\startupCache', subdir: this.isDElang ? 'Firefox Verzeichnisse' : 'Firefox Folders', image: 'chrome://mozapps/skin/extensions/category-discover.svg' } ], configs: [ // Untermenü Firefox Funktionen { name: this.isDElang ? 'Symbolleiste anpassen…' : 'Customize toolbar…', command: "gCustomizeMode.enter()", subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'chrome://browser/skin/customize.svg' }, { name: this.isDElang ? 'Neustart im abgesicherten Modus' : 'Reatart in Troubleshooting Mode', command: "safeModeRestart();", subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'chrome://devtools/skin/images/debugging-workers.svg' }, { name: this.isDElang ? 'Browser-Konsole' : 'Browser Console', command: "var { require } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs', {});\ var { BrowserConsoleManager } = require('resource://devtools/client/webconsole/browser-console-manager');\ BrowserConsoleManager.openBrowserConsoleOrFocus();", subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'chrome://devtools/skin/images/tool-webconsole.svg' }, { name: this.isDElang ? 'Entwickler-Werkzeuge' : 'Web Developer Tools', command: "var { require } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs', {});\ var { gDevToolsBrowser } = require('devtools/client/framework/devtools-browser');\ gDevToolsBrowser.toggleToolboxCommand(window.gBrowser, Cu.now());", subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'chrome://global/skin/icons/performance.svg', }, { name: this.isDElang ? 'Browser-Werkzeuge' : 'Browser Toolbox', command: "var { require } = ChromeUtils.importESModule('resource://devtools/shared/loader/Loader.sys.mjs', {});\ var { BrowserToolboxLauncher } = require('resource://devtools/client/framework/browser-toolbox/Launcher.sys.mjs');\ BrowserToolboxLauncher.init();", subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'chrome://devtools/skin/images/command-frames.svg', }, { name: this.isDElang ? 'Firefox synchronisieren' : 'Firefox synchronise', command: "gSync.openPrefs('menubar');", subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'chrome://browser/skin/sync.svg' }, { name: this.isDElang ? 'Zugangsdaten und Passwörter' : 'Logins & Passwords', command: "LoginHelper.openPasswordManager(window, { entryPoint: 'mainmenu' })", tooltiptext: 'about:logins', subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'chrome://browser/skin/login.svg' }, { name: this.isDElang ? 'Task Manager' : 'Task Manager', command: "switchToTabHavingURI('about:processes', true)", tooltiptext: 'about:processes', subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M5 5a3 3 0 0 1 6 0v7a3 3 0 1 1-6 0V5Z"/><path fill-rule="evenodd" d="M6.369 0c.345 0 .625.28.625.625v1.371a1.006 1.006 0 0 0 2.012 0V.626a.625.625 0 1 1 1.25 0v1.37a2.256 2.256 0 1 1-4.512 0V.626c0-.346.28-.626.625-.626ZM2.627 1c.345 0 .625.28.625.626v1.871c0 .76.616 1.376 1.376 1.376h6.745c.76 0 1.376-.616 1.376-1.376V1.626a.625.625 0 0 1 1.25 0v1.871a2.627 2.627 0 0 1-2.626 2.627H4.628A2.627 2.627 0 0 1 2 3.497V1.626c0-.345.28-.625.626-.625ZM0 8.63c0-.345.28-.625.625-.625h14.75a.625.625 0 1 1 0 1.25H.625A.625.625 0 0 1 0 8.63Zm4.628 3.498c-.76 0-1.376.616-1.376 1.375v1.872a.625.625 0 1 1-1.25 0v-1.872a2.627 2.627 0 0 1 2.626-2.626h6.745a2.627 2.627 0 0 1 2.626 2.626v1.872a.625.625 0 1 1-1.25 0v-1.872c0-.76-.616-1.375-1.376-1.375H4.628Z" clip-rule="evenodd"/></svg>' }, { name: this.isDElang ? 'Offline arbeiten' : 'Work Offline', command: "BrowserOffline.toggleOfflineStatus();", subdir: this.isDElang ? 'Firefox Funktionen' : 'Firefox Features', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path fill-rule="evenodd" d="m12.499 9.154 1.326-1.326a4 4 0 0 0-5.657-5.656L6.842 3.497a.625.625 0 0 0 0 .884l4.773 4.773c.244.244.64.244.884 0ZM9.052 3.055a2.75 2.75 0 0 1 3.889 3.89l-.878.878-3.89-3.89.879-.878ZM3.497 6.842 2.172 8.168a4 4 0 0 0 5.656 5.657l1.326-1.326a.625.625 0 0 0 0-.884L4.381 6.842a.625.625 0 0 0-.884 0Zm3.448 6.099a2.75 2.75 0 0 1-3.89-3.89l.876-.875 3.889 3.89-.875.875Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M15.812.188a.625.625 0 0 1 0 .884l-2 2a.625.625 0 1 1-.884-.884l2-2a.625.625 0 0 1 .884 0Zm-8.37 6.37a.625.625 0 0 1 0 .884l-1.5 1.5a.625.625 0 0 1-.884-.884l1.5-1.5a.625.625 0 0 1 .884 0Zm2 2a.625.625 0 0 1 0 .884l-1.5 1.5a.625.625 0 1 1-.884-.884l1.5-1.5a.625.625 0 0 1 .884 0Zm-6.5 4.5a.625.625 0 0 1 0 .884l-1.87 1.87a.625.625 0 0 1-.884-.884l1.87-1.87a.625.625 0 0 1 .884 0Z" clip-rule="evenodd"/></svg>' }, // Untermenü about: /* { name: 'separator' }, */ { name: 'about:about', command: "openTrustedLinkIn('about:about', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://branding/content/about-logo.svg' }, { name: 'about:cache', command: "openTrustedLinkIn('about:cache', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/developer.svg' }, { name: 'about:certificate', command: "openTrustedLinkIn('about:certificate', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="16" height="16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M25 2C12.296875 2 2 12.296875 2 25C2 37.703125 12.296875 48 25 48C37.703125 48 48 37.703125 48 25C48 12.296875 37.703125 2 25 2 Z M 25 4C36.578125 4 46 13.421875 46 25C46 36.578125 36.578125 46 25 46C13.421875 46 4 36.578125 4 25C4 13.421875 13.421875 4 25 4 Z M 25 8C20.035156 8 16 12.035156 16 17L16 21L22 21L22 17C22 15.347656 23.347656 14 25 14C26.652344 14 28 15.347656 28 17L28 21L34 21L34 17C34 12.035156 29.964844 8 25 8 Z M 25 10C28.867188 10 32 13.132813 32 17L32 19L30 19L30 17C30 14.238281 27.761719 12 25 12C22.238281 12 20 14.238281 20 17L20 19L18 19L18 17C18 13.132813 21.132813 10 25 10 Z M 16 22C13.792969 22 12 23.792969 12 26L12 36C12 38.207031 13.792969 40 16 40L34 40C36.207031 40 38 38.207031 38 36L38 26C38 23.792969 36.207031 22 34 22 Z M 16 24L34 24C35.105469 24 36 24.894531 36 26L36 36C36 37.105469 35.105469 38 34 38L16 38C14.894531 38 14 37.105469 14 36L14 26C14 24.894531 14.894531 24 16 24 Z M 17 26C16.449219 26 16 26.449219 16 27L16 35C16 35.550781 16.449219 36 17 36C17.550781 36 18 35.550781 18 35L18 27C18 26.449219 17.550781 26 17 26 Z M 25 26C23.894531 26 23 26.894531 23 28C23 28.714844 23.382813 29.375 24 29.730469L24 35L26 35L26 29.730469C26.617188 29.371094 27 28.714844 27 28C27 26.894531 26.105469 26 25 26Z" /></svg>' }, { name: 'about:checkerboard', command: "openTrustedLinkIn('about:checkerboard', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/clipboard.svg' }, { name: 'about:compat', command: "openTrustedLinkIn('about:compat', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'resource://devtools-shared-images/alert-small.svg' }, { name: 'about:config', command: "openTrustedLinkIn('about:config', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/settings.svg' }, { name: 'about:crashes', command: "openTrustedLinkIn('about:crashes', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/loading.svg' }, { name: 'about:debugging', command: "openTrustedLinkIn('about:debugging', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M5 5a3 3 0 0 1 6 0v7a3 3 0 1 1-6 0V5Z"/><path fill-rule="evenodd" d="M6.369 0c.345 0 .625.28.625.625v1.371a1.006 1.006 0 0 0 2.012 0V.626a.625.625 0 1 1 1.25 0v1.37a2.256 2.256 0 1 1-4.512 0V.626c0-.346.28-.626.625-.626ZM2.627 1c.345 0 .625.28.625.626v1.871c0 .76.616 1.376 1.376 1.376h6.745c.76 0 1.376-.616 1.376-1.376V1.626a.625.625 0 0 1 1.25 0v1.871a2.627 2.627 0 0 1-2.626 2.627H4.628A2.627 2.627 0 0 1 2 3.497V1.626c0-.345.28-.625.626-.625ZM0 8.63c0-.345.28-.625.625-.625h14.75a.625.625 0 1 1 0 1.25H.625A.625.625 0 0 1 0 8.63Zm4.628 3.498c-.76 0-1.376.616-1.376 1.375v1.872a.625.625 0 1 1-1.25 0v-1.872a2.627 2.627 0 0 1 2.626-2.626h6.745a2.627 2.627 0 0 1 2.626 2.626v1.872a.625.625 0 1 1-1.25 0v-1.872c0-.76-.616-1.375-1.376-1.375H4.628Z" clip-rule="evenodd"/></svg>' }, { name: 'about:downloads', command: "openTrustedLinkIn('about:downloads', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/downloads/downloads.svg' }, { name: 'about:logging', command: "openTrustedLinkIn('about:logging', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://devtools/skin/images/tool-webconsole.svg' }, { name: 'about:logins', command: "openTrustedLinkIn('about:logins', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/login.svg' }, { name: 'about:memory', command: "openTrustedLinkIn('about:memory', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://devtools/skin/images/tool-memory.svg' }, { name: 'about:networking', command: "openTrustedLinkIn('about:networking', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path fill-rule="evenodd" d="m12.499 9.154 1.326-1.326a4 4 0 0 0-5.657-5.656L6.842 3.497a.625.625 0 0 0 0 .884l4.773 4.773c.244.244.64.244.884 0ZM9.052 3.055a2.75 2.75 0 0 1 3.889 3.89l-.878.878-3.89-3.89.879-.878ZM3.497 6.842 2.172 8.168a4 4 0 0 0 5.656 5.657l1.326-1.326a.625.625 0 0 0 0-.884L4.381 6.842a.625.625 0 0 0-.884 0Zm3.448 6.099a2.75 2.75 0 0 1-3.89-3.89l.876-.875 3.889 3.89-.875.875Z" clip-rule="evenodd"/><path fill-rule="evenodd" d="M15.812.188a.625.625 0 0 1 0 .884l-2 2a.625.625 0 1 1-.884-.884l2-2a.625.625 0 0 1 .884 0Zm-8.37 6.37a.625.625 0 0 1 0 .884l-1.5 1.5a.625.625 0 0 1-.884-.884l1.5-1.5a.625.625 0 0 1 .884 0Zm2 2a.625.625 0 0 1 0 .884l-1.5 1.5a.625.625 0 1 1-.884-.884l1.5-1.5a.625.625 0 0 1 .884 0Zm-6.5 4.5a.625.625 0 0 1 0 .884l-1.87 1.87a.625.625 0 0 1-.884-.884l1.87-1.87a.625.625 0 0 1 .884 0Z" clip-rule="evenodd"/></svg>' }, { name: 'about:processes', command: "openTrustedLinkIn('about:processes', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", tooltiptext: 'Task Manager', subdir: 'about:', image:'chrome://global/skin/icons/performance.svg' }, { name: 'about:policies', command: "openTrustedLinkIn('about:policies', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/content/policies/policies-active.svg' }, { name: 'about:profiles', command: "openTrustedLinkIn('about:profiles', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/info.svg' }, { name: 'about:profiling', command: "openTrustedLinkIn('about:profiling', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://devtools/skin/images/profiler-stopwatch.svg' }, { name: 'about:protections', command: "openTrustedLinkIn('about:protections', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/tracking-protection.svg' }, { name: 'about:rights', command: "openTrustedLinkIn('about:rights', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/illustrations/about-rights.svg' }, { name: 'about:serviceworkers', command: "openTrustedLinkIn('about:serviceworkers', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/developer.svg' }, { name: 'about:studies', command: "openTrustedLinkIn('about:studies', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/ion.svg' }, { name: 'about:support', command: "openTrustedLinkIn('about:support', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://devtools/skin/images/browsers/firefox.svg' }, { name: 'about:sync-log', command: "openTrustedLinkIn('about:sync-log', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/sync.svg' }, { name: 'about:telemetry', command: "openTrustedLinkIn('about:telemetry', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/arrow-down.svg' }, { name: 'about:third-party', command: "openTrustedLinkIn('about:third-party', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/library.svg' }, { name: 'about:unloads', command: "openTrustedLinkIn('about:unloads', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", tooltiptext: 'Tabs entladen', subdir: 'about:', image:'chrome://mozapps/skin/extensions/category-available.svg' }, { name: 'about:url-classifier', command: "openTrustedLinkIn('about:url-classifier', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://global/skin/icons/link.svg' }, { name: 'about:webrtc', command: "openTrustedLinkIn('about:webrtc', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/notification-icons/screen.svg' }, { name: 'about:windows-messages', command: "openTrustedLinkIn('about:windows-messages', gBrowser.selectedTab.isEmpty ? 'current' : 'tab')", subdir: 'about:', image:'chrome://browser/skin/window.svg' }, // Hauptmenü Einträge { name: this.isDElang ? 'Neues privates Fenster' : 'New Private Window', command: "OpenBrowserWindow({private: true});", id: 'AMprivate', image: "chrome://browser/skin/privateBrowsing.svg" }, { name: 'separator' }, { name: this.isDElang ? 'Einstellungen' : 'Firefox Settings', command: "openPreferences();", id: 'AMsettings', image: "chrome://devtools/skin/images/settings.svg", }, { name: 'Add-ons', command: "BrowserAddonUI.openAddonsMgr();", id: 'AMaddons', image: "chrome://mozapps/skin/extensions/category-extensions.svg", }, { name: 'separator' }, { name: this.isDElang ? 'Lesezeichen-Verwaltung' : 'Manage Bookmarks', command: "PlacesCommandHook.showPlacesOrganizer('AllBookmarks');", id: 'AMbookmarks', image: "chrome://browser/skin/bookmark-star-on-tray.svg", }, /* { name: 'separator' }, */ { name: this.isDElang ? 'Chronik' : 'History', command: "PlacesCommandHook.showPlacesOrganizer('History');", id: 'AMhistory', image: "chrome://browser/skin/history.svg", }, { name: this.isDElang ? 'Downloads' : 'Downloads', command: "BrowserCommands.downloadsUI();", id: 'AMdownloads', image: "chrome://browser/skin/downloads/download-summary.svg", }, { name: this.isDElang ? 'Seite speichern unter…' : 'Save Page as…', command: "saveBrowser(gBrowser.selectedBrowser)", id: 'AMsave', image: "chrome://browser/skin/save.svg", }, { name: this.isDElang ? 'Chronik löschen' : 'Clear browsing data and cookies', command: "Sanitizer.showUI(window);", id: 'AMsanitize', image: "chrome://devtools/skin/images/clear.svg", }, { name: 'separator', }, { name: this.isDElang ? 'Neustart' : 'Restart', tooltiptext: this.isDElang ? 'userChrome.js-Cache wird geleert' : 'Restart and recreate the quick start cache.', // command: "Services.appinfo.invalidateCachesOnRestart(); BrowserUtils.restartApplication();", command: 'Services.appinfo.invalidateCachesOnRestart(); \ Services.startup.quit(Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);', id: 'AMreboot', image: "chrome://devtools/skin/images/reload.svg", }, { name: this.isDElang ? 'Beenden' : "Exit", command: "goQuitApplication(event);", id: 'AMquit', image: 'data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="context-fill" fill-opacity="context-fill-opacity"><path d="M5.561 3.112c-.132-.32-.5-.474-.807-.314a7 7 0 1 0 6.492 0c-.306-.16-.675-.006-.807.314s.021.683.325.85a5.747 5.747 0 1 1-5.528 0c.303-.167.457-.53.325-.85Z"/><path fill-rule="evenodd" d="M8 1.375c.345 0 .625.28.625.625v6a.625.625 0 1 1-1.25 0V2c0-.345.28-.625.625-.625Z" clip-rule="evenodd"/></svg>' }, /* { name: 'separator', }, */ ] }, _externalAppPopup: null, _isready: false, init: function() { this.handleRelativePath(this.toolbar.apps); const XULNS = 'http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'; var ExternalAppBtn = document.createElementNS(XULNS, 'toolbarbutton'); ExternalAppBtn.id = "AppMenuButton"; ExternalAppBtn.className = "toolbarbutton-1"; ExternalAppBtn.setAttribute("label", AppConstants.MOZ_APP_DISPLAYNAME_DO_NOT_USE); ExternalAppBtn.setAttribute("onclick", "event.preventDefault();event.stopPropagation();"); ExternalAppBtn.setAttribute("tooltiptext", AppConstants.MOZ_APP_DISPLAYNAME_DO_NOT_USE + " " + (this.isDElang ? "Menü" : "Menu")); ExternalAppBtn.setAttribute("type", "menu"); ExternalAppBtn.setAttribute("removable", "true"); if (Appmenu.isButton) { const newURIParam = { aURL: 'data:text/css,' + encodeURIComponent(this.style), aOriginCharset: null, aBaseURI: null }; const cssUri = Services.io.newURI(newURIParam.aURL, newURIParam.aOriginCharset, newURIParam.aBaseURI); if (!this.sss.sheetRegistered(cssUri, this.sss.USER_SHEET)) this.sss.loadAndRegisterSheet(cssUri, this.sss.USER_SHEET); } else { ExternalAppBtn.style.listStyleImage = 'url("chrome://browser/skin/menu.svg")'; ExternalAppBtn.style.MozContextProperties = "fill"; ExternalAppBtn.style.setProperty("fill", "currentColor"); } if (Appmenu.isUrlbar === 1) { var navBar = document.getElementById("nav-bar-customization-target"); navBar.insertBefore(ExternalAppBtn, navBar.firstChild); } else if (Appmenu.isUrlbar === 2) { var menubar = document.getElementById("toolbar-menubar"); menubar.insertBefore(ExternalAppBtn, menubar.firstChild); } else { var TabsToolbar = document.getElementById("TabsToolbar"); TabsToolbar.insertBefore(ExternalAppBtn, TabsToolbar.firstChild); } var ExternalAppPopup = document.createElementNS(XULNS, 'menupopup'); //ExternalAppPopup.setAttribute('onpopupshowing', 'event.stopPropagation(); Appmenu.onpopupshowing();'); ExternalAppPopup.setAttribute('id', 'AMpopup'); this._externalAppPopup = ExternalAppPopup; ExternalAppBtn.appendChild(ExternalAppPopup); Appmenu.onpopupshowing(); // Menü mit Tastaturkürzel öffnen if (Appmenu.hotkey) { let key = document.createXULElement('key'); key.id = 'key_AppMenuPopup'; key.setAttribute('key', Appmenu.hotkey); if (Appmenu.hotkeyModifier) key.setAttribute('modifiers', Appmenu.hotkeyModifier); key.setAttribute('oncommand', 'document.getElementById("AMpopup").openPopup();'); document.getElementById('mainKeyset').appendChild(key); } }, onpopupshowing: function() { if (this._isready) return; if (this._externalAppPopup === null) return; var ExternalAppPopup = this._externalAppPopup; for (let subdir of this.toolbar.subdirs) { if (subdir.name == 'separator') { ExternalAppPopup.appendChild(document.createXULElement('menuseparator')); } else { var subdirItem = ExternalAppPopup.appendChild(document.createXULElement('menu')); var subdirItemPopup = subdirItem.appendChild(document.createXULElement('menupopup')); if (subdir.id) subdirItem.setAttribute('id', subdir.id); subdirItem.setAttribute('class', 'menu-iconic'); subdirItem.setAttribute('label', subdir.name); subdirItem.setAttribute('image', subdir.image); Appmenu.subdirPopupHash[subdir.name] = subdirItemPopup; Appmenu.subdirMenuHash[subdir.name] = subdirItem; } } for (let app of this.toolbar.apps) { var appItem; if (app.name == 'separator') { appItem = document.createXULElement('menuseparator'); } else { appItem = document.createXULElement('menuitem'); appItem.setAttribute('class', 'menuitem-iconic'); appItem.setAttribute('label', app.name); appItem.setAttribute('image', app.image); appItem.setAttribute('oncommand', "Appmenu.exec(this.path, this.args);"); appItem.setAttribute('tooltiptext', app.name); appItem.path = app.path; appItem.args = app.args; } if (app.subdir && Appmenu.subdirPopupHash[app.subdir]) Appmenu.subdirPopupHash[app.subdir].appendChild(appItem); else ExternalAppPopup.appendChild(appItem); } for (let config of this.toolbar.configs) { var configItem; if (config.name == 'separator') { configItem = document.createXULElement('menuseparator'); } else { configItem = ExternalAppPopup.appendChild(document.createXULElement('menuitem')); configItem.setAttribute('class', 'menuitem-iconic'); configItem.setAttribute('label', config.name); configItem.setAttribute('image', config.image); configItem.setAttribute('oncommand', config.command); if (config.tooltiptext) { configItem.setAttribute('tooltiptext', config.tooltiptext); } else { configItem.setAttribute('tooltiptext', config.name); } configItem.setAttribute('id', config.id); } if (config.subdir && Appmenu.subdirPopupHash[config.subdir]) { Appmenu.subdirPopupHash[config.subdir].appendChild(configItem); } else { ExternalAppPopup.appendChild(configItem); } } if (this.autohideEmptySubDirs) { for (let i = 0; i < Appmenu.subdirPopupHash.length; i++) { if (Appmenu.subdirPopupHash[i].hasChildNodes()) { continue; } else { Appmenu.subdirMenuHash[i].setAttribute("hidden", "true"); } } } if (this.moveSubDirstoBottom) { let i = ExternalAppPopup.childNodes.length; while (ExternalAppPopup.firstChild.getAttribute('class') != 'menuitem-iconic' && i-- != 0) { ExternalAppPopup.appendChild(ExternalAppPopup.firstChild); } } this._isready = true; }, handleRelativePath: function(apps) { for (let app of apps) { if (app.path) { app.path = app.path.replace(/\//g, '\\'); var ffdir = Cc['@mozilla.org/file/directory_service;1'].getService(Ci.nsIProperties).get(app.root, Ci.nsIFile).path; if (/^(\\)/.test(app.path)) { app.path = ffdir + app.path; } } } }, exec: function(path, args) { args = args || []; var args_t = args.slice(0); for (let arg of args_t) { arg = arg.replace(/%u/g, gBrowser.currentURI.spec); } var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); file.initWithPath(path); if (!file.exists()) { //Cu.reportError('Datei nicht gefunden: ' + path); alert('Datei nicht gefunden: ' + path); return; } if (file.isExecutable() && !path.endsWith('.js')) { var process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess); process.init(file); process.run(false, args_t, args_t.length); } else if (file.isFile()) { if (this.editor) { let UI = Cc["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter); UI.charset = window.navigator.platform.toLowerCase().includes('win') ? 'Shift_JIS' : 'UTF-8'; let path = UI.ConvertFromUnicode(file.path); let app = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); app.initWithPath(this.editor); let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess); process.init(app); process.run(false, [path], 1); } else { file.launch(); } } else if (file.isDirectory()) { if (this.fileManager) { let args=[this.FMParameter,path]; let app = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile); app.initWithPath(this.fileManager); let process = Cc['@mozilla.org/process/util;1'].createInstance(Ci.nsIProcess); process.init(app); process.run(false, args, args.length); } else { file.launch(); } } }, editmenu: async () => { // ZUGEFÜGT! if (document.getElementById("main-menubar").querySelectorAll(":scope > script").length >= 1) { const _AMjs = {}; _AMjs.uri = "data:application/x-javascript;charset=UTF-8,"; _AMjs.res = await fetch(document.getElementById("main-menubar").querySelectorAll(":scope > script")[0].src); _AMjs.text = (await _AMjs.res.text()).replace(/main-menubar/, "AMpopup"); const scriptloader = Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader); scriptloader.loadSubScript(_AMjs.uri + encodeURIComponent(_AMjs.text), this); }; setTimeout(function() { var pane1 = document.getElementById('AMpopup'); var item2 = document.getElementById('AMfolders'); // Menüs einfügen for (var menu of Array.from(document.getElementById("main-menubar").querySelectorAll(":scope > menu"))) { var popup = menu.menupopup; popup.remove(); menu.textContent = menu.renderedOnce = ""; var img = Appmenu.iconsMenu[menu.id]; if (img) { menu.className = "menu-iconic"; menu.style.listStyleImage = img; } menu.render; menu.append(popup); menu.disablrd = false; pane1.insertBefore(menu, item2); } var separator = document.createXULElement('menuseparator'); separator.setAttribute('flex', '1'); pane1.insertBefore(separator, item2); // Script-Menüs einfügen var ids = ['usercssloader-menu', 'ExtraConfigMenu', 'no-eom-button']; for (var id of ids) { var _id = document.getElementById(id); if (_id) pane1.insertBefore(_id, item2); } }, 2e3); } // ZUGEFÜGT! }; if (window.gBrowser) { Appmenu.init(); if (Appmenu.isEditMenu) Appmenu.editmenu(); }
Жизнь иногда такое выкидывает, что хочется подобрать...
На форуме
Dumby посмотрите оконную виджет кнопочку-индикатор. Прослушки глобальные, действуют в любом месте окна, т.е. жестко с кнопкой не связаны. Цель: вместо этих прослушек добавить такую, чтобы кнопка делала opacity = 0.5 или disabled = true, если буфер обмена пуст и opacity = 1 или disabled = false? если буфер обмена не пуст.
Или с событием 'copy' такое не прокатит и нужно ждать поддержки такой фишки?
location.href.endsWith("://browser/content/browser.xhtml") && (async () => CustomizableUI.createWidget({ id: "test_button", localized: false, get icon() { let icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAABY0lEQVR4nGNgwANeL2EofrWUoYiBXPBoHsMfECbbgLszGf6DMNkGXJvM8B+EyTYgODXuPwiTpit0FTNv0ip1noTltsJhU/6DsED0Ylve6MXqIDm8ennjl8fyxi39yh+35D9/7KL/ArEL/gvEzPsvGD33v2DU7P+CkTO/CodPi8VpAH/sglUCMfPhGoQiZ/0XipjxXzh8GtglIqGT/ouGTFiF04CP29T2f9qu/h8f/rhNbR9OA77sMXz5ZY/hf3z4826D51g1fzpkI/r9oPV/XPjjLhMEe7epMIYBv486+/w66vQfhL8fsgfTyPjtVn04+/dhJ09MA054tvw56fUfhD/uMgfTyPjNJk04+/cJryYMA/6e9j/+74z/fxB+s0kDTCPj1+tk//897Qtm/z3jdxTDgP/nQrL+nwua+/9c0KG368S//j8b9O7/uaBfYHw26N3HzfIffx9zPg1RE5KFMyZIBQA3pi1KgcfhAAAAAABJRU5ErkJggg"; let subst = this.id.toLowerCase() + "-icon"; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newURI(icon)); delete this.icon; return this.icon = "resource://" + subst; }, onCreated(btn) { btn.ownerGlobal.addEventListener('mousedown', () => btn.style.opacity = 0.5); btn.ownerGlobal.addEventListener('mouseup', () => btn.style.opacity = 1); btn.setAttribute("image", this.icon); }, }))();
Отсутствует
Или с событием 'copy' такое не прокатит
Какое «такое»? Событие "copy" наступит когда случится копирование
в этом окне, а значит в этом процессе, не в контентских процессах.
А даже если слушать и в них, то это всё равно всего лишь copy.
нужно ждать поддержки такой фишки?
Да, такая фишка была бы здесь полезна, только это настораживает:
«
If the clipboard contents are changed outside the user agent,
then the clipboardchange event MUST fire when the user agent regains focus.
»
Хотел попробовать записать какой-то аналог на ctypes,
но далеко не продвинулся, то ли в ctypes что-то сломано,
то ли руки кривые, но при попытке использовать функцию
(процедуру, как в осуществлении SetWindowsHookExW() или SetWindowLongA())
браузер валится с MozCrashReason: *** Compartment mismatch 0 vs. xxxxxxxx at argument 0
Ладно, если это так важно, то можно было бы и интервал подрядить на сколько не жалко.
Но как узнать что буфер обмена пуст? В смысле, какое состояние буфера считать пустым?
Непонятно.
Отсутствует
можно было бы и интервал подрядить на сколько не жалко.
Это интересно только в плане технической реализации
Но как узнать что буфер обмена пуст? В смысле, какое состояние буфера считать пустым?
Все упрощается тем, что я никогда не очищаю буфер вне браузера, т.е. это будет делать кнопка. А в плане реализации мне не подходит оконный readFromClipboard(). Это становится понятным, если в буфере несколько типов данных, например, мы сначала скопировали текст, а потом картинку. Подходит await navigator.clipboard.read().
В итоге сделал такую кнопку. Просьба посмотреть и более грамотно расписать с точки зрения гуру, ну и заменить readFromClipboard()
location.href.endsWith("://browser/content/browser.xhtml") && (async (alertsService) => CustomizableUI.createWidget({ id: "my-cleanClipbrd", label: "Clean clipbrd", tooltiptext: "Clean data from Clipboard", localized: false, get icon() { let icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAABY0lEQVR4nGNgwANeL2EofrWUoYiBXPBoHsMfECbbgLszGf6DMNkGXJvM8B+EyTYgODXuPwiTpit0FTNv0ip1noTltsJhU/6DsED0Ylve6MXqIDm8ennjl8fyxi39yh+35D9/7KL/ArEL/gvEzPsvGD33v2DU7P+CkTO/CodPi8VpAH/sglUCMfPhGoQiZ/0XipjxXzh8GtglIqGT/ouGTFiF04CP29T2f9qu/h8f/rhNbR9OA77sMXz5ZY/hf3z4826D51g1fzpkI/r9oPV/XPjjLhMEe7epMIYBv486+/w66vQfhL8fsgfTyPjtVn04+/dhJ09MA054tvw56fUfhD/uMgfTyPjNJk04+/cJryYMA/6e9j/+74z/fxB+s0kDTCPj1+tk//897Qtm/z3jdxTDgP/nQrL+nwua+/9c0KG368S//j8b9O7/uaBfYHw26N3HzfIffx9zPg1RE5KFMyZIBQA3pi1KgcfhAAAAAABJRU5ErkJggg"; let subst = this.id.toLowerCase() + "-icon"; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newURI(icon)); delete this.icon; return this.icon = "resource://" + subst; }, onCreated(btn) { btn.setAttribute("image", this.icon); args11 = ["popuphiding", () => { console.log('popup close'); if (!readFromClipboard()) return; btn.style.visibility = 'visible'; PlacesToolbarItems.removeEventListener(...args11); console.log('remove listener'); }]; if (!readFromClipboard()) { btn.style.visibility = 'hidden'; PlacesToolbarItems.addEventListener(...args11); } }, onCommand(e) { Services.clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); e.target.style.visibility = 'hidden'; PlacesToolbarItems.addEventListener(...args11); alertsService.showAlertNotification("chrome://browser/skin/customizableui/whimsy.png", "Clipboard", "Буфер обмена растоптан!"); setTimeout(() => alertsService.closeAlert(), 2000); }, }))(Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService));
Отсутствует
заменить readFromClipboard()
На await navigator.clipboard.read() что ли?
А в чём тут затруднение? Выражение вернёт массив,
либо пустой, либо не пустой, просто проверяем length
Другое дело, что navigator.clipboard берёт лишь немногое.
Например, в копируем файл в проводнике,
и в буфере торчит больше десятка форматов,
а await navigator.clipboard.read() отдаёт пустой массив.
Просьба посмотреть
Здесь виджет создаётся кодом, исполнившемся в окне,
и многое некоторое привязано к этому окну.
Например, PlacesToolbarItems вычисляется
как #PlacesToolbarItems того окна, в котором создан виджет.
Если открыть другое окно браузера, то это не изменится, листенеры
будут добавляться и удаляться для элемента в окне происхождения,
то есть, в новом окне код не будет работать как надо.
Также args11, мало того, что это ненужная глобальная переменная,
типа window.args11, так при открытии нового окна, код перепишет этот args11,
и если листенер из предыдущего args11 был добавлен и не удалён, то его уже не удалить.
setTimeout() это тоже setTimeout() окна происхождения,
если это окно закрыть, то setTimeout() работать перестанет.
И если это ещё можно поправить, то если в код добавить async-await,
то от отвала асинхронной машинерии при закрытии окна происхождения
уже не спасёт ничто.
Лучше создавать виджет в другом месте, вот, например, через SystemGlobal.eval()
(async p => await p || window.__SSi == "window0" && Cu.getGlobalForObject(Cu) .eval(`(${(m, self, widget) => widget = m.CustomizableUI.createWidget(self = { id: "my-cleanClipbrd", label: "Clean clipbrd", tooltiptext: "Clean data from Clipboard", localized: false, get icon() { let icon = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsTAAALEwEAmpwYAAABY0lEQVR4nGNgwANeL2EofrWUoYiBXPBoHsMfECbbgLszGf6DMNkGXJvM8B+EyTYgODXuPwiTpit0FTNv0ip1noTltsJhU/6DsED0Ylve6MXqIDm8ennjl8fyxi39yh+35D9/7KL/ArEL/gvEzPsvGD33v2DU7P+CkTO/CodPi8VpAH/sglUCMfPhGoQiZ/0XipjxXzh8GtglIqGT/ouGTFiF04CP29T2f9qu/h8f/rhNbR9OA77sMXz5ZY/hf3z4826D51g1fzpkI/r9oPV/XPjjLhMEe7epMIYBv486+/w66vQfhL8fsgfTyPjtVn04+/dhJ09MA054tvw56fUfhD/uMgfTyPjNJk04+/cJryYMA/6e9j/+74z/fxB+s0kDTCPj1+tk//897Qtm/z3jdxTDgP/nQrL+nwua+/9c0KG368S//j8b9O7/uaBfYHw26N3HzfIffx9zPg1RE5KFMyZIBQA3pi1KgcfhAAAAAABJRU5ErkJggg"; let subst = this.id.toLowerCase() + "-icon"; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newURI(icon)); delete this.icon; return this.icon = "resource://" + subst; }, show: async win => (await win.navigator.clipboard.read()).length, args11: ["popuphiding", async e => { console.log("popup closing"); await self.show(e.view) && self.setState( "visible", "removeEventListener", console.log("remove listener(s)") ); }], setState(visibility, method) { for(var {node} of widget.instances) node.style.visibility = visibility, node.trg[method](...this.args11); }, async onCreated(btn) { btn.setAttribute("image", this.icon); btn.trg = btn.ownerDocument.getElementById("PlacesToolbarItems"); if (await this.show(btn.ownerGlobal)) return; btn.style.visibility = "hidden"; btn.trg.addEventListener(...this.args11); console.log("add listener"); }, onCommand(e) { Services.clipboard.emptyClipboard(Ci.nsIClipboard.kGlobalClipboard); self.setState("hidden", "addEventListener"); console.log("add listener(s)"); self.notify(e.view); }, notify(win) { var name = "whimsy_clipboard"; var as = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); var close = as.closeAlert.bind(null, name); (this.notify = win => { as.showAlertNotification( "chrome://browser/skin/customizableui/whimsy.png", "Clipboard", "Буфер обмена растоптан!", false, "", null, name ); win.setTimeout(close, 2e3); })(win); }, })})(ChromeUtils.importESModule("resource:///modules/CustomizableUI.sys.mjs"));`))(window.delayedStartupPromise);
Отсутствует
копируем файл в проводнике,
и в буфере торчит больше десятка форматов,
а await navigator.clipboard.read() отдаёт пустой массив
Да, так и есть, для .read() и readFromClipboard() - это неизвестный формат данных. Сможем ли где-то в браузере вставить такое? Вряд ли. Но и веб стандарт по буферу еще не до конца реализован в браузерах
виджет создаётся кодом, исполнившемся в окне,
и многое некоторое привязано к этому окну
Редко когда открываю window1, разве что случайно нажав Ctrl+N, и сразу закрываю. Отношусь к одноокошечникам.
args11, мало того, что это ненужная глобальная переменная
С моими познаниями даже не знаю как, например, в onCommand() получить значение переменной, созданной через let (var) в onCreated()
Лучше создавать виджет в другом месте, вот, например, через SystemGlobal.eval()
А если работать только в одном окне, то лучше тоже через SystemGlobal.eval()?
Спасибо за виджет и информацию, все работает как надо
Но главный вопрос, который меня интересует: возможно ли скриптом внедрить свой css на страницу about:preferences для ее стилизации?
Отредактировано dinn (07-10-2024 21:28:35)
Отсутствует
С моими познаниями даже не знаю как, например, в onCommand() получить значение переменной, созданной через let (var) в onCreated()
Неудивительно.
Такое не возможно ни с какими познаниями, просто потому что — никак.
Ну, вариант вытащить ссылку дебаггером мы здесь рассматривать не будем,
поскольку это лютая жесть.
А если работать только в одном окне, то лучше тоже через SystemGlobal.eval()?
Если так ставить вопрос, то получается, что не особо лучше.
Но, вот послушай.
Теретически, открыть окно браузера может и вэб-контент.
Допустим, например, в about:preferences#privacy снята галка
«Блокировать всплывающие окна».
Открываем адрес data:text/plain;charset=utf-8,test
и с веб-консоли (Ctrl+Shift+K) запускаем
open("about:logo", "_blank", "width=300,height=280");
Открывается окошко, которое не выглядит как окно браузера,
но, тем не менее, это именно оно.
Или, вот, например, ставим этот (замечательный, кстати) аддон.
Убеждаемся, что в настройках аддона стоит галка [✔] Открывать в окне.
Теперь, ПКМ на какой-нибудь ссылке —> «Свойства ссылки».
Открывается окно, которое выглядит ещё менее похожим на окно браузера,
тем не менее, это именно оно. И аддон здесь нипричём, просто таково
осуществление в браузере симуляции гуглячьего API.
Всё это, скорее, важно не само по себе,
а при наличии в коде чего-то деструктивного, вроде переопределения args11.
Короче, это я всё к тому, что делай как хочешь, но делай осознанно.
Типа да, я знаю, что args11 будет торчать в окне, но это так проще и удобнее.
И, имя args11 выглядит достаточно уникальным, чтобы не образовывать конфликта имён.
Ещё раз — сознательно, а не то, чтобы просто по запарке.
Но главный вопрос, который меня интересует: возможно ли скриптом внедрить свой css на страницу about:preferences для ее стилизации?
Ооо, здесь нужно железобетонное обоснование
чем «для ее стилизации» не угодил userContent.css
Почему именно «скриптом», почему именно «внедрить на страницу»,
и всякие иные прочие подробности.
И, если есть сам скрипт, пусть даже неудачный, то его тоже.
В любом случае, разумеется, ответ подразумевает начинаться с "Да, это возможно."
Отсутствует
здесь нужно железобетонное обоснование
Его нет, но есть интерес альтернативного подхода. Если очень кратко, то какова вероятность того, что при переносе на четвертый уровень, а затем полного удаления документа из web стандарта, это не распространится на юзер стили agent, chrome и content? В поисках альтернативы был успешно опробован метод, а вот что делать с внутренними страницами about:*, chrome:* пока не знаю. Или слишком забегаю вперед?
Отсутствует
был успешно опробован метод
Это что ещё за monkey-offtopic?
что делать
Вот, развлекайся
location == "chrome://browser/content/browser.xhtml" && addEventListener("DOMDocElementInserted", e => { var doc = e.target; if (!doc.documentURI.startsWith("about:preferences")) return; var css1 = "richlistitem {background-color: pink !important}"; doc.documentElement.appendChild(doc.createElement("style")).append(css1); var win = doc.ownerGlobal; var css2 = "h1, h2 {background-color: limegreen !important;}"; var sheet = new win.CSSStyleSheet(); sheet.replaceSync(css2); doc.adoptedStyleSheets.push(sheet); var wu = win.windowUtils; var css3 = "label, description {background-color: yellow !important; color: red !important;}"; wu.loadSheetUsingURIString("data:text/css," + encodeURIComponent(css3), wu.USER_SHEET); });
Отсутствует
Вот, развлекайся
ооо, спасибо, красота. Целых 3 способа. С конструктором больше понравилось + есть гордая надпись в правилах: constructed.
Это что ещё за monkey-offtopic?
Не совсем, если userChrome.js скрипт не умеет выборочно стилизовать http(s) страницы
Отсутствует
Dumby, может перед push впаять wrappedJSObject? Не дает мне стилизовать меню и настройки одного из расширений
location == "chrome://browser/content/browser.xhtml" && addEventListener("DOMDocElementInserted", e => { let doc = e.target; if (!doc.documentURI.startsWith("moz-extension://f6665cb1")) return; let win = doc.ownerGlobal; let file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.initWithPath(file.path+"\\css\\test\\yt_dark.css"); let fis = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream); let sis = Cc["@mozilla.org/scriptableinputstream;1"].createInstance(Ci.nsIScriptableInputStream); fis.init(file, -1, 0, 0); sis.init(fis, "UTF-8"); let data = sis.read(sis.available()); let sheet = new win.CSSStyleSheet(); sheet.replaceSync(data); doc.adoptedStyleSheets.push(sheet); });
Отредактировано dinn (11-10-2024 22:07:37)
Отсутствует
расширений
Расширения запрещены со времён Firefox 57.
Неужели нет способа как-то проверить, чтобы стилизовать именно это расширение, а не другое?
Ну по id'шнику можно, только они тоже бывают uuid'ом.
e.target выдает, что readyState находится на этапе loading, а значит title всегда будет пустым
Это логично, однако, только что-то я тебя не пойму.
Звучит так, словно WebExtensions у тебя в родительском процессе.
Но разве такое сейчас возможно?
Когда-то давно было возможно, но уже тогда они,
в таком случае, работали криво, а теперь, вроде, вообще не работают.
WebExtensions живут в своём отдельном процессе.
А значит, бесполезно что-то слушать в окне браузера,
которое в родительском процессе, в котором
аддонского добра просто быть не может, никакого.
Чтобы действовать в аддонском процессе,
лучше всего подходит зарегистрировать JSWindowActor
то есть .mjs скрипт-модуль.
Но для этого нужен файл на диске, и адрес на него
по протоколу chrome: или resource:
Поскольку о своём uc-скриптоприёмнике ты не рассказал ничего
(ведь в некоторых может есть своя встроенная хром/ресурс регистрация),
то вот, например, регистрируем ресурс на папку css
и регистрируем actor созданный в этой папке css
под именем WebExtensionsStylerChild.mjs
(async p => { if (await p || window.__SSi != "window0") return; var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("css"); var subst = "uc-css-folder"; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newFileURI(file)); ChromeUtils.registerWindowActor("WebExtensionsStyler", { child: { events: {DOMDocElementInserted: {}}, esModuleURI: `resource://${subst}/WebExtensionsStylerChild.mjs` }, allFrames: true, remoteTypes: ["extension"] }); })(window.delayedStartupPromise);
Cu.readUTF8File() — работает, и с ним попроще,
но в консоли есть предупреждение: «Use of nsIFile in content process is deprecated.»
А раз тебе «С конструктором больше понравилось», то надо читать с диска,
хотя, казалось бы, лучше использовать windowUtils
не только потому, что он сам будет читать, но и потому, что можно
заказать author, user или agent origin стиля, а для adopted — нельзя.
Ладно, вот, например, чтение через fetch()
и синхрон-костыль, потому что не хочется чего-то лишнего
в других частях кода, а читаться каждый стиль будет только раз.
var data = { "uBlock0@raymondhill.net": { "popup-fenix.html": "ublock/popup", "dashboard.html": "ublock/prefs-root", "1p-filters.html": "ublock/prefs-my-filters", "whitelist.html": "ublock/prefs-test-non-existent-style-throws-once", }, "linkPropertiesPlus@infocatcher": { "properties.html": "lpp/link-props" }, "treestyletab@piro.sakura.ne.jp": { "sidebar/sidebar.html?style=photon&reloadMaskImage=true": "tst/two-sidebars", "sidebar/sidebar.html?style=highcontrast&reloadMaskImage=true": "tst/two-sidebars", }, }; var read = obj => { var folder = Services.io.newURI(import.meta.url).resolve(".."); var text, thread = Services.tm.currentThread; var tick, ex, stop = () => tick = false, err = e => ex = e; var ftch = async url => text = await (await fetch(url)).text(); return (read = obj => { var url = folder + obj.css + ".css"; ftch(url).catch(err).finally(tick = stop); while(tick) thread.processNextEvent(true); if (ex) return delete data[obj.id][obj.path], console.error(`Fetch-Sheet-Error for ${obj.id}\n${url}\n${ex.message}`), ex = null; var res = text; text = null; return data[obj.id][obj.path] = res; })(obj); } var readSheet = function() { return read(this); } for(var [id, obj] of Object.entries(data)) { var dupes = {}; for(var path in obj) { var css = obj[path]; delete obj[path]; path = "/" + path; if (css in dupes) { if (typeof dupes[css] == "string") { const parent = obj, link = dupes[css]; dupes[css] = () => parent[link]; } Object.defineProperty(obj, path, { get: dupes[css], configurable: true, enumerable: true }); } else dupes[css] = path, (obj[path] = {css, path, id})[Symbol.toPrimitive] = readSheet; } } export class WebExtensionsStylerChild extends JSWindowActorChild { handleEvent(e) { var doc = e.target; var obj = data[doc.nodePrincipal.addonId]; if (obj) { var u = doc.documentURIObject; var style = obj[u.pathQueryRef] || u.hasRef && obj[u.specIgnoringRef.slice(52)] || obj[u.filePath]; if (style) { var sheet = new doc.ownerGlobal.CSSStyleSheet(); sheet.replaceSync(style); doc.adoptedStyleSheets.wrappedJSObject.push(sheet); } } } }
может перед push впаять wrappedJSObject?
Я сначала впаял перед doc, но да, перед push тоже работает.
Отсутствует
WebExtensions живут в своём отдельном процессе.
А значит, бесполезно что-то слушать в окне браузера,
которое в родительском процессе, в котором
аддонского добра просто быть не может, никакого.
Ну почему бесполезно слушать? Пока еще не удалили эту настройку, а если она в false, то можно послушать
Поскольку о своём uc-скриптоприёмнике ты не рассказал ничего
Этот. Нет в нем никаких регистраций
Теперь про mjs'ку
В вашем первом коде все понятно, норм зарегилось, а во втором коде ничего не ясно. Это содержимое WebExtensionsStylerChild.mjs? Как этот mjs запускать? Что в нем за export .. extends? Не получилось ничего стилизовать таким способом, хотя бы на примере uMatrix
А раз тебе «С конструктором больше понравилось
Чтение из css файла я только с ним попробовал
Кстати, можно выкинуть всё связанное со стилями,
и воткнуть проставление на <html> атрибутов "data-a-url" и "data-a-domain"
Тогда будет типа унификация с методом, который «был успешно опробован»
Было бы круто, но раз не смог разобраться с тем, что понимает первоклассник, то ...
Отредактировано dinn (14-10-2024 18:13:25)
Отсутствует
Ну почему бесполезно слушать? Пока еще не удалили эту настройку, а если она в false, то можно послушать
Да, действительно, ты прав.
Я не ту настройку крутил, а эта работает.
Выходит, что здесь ничего особо не изменилось.
Но тогда непонятно в чём затруднение.
Событие приходит и с попапа, и со страницы.
location == "chrome://browser/content/browser.xhtml" && addEventListener("DOMDocElementInserted", e => { let doc = e.target; if (doc.nodePrincipal.addonId == "uMatrix@raymondhill.net") { var uri = doc.documentURIObject; console.log("\u{1f7e9}".repeat(7) + " uMatrix DOCUMENT DETECTED\n" + uri.spec); var color; switch (uri.filePath) { case "/popup.html": color = "deeppink"; break; case "/dashboard.html": color = "limegreen"; break; case "/settings.html": color = "royalblue"; break; default: return; } doc.documentElement.style.cssText = ` contain: paint !important; overflow: hidden !important; transform: translateX(64px) !important; box-shadow: -4px 0 yellow, -64px 0 ${color} !important; `; } });
Этот. Нет в нем никаких регистраций
Кстати, там по событию "load".
Вроде как на этот момент window.__SSi уже есть,
поэтому delayedStartupPromise для него можно не ждать.
Это содержимое WebExtensionsStylerChild.mjs?
Да, это содержимое WebExtensionsStylerChild.mjs
Как этот mjs запускать?
Запускать ничего не надо, он зарегистрирован
в первом (оконном) коде через ChromeUtils.registerWindowActor()
там где esModuleURI
Что в нем за export .. extends?
Модуль должен экспортировать класс, с именем, заявленным при регистрации,
то есть, имя actor'а плюс "Child" — для контентской стороны,
и плюс "Parent" — для родительского процесса (если указан).
А extends, ну он extend'ит существующий класс JSWindowActorChild
чтобы пользоваться его свойствами и методами, да и вообще, похоже,
что он просто обязан это делать, а то будет молча проигнорирован.
Не получилось ничего стилизовать таким способом
Ещё бы, в регистрации написано: remoteTypes: ["extension"]
а у тебя такого процесса нет.
Можно заменить на matches: ["moz-extension://*"]
тогда будет работать.
Так-то, о подобных вещах поперёк мейнстрима,
типа WE в родительском процессе, лучше говорить сразу,
чтобы не приходилось гадать.
Было бы круто, но раз не смог разобраться
Ну так рассказывай, что делал, что не получается.
Только, желательно, доходчиво.
Отсутствует
Но тогда непонятно в чём затруднение
в том, но я не смог найти в e.target.... uMatrix@raymondhill.net
Так-то, о подобных вещах поперёк мейнстрима,
типа WE в родительском процессе, лучше говорить сразу,
чтобы не приходилось гадать.
Это со стороны выглядит, что я знал, а на самом деле узнал только после тестов перед написанием предыдущего сообщения, т.к. у меня в user.js extensions.webextensions.remote=false еще с FF91
Ещё бы, в регистрации написано: remoteTypes: ["extension"]
а у тебя такого процесса нет.
Можно заменить на matches: ["moz-extension://*"]
тогда будет работать.
Сократим mjs до
export class WebExtensionsStylerChild extends JSWindowActorChild { handleEvent(e) { var doc = e.target; console.log(doc); } }
Если extensions.webextensions.remote=true, то
remoteTypes: ["extension"] // не пашет
matches: ["moz-extension://*"] // не пашет
или в консоли уже не увидеть?
Если extensions.webextensions.remote=false, то
remoteTypes: ["extension"] // не пашет
matches: ["moz-extension://*"] // пашет
Отсутствует
Если extensions.webextensions.remote=false, то
remoteTypes: ["extension"] // не пашет
Да, я уже говорил, что не должен пахать.
remoteTypes — это массив префиксов типов процессов, где должно работать
(если отсутствует — тогда во всех DOM'ских процессах).
А раз процесса с remoteType "extension" нет, то ...
matches: ["moz-extension://*"] // пашет
Это хорошо, значит хотя бы всё размещено и подключено верно.
Если extensions.webextensions.remote=true, то
remoteTypes: ["extension"] // не пашет
matches: ["moz-extension://*"] // не пашетили в консоли уже не увидеть?
А вот это странно.
Если аддонский процесс есть (можно глянуть в about:processes),
то я даже не знаю что и предположить.
Ну, разве что, действительно,
в консоли браузера просто не включён многопроцессный режим
(devtools.browsertoolbox.scope = everything).
Отсутствует
Dumby Большое спасибо за практикум.
в консоли браузера просто не включён многопроцессный режим
Да, так и есть. Ни разу в жизни не включал. Теперь вижу при
extensions.webextensions.remote=true
remoteTypes: ["extension"]
Для стилизации uMatrix у меня один css файл для попапа и настроек. Если получится, то сделаю чтение из css, а если нет, то придется вбивать в mjs 300 строк.
Нет, чушь несу. Зачем читать css, если все уже прочитано и закешировано при старте брауза. Вообщем, содержимое mjs
export class WebExtensionsStylerChild extends JSWindowActorChild { handleEvent(e) { var doc = e.target; if (doc.nodePrincipal.addonId == "uMatrix@raymondhill.net") { doc.documentElement.setAttribute('data-a-url', "uMatrix"); } } }
Пашет, расшира стилизовалась, но атрибут прописался еще в двух местах, где он быть не должен?
1) В каком-то внутреннем расширении брауза на странице _generated_background_page.html
2) в расширении uMatrix на странице background.html
Отредактировано dinn (16-10-2024 01:15:23)
Отсутствует
Dumby отказался от стилизации в обертке data-a-url из-за невозможности стилизации ShadowRoot, хотя это легко решается добавлением стилей извне css.
Ваша версия с синхрон-косылем не осталась без внимания. В итоге перешел на нее. Порадовало то, что не требует обертки в css и нет зависимости от "toolkit.legacyUserProfileCustomizations.stylesheets"
Отсутствует
Dumby возможно ли добавить кнопку на страницу about:config, чтобы при клике она выполняла код, который спокойно выполняется из консоли текущей страницы? Например такой:
var test = [...gExistingPrefs.values()].sort((a, b) => a.name > b.name);
Само собой, все отключено, чтобы сабж не вякал варнингом и allow pasting
Хотя сомневаюсь, что Content-Security-Policy такое позволит. Попробую поработать с html и js старого конфига, который через манифест стартует
Отредактировано dinn (22-10-2024 00:54:07)
Отсутствует
возможно ли добавить кнопку на страницу about:config, чтобы при клике она выполняла код, который спокойно выполняется из консоли текущей страницы?
Да, возможно.
Можно дебаггером, но у тебя его нет.
Можно подрядить разрезольвившийся precompiledScript,
с отдаваемого ChromeUtils.compileScript()
вызвав его метод executeInGlobal();
Или, например вот, тупо scriptloader'ом
ну, просто чтобы ты не сомневался, что возможно
location == "chrome://browser/content/browser.xhtml" && (func => addEventListener("DOMContentLoaded", e => e.target.documentURI == "about:config" && Services.scriptloader.loadSubScript( "data:," + encodeURIComponent(`(${func})();`), e.target.ownerGlobal ) ))(() => { var btn = document.createElement("button"); btn.append("Button"); document.getElementById("toolbar").prepend(btn); btn.addEventListener("click", () => { var test = [...gExistingPrefs.values()].sort((a, b) => a.name > b.name); alert(test.map(obj => obj.name + " -> " + obj.value).join("\n")); }); });
Отсутствует