скрытый текст
А чего это там код
два раза два раза
повторяется?
Исправь, если у тебя так.
А правка, может такую попробуй
/* mp.setAttribute("onpopupshowing", "this.updateMenu();"); mp.setAttribute("oncommand", "if(!event.button) this.handleEvent(event);"); // Ignore middle-click in Firefox 89+ mp.setAttribute("onmousedown", "if(event.button == 0) this.handleEvent(event);"); mp.setAttribute("onclick", "if(event.button > 0) this.handleEvent(event);"); mp.setAttribute("oncontextmenu", "return false;"); mp.setAttribute("onpopuphidden", "this.destroyMenu();"); */ addEventListener("popupshowing", () => mp.updateMenu(), false, mp); addEventListener("command", mp.onmousedown = mp.onclick = e => { if (!e.button || e.type.endsWith("k")) mp.handleEvent(e); }, false, mp); mp.toggleAttribute("context"); addEventListener("popuphidden", () => mp.destroyMenu(), false, mp);
Отсутствует
Dumby
Спасибо! Кнопка заработала.
Огромная просьба. Посмотри еще раз код
Дополнительные пункты в контекстном меню кнопки из моего
предыдущего поста. Очень полезная кнопка. Твоя правка к сожалению не сработала.
Ни один пункт меню не работает.
Отредактировано Garalf (08-02-2025 23:31:32)
Отсутствует
Огромная просьба. Посмотри еще раз код
Дополнительные пункты в контекстном меню кнопки
Посмотрел.
На сей раз на 137.0a1 (2025-02-09).
Создал кнопку с предоставленным кодом инициализации.
Сделал предложенные правки. Рестарт.
Пункты «Показать Id кнопки» и «Переместить кнопку...» точно работают.
Остальные не проверял, поскольку, таким образом, утверждение
«Ни один пункт меню не работает» уже не подтвердилось.
Отсутствует
Проверь пожалуйста пункт меню Редактирование кнопки.
Это не представляется возможным,
поскольку меня такого пункта вообще нет.
Есть пункт «Редактировать…».
#custombuttons-contextpopup-edit,
ну тот, который самый первый сверху.
Но этот пункт не из добавляемых кодом, а пункт самого расширения.
Если имееется в виду именно он, и если не работает именно он,
то, может, обновление встало криво,
или startupCache при этом, после рестарта не очистился,
или, даже не знаю что ещё.
Отсутствует
Dumby
Раз теме тишина попрошу полечить еще одну кнопку.
UserCSSLoader
(obj => { this.onclick = obj.click.bind(obj); this.oncontextmenu = obj.contextmenu.bind(obj); this.tooltipText = "L: Reload userChrome.css\nM: CB Menu\nR: Reload userContent.css"; })({ async click(e) { if (e.button == 1) return gShowPopup(self); if (e.button || !this.chromeSheet) return; await this.reload(this.chromeSheet); this.restyle(0); }, async contextmenu(e) { if (e.ctrlKey || e.shiftKey || e.detail != 1 || !this.contentSheetURL) return; e.preventDefault(); var count = Services.ppmm.childCount, one = count == 1; var data = await this.reloadTab("chrome://extensions/content/dummy.xul", one ? false : {}); if (one) this.reloadTab(); else if (data) { var url = "data:," + encodeURIComponent( self.Help + this.contentSheetURL + '", ' + JSON.stringify(data) + ");" ); var types = ["web", "file", "extension"]; for(var ind = 0; ind < count; ind++) { var child = Services.ppmm.getChildAt(ind); types.includes(child.remoteType) && child.loadProcessScript(url, false); } } this.restyle(250); }, async reload(sheet, obj) { try {var style = await (await fetch(sheet.href)).text();} catch (ex) {return obj;} InspectorUtils.parseStyleSheet(sheet, style); if (obj) obj[sheet.href] = style; for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && await this.reload(rule.styleSheet, obj); } return obj; }, reloadTab(url, obj) { var tab = gBrowser.addTab(url, {skipAnimation: true}); tab.style.setProperty("display", "none", "important"); return new Promise(resolve => { var result, stop, destroy = () => { if (!stop) resolve(result), gBrowser.removeTab(tab), stop = true; } setTimeout(destroy, 500); try { tab.linkedBrowser.addEventListener("DOMContentLoaded", async e => { var sheet = this.getSheet(e.target, this.contentSheetURL); if (sheet) result = await this.reload(sheet, obj); destroy(); }, {once: true}); } catch(ex) { destroy(); } }); }, getSheet(doc, href) { var sheets = InspectorUtils.getAllStyleSheets(doc); return sheets.find(sheet => sheet.href == href); }, get contentSheetURL() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("userContent.css"); if (!file.exists()) return null; delete this.contentSheetURL; return this.contentSheetURL = Services.io.newFileURI(file).spec; }, get restyle() { var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = Services.io.newURI("data:text/css,:root{}"), type = sss.USER_SHEET; delete this.restyle; return this.restyle = delay => setTimeout(() => { sss.loadAndRegisterSheet(uri, type); sss.unregisterSheet(uri, type); }, delay); }, get chromeSheet() { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append("userChrome.css"); if (!file.exists()) return null; var href = Services.io.newFileURI(file).spec; var sheet = this.getSheet(document, href); if (!sheet) return null; delete this.chromeSheet; return this.chromeSheet = sheet; } });
Напомню - это 136.b3 Кстати, пункт меню Edit в контекстном меню кнопки
неожиданно заработал.
Отредактировано Garalf (11-02-2025 10:19:25)
Отсутствует
Dumby
Справка
((href, data) => { var en = Services.ww.getWindowEnumerator(null); if (!en.hasMoreElements()) return; var doc = en.getNext().document; var du = Components.classes["@mozilla.org/inspector/dom-utils;1"] .getService(Components.interfaces.inIDOMUtils); var reload = sheet => { var style = data[sheet.href]; if (!style) return; du.parseStyleSheet(sheet, style); for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && reload(rule.styleSheet); } } var sheet = du.getAllStyleSheets(doc).find(sheet => sheet.href == href); if (sheet) reload(sheet); })("
Отсутствует
Справка
Другое дело.
Напомню - это 136.b3
Что-то я не вижу в кнопке
ни использования «on…» атрибутов, ни импорта модулей.
Но многовато чего-то совсем древнего,
поэтому попробую чуть переделать.
Код со Справки перенёс в Инициализацию.
(code => { this._handleClick = () => { var href = getHref("hrome"); if (!href) return; var sheet = getSheet(document, href); sheet && (this._handleClick = () => reload(sheet).then(restyle))(); } this.onauxclick = e => e.button > 1 || gShowPopup(this); this.oncontextmenu = e => { if (e.ctrlKey || e.shiftKey || e.detail != 1) return; e.preventDefault(); reloadContentSheet(); } this.tooltipText = "L: Reload userChrome.css\nM: CB Menu\nR: Reload userContent.css"; var getHref = str => { var file = Services.dirsvc.get("UChrm", Ci.nsIFile); file.append(`userC${str}.css`); if (file.exists()) return Services.io.newFileURI(file).spec; } var getSheet = (doc, href) => InspectorUtils.getAllStyleSheets(doc).find(sheet => sheet.href == href); var reload = async (sheet, obj) => { try {var style = await (await fetch(sheet.href)).text();} catch {return obj;} InspectorUtils.parseStyleSheet(sheet, style); if (obj) obj[sheet.href] = style; for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && await reload(rule.styleSheet, obj); } return obj; } var restyle = delay => { var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); var uri = Services.io.newURI("data:text/css,:root{}"), type = sss.USER_SHEET; var regUnreg = () => { sss.loadAndRegisterSheet(uri, type); sss.unregisterSheet(uri, type); }; (restyle = delay => setTimeout(regUnreg, delay))(delay); } var reloadContentSheet = async () => { var href = getHref("ontent"); if (!href) return; var {br} = this; if (!br) { br = this.br = document.createXULElement("browser"); br.setAttribute("type", "content"); this.append(br); await new Promise(resolve => br.addEventListener("pageshow", resolve, {once: true})); } var sheet = getSheet(br.contentDocument, href); if (!sheet) return; br.remove(); delete this.br; var {ppmm} = Services; var re = /^(?:web|file|extension|privileged)/; var prfx = "data:," + encodeURIComponent(code.trim() + sheet.href + '", '); (reloadContentSheet = async () => { var data = await reload(sheet, Object.create(null)); var url = prfx + encodeURIComponent(JSON.stringify(data)) + ");" for(var ind = 0, count = ppmm.childCount; ind < count; ind++) { var child = ppmm.getChildAt(ind); re.test(child.remoteType) && child.loadProcessScript(url, false); } restyle(350); })(); } })(` ((href, data) => { var en = Services.ww.getWindowEnumerator(null); if (!en.hasMoreElements()) return; var doc = en.getNext().document; var reload = sheet => { var style = data[sheet.href]; if (!style) return; InspectorUtils.parseStyleSheet(sheet, style); for(var ind = 0, len = sheet.cssRules.length; ind < len; ind++) { var rule = sheet.cssRules.item(ind); rule.type == rule.IMPORT_RULE && rule.styleSheet.href.startsWith("file:///") && reload(rule.styleSheet); } } var sheet = InspectorUtils.getAllStyleSheets(doc).find(sheet => sheet.href == href); sheet && reload(sheet); })(" `);
Отсутствует
Dumby
Нашел еще две удобные неработающие кнопки
1. "Два в одном"
//Настройка функций кликов мыши для кнопки .................... this.onclick =e=> {if(e.button==0)BrowserOpenAddonsMgr();//ЛКМ if(e.button==1)gShowPopup(this); //СКМ if(e.button==2 && !e.ctrlKey && !e.shiftKey && !e.altKey && !e.metaKey){//ПКМ setTimeout(function(){document.getElementById("custombuttons-contextpopup").hidePopup();},0);openPreferences();}}; this.tooltipText="Л: Addons\nС: CBMenu\nП: Preferences"; //data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAABuwAAAbsBOuzj4gAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAMJSURBVDiNdVPNa1N5FD2/30uMeX1IPjFmE3BKERdhRKqgwyBqibsuZqGYRRf2H3Ax0J28je22XcRCwwhNKh0ki24GSn20iE3TNMKjONKkHyYUokmbMR++F/Oa966baUkVL9zNvfdc7jmHy4gIP4uFhcUFABgejgz/dIiITjKZTF3JZtXKzEziPgC+tbV3tLW1dwSAz8wk7mezaiWZTF3pxZxaEI2O3mk2NSoWy918/kO73e5Qu92hQuFDu1gsd5tNjaLR0Tu9GEZEiMdf/Orz+Ry6rndu3rz21u/3ciLCp08VAEAgcB6MMRwc1KzV1exVURQdh4eHndHRhyoDwBYXX38Mhy+f17S26fW6hHR6HUtLKzBNEwAgCAKGhm7hxo3rqNXqZl+fU9jcfF+JRH6/wImIEolZeX+/bElSn5DLqUins0TUKXBuRDk3okSdQjqdpVxOhST1Cfv7ZSuRmJXpRAiAK0pGL5UqNDUVt2T5ab6XJxFBlp/mp6biVqlUIUVZ0wFwIgKfnIwnl5fXW8FgwKlpOiRJZB6PW/7eLY/HLUuSyDRNRzB4wbm8vN6anIwnbaq6yTWtaw+FfoHLJcHn8+PsWdsPdnu9XkiSG3t7H1Gvf0GptGvf3n7PTyiMj0+35uaWqFAoWoqy8gMFRVnJFwpFa35eofHx6dYxBRsAxGKz94jsgig6oOsGGxi41K+qm3nLIhkAOGdPBgYu9TcaGjt3ToTH4xZisdl7AP7hjDFWLldjLpfHqesNq15v4etXg4dCF/sDgeBcIBCcC4Uu9h8ddXmzqUHXm5bf73dWq7UYY4zZiIgikeEHq6uvXA6Hvf748Z9vOh2XcHBQ46LoAGMMnz/XuWmaMIwv5vPnz34zDMNltzvqRESs95mmp/+6Ojh4faPR+K9rWQaFw+EzjDG8e/evYbefYW63z5bJpAcfPRp5e4zhvUpnMmlbLpepplJ/jwwN3XXu7u5oOzvb2u3bt5wvX86PbGysVTOZtVMWnboAABhjjP4vTkxMpABgbGzsj+97x/ENhTvQG3f/6bsAAAAASUVORK5CYII= //forum.mozilla-russia.org/viewtopic.php?pid=704725#p704725 //openWebPanel("Downloads","about:downloads");
2. Поиск по изображению
/*Initialization Code*/ // Добавить подменю "Поиск изображения в" в контекстном меню изображений, от 31.05.2019. ............. (()=> { var copyimage = document.getElementById("context-copyimage-contents"); var contextMenu = copyimage.parentNode; var array = [ ['Google', 'https://www.google.lv/favicon.ico', 'http://www.google.com/searchbyimage?image_url='], ['Яндекс', 'http://yastatic.net/morda-logo/i/favicon_islands.ico', 'https://yandex.com/images/search?rpt=imageview&img_url='], ['Bing', 'https://www.bing.com/s/a/bing_p.ico', 'https://www.bing.com/images/searchbyimage?FORM=IRSBIQ&cbir=sbi&imgurl='], ['Tineye', 'http://tineye.com/favicon.ico', 'http://tineye.com/search?pluginver=bookmark_1.0&url='], ['SauceNao', 'https://saucenao.com/favicon.ico', 'https://saucenao.com/search.php?url='], ['IQDB', 'https://iqdb.org/favicon.ico', 'https://iqdb.org/?url='], ]; var menu = contextMenu.insertBefore(document.createXULElement("menu"), copyimage); menu.setAttribute("label", "Поиск изображения в ..."); menu.setAttribute("class", "menu-iconic"); menu.onclick =e=> { e.target.nodeName == 'menu' && search(array[0][2]); setTimeout(()=> contextMenu.hidePopup(), 20) }; addEventListener("popupshowing", ()=> menu.hidden = copyimage.hidden, true, contextMenu); addDestructor(() => menu.remove()); var menuPopup = menu.appendChild(document.createXULElement("menupopup")); array.forEach(m=> { var mItem = menuPopup.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", m[0]); mItem.setAttribute("image", m[1]); mItem.setAttribute("class", "menuitem-iconic"); mItem.onclick =()=> search(m[2]); }); function search(finder) { gBrowser.selectedTab = gBrowser.addTrustedTab(finder + encodeURIComponent(gContextMenu.imageURL)) }; var mItem = menuPopup.appendChild(document.createXULElement("menuitem")); mItem.setAttribute("label", 'Искать во всех поисковиках'); mItem.setAttribute("class","menuitem-iconic"); mItem.setAttribute("image", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAADZElEQVR42oXSe0xbVRwH8N8597a35e7SAmUFukGhY66AMiNzw4GvTCQLCssc4pQsmTOa+ERMlrktW1zigpnEuWn8x2eMmiVGMBDCFjS+cJHEDIk8RoSNV1+3tLWX3t72nnO8sETJFrfvP7/k5Pw+Ob9fDoLrYi8ow9GFUbq+5aRLrGraqQcX6hlF2wkFEWn6EDIJAyQy9+3VT58cWb6PrmvmjGZS/FSHlxbXtbtLobGqJlPKMhNepWb0V8hKpi8FNd/gzCCogbdmvtg/8C9gz9+Eor5x5nn2tDOZ98Dx2i3C/uYai9mOGCxiDQIIg1/PgUCEhyvDMox9PXYBkPzaaoAzAFL0yle7ShtqO/eWJ9w1vJ1oGsVzYhTNATMQG4Q1G40ldDw6PB339fs7VgMmA0jnHfioo6F9Z3tDYYJzKSZKMYcDvAILiICfZUNYEYFixMKpKBk8MfTTasBsACnngU/6Wg4+VL/VFSOmBHAYY1BAhzAvgmyMEIkh0EUOBD1Eu49eStwA5D3z4TcPv9TYdHvxEhXSGgaEIMkJkKAS+ONmSKYolOVqMBlRSd8bv8v/AQXlJoiHUE5rZ1tFa/Nhj1uVrCaNMoQxYSaIqDxAGqAuQ2XZ1iS8HUTpkZMXe1eATOdtiCcJblGe1a3PnWp0uEvfv3tbeX5RhSet/q3wxh6xgAncZUmw2hxEryQx9/LHE7I2RV5HNudGFAtcZsuQd919u/kiz56JOwobcjd6xerqKnB4HIB4RvMzCM1DGj8X0GD64pL2Xdf850z+4djKC8wl24XUpj1P75sdfe/+sSHoq3uQnSuwa+s2Vy5uubd2jQWUTAYchJK8HpyIzvv7p/rMkV/OzPeeGEWi+x6LufiR573h8VO7Zr4n9fEZNeiqXHOofFvPsKPkS1fKsX5JU6uNZQh8Wh/hRcuvOC3/fLXrcGj52yOo7zzU9udvbzbN9uglggK2MhsnvfiE0tY9tfed7vM98D+x53tx1DdG0Z2b97Ejf3SRSiGGCysyENvdoipZa4+/8NmPp8+N+Ei2ZEVpQhG71rdcqFFozD+xcoQugFUvlDS8wWsl8Uebk5C79ujjHwyc6R/309ysDBRauEzhJkG9ErAdG0xEe6yVkwqcr+549/zZgcmQ7pAEkH2TDG6RfwCoJI0uEWJP5QAAAABJRU5ErkJggg=="); mItem.onclick =()=> { array.forEach(m=> { gBrowser.selectedTab = gBrowser.addTrustedTab(m[2] + encodeURIComponent(gContextMenu.imageURL)) }) }; })(); var style = custombutton.buttonGetHelp(self).replace(/id/g, _id); var uri = makeURI('data:text/css,'+ encodeURIComponent(style)); var sss = Cc["@mozilla.org/content/style-sheet-service;1"].getService(Ci.nsIStyleSheetService); sss.loadAndRegisterSheet(uri, 0);
Отредактировано Garalf (20-02-2025 18:45:49)
Отсутствует
Dumby
В 136 пререлизе у меня не устанавливаются CB и ATB
Появляется сообщение: Дополнение не может быть установлено,
так как оно не было проверено.
Может, что то в config.js не так?
// try {(jsval => { var dbg, gref, genv = func => { var sandbox = new Cu.Sandbox(g, {freshCompartment: true}); Cc["@mozilla.org/jsdebugger;1"].createInstance(Ci.IJSDebugger).addClass(sandbox); (dbg = new sandbox.Debugger()).addDebuggee(g); gref = dbg.makeGlobalObjectReference(g); return (genv = func => func && gref.makeDebuggeeValue(func).environment)(func); } var g = Cu.getGlobalForObject(jsval), o = g.Object, {freeze} = o, disleg; var AC = "AppConstants", uac = `resource://gre/modules/${AC}.`; var lexp = () => lockPref("extensions.experiments.enabled", true); if (o.isFrozen(o)) { // Fx 102.0b7+ lexp(); disleg = true; var env, def = g.ChromeUtils.defineModuleGetter; g.ChromeUtils.defineModuleGetter = (...args) => { try { genv(); dbg.addDebuggee(globalThis); var e = dbg.getNewestFrame().older.environment; var obj = e.parent.type == "object" && e.parent.object; if (obj && obj.class.startsWith("N")) // JSM, NSVO obj.unsafeDereference().Object = { freeze: ac => (ac.MOZ_REQUIRE_SIGNING = false) || freeze(ac) }; else env = e; // ESM, Lexy "var"(?) } catch(ex) {Cu.reportError(ex);} (g.ChromeUtils.defineModuleGetter = def)(...args); } ChromeUtils.import(uac + "jsm"); // (?) env && env.setVariable(AC, gref.makeDebuggeeValue(freeze(o.assign( new o(), env.getVariable(AC).unsafeDereference(), {MOZ_REQUIRE_SIGNING: false} )))); } else o.freeze = obj => { if (!Components.stack.caller.filename.startsWith(uac)) return freeze(obj); obj.MOZ_REQUIRE_SIGNING = false; if ((disleg = "MOZ_ALLOW_ADDON_SIDELOAD" in obj)) lexp(); else obj.MOZ_ALLOW_LEGACY_EXTENSIONS = true, lockPref("extensions.legacy.enabled", true); return (o.freeze = freeze)(obj); } lockPref("extensions.experiments.enabled", true); lockPref("xpinstall.signatures.required", false); lockPref("extensions.langpacks.signatures.required", false); var useDbg = true, xpii = "resource://gre/modules/addons/XPIInstall.jsm"; if (Ci.nsINativeFileWatcherService) { // Fx < 100 jsval = Cu.import(xpii, {}); var shouldVerify = jsval.shouldVerifySignedState; if (shouldVerify.length == 1) useDbg = false, jsval.shouldVerifySignedState = addon => !addon.id && shouldVerify(addon); } if (useDbg) { jsval = g.ChromeUtils.import(xpii); var env = genv(jsval.XPIInstall.installTemporaryAddon); var ref = name => {try {return env.find(name).getVariable(name).unsafeDereference();} catch {}} jsval.XPIDatabase = (ref("lazy") || {}).XPIDatabase || ref("XPIDatabase"); var proto = ref("Package").prototype; var verify = proto.verifySignedState; proto.verifySignedState = function(id) { return id ? {cert: null, signedState: undefined} : verify.apply(this, arguments); } dbg.removeAllDebuggees(); } if (disleg) jsval.XPIDatabase.isDisabledLegacy = () => false; })( "permitCPOWsInScope" in Cu ? Cu.import("resource://gre/modules/WebRequestCommon.jsm", {}) : Cu );} catch(ex) {Cu.reportError(ex);} // // (async xp => { var imp, ids = [ "custombuttons@xsms.org", ]; if (Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime).inSafeMode) return; if (Cr.NS_ERROR_FILE_TARGET_DOES_NOT_EXIST) var {XPIInternal} = (imp = url => Cu.import(url, {}))(xp + "jsm"); else { // Fx 101+ var g = Cu.getGlobalForObject(Cu), te = new g.TextEncoder(); var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService); var rph = ios.getProtocolHandler("resource").QueryInterface(Ci.nsIResProtocolHandler); var impJSM = g.ChromeUtils.import, impESM = g.ChromeUtils.importESModule; try {var exp = impESM(xp + "sys.mjs");} catch {exp = impJSM(xp + "jsm");} var {XPIInternal} = exp; var ss = (subst, uri, ext) => rph.setSubstitution( subst, ios.newURI(uri.resolve("startup." + ext)) ); try {var useESM = parseInt(Services.appinfo.platformVersion) >= 108;} catch {} imp = (uri, id) => { var subst = te.encode(id).join(""); var url = `resource://${subst}/`; if (useESM) try { ss(subst, uri, "mjs"); return impESM(url); } catch(ex) { if (!ex || ex.message != "Failed to load " + url) return Cu.reportError(ex); } ss(subst, uri, "jsm"); return impJSM(url); } } var load = async (file, id) => { var rootURI = XPIInternal.getURIForResourceInFile(file, ""); imp(rootURI, id).start(rootURI); } var proto = XPIInternal.BootstrapScope.prototype; var func = proto._beforeCallBootstrapMethod; proto._beforeCallBootstrapMethod = () => { proto._beforeCallBootstrapMethod = func; for(var {id, loader, file} of XPIInternal.XPIStates.enabledAddons()) ids.includes(id) && !loader && load(file, id); } })("resource://gre/modules/addons/XPIProvider."); // // version, date year-month-day: 2024-6-12 (async () => { var file = Services.dirsvc.get("UChrm", Ci.nsIFile), iname; file.append("user_chrome_files"); file.append("user_chrome.manifest"); if (!file.exists() || !file.isFile()) return; switch (Services.appinfo.name) { case "Firefox": iname = "user_chrome.js"; break; case "Thunderbird": iname = "user_chrome_tb.js"; break; default: return; } Components.manager.QueryInterface(Ci.nsIComponentRegistrar) .autoRegister(file); var sandbox = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), { wantComponents: true, sandboxName: "UserChromeFiles", wantGlobalProperties: ["ChromeUtils"], }); Services.scriptloader.loadSubScript(`chrome://user_chrome_files/content/user_chrome/${iname}`, sandbox, "UTF-8"); })();
policies.json
{ "policies": { "BlockAboutAddons": false, "BlockAboutConfig": false, "BlockAboutProfiles": false, "BlockAboutSupport": false, "DisableSetDesktopBackground": true, "DisableMasterPasswordCreation": true, "DisableFeedbackCommands": true, "DisableFirefoxStudies": true, "DisableProfileRefresh": true, "DisableTelemetry": true, "NoDefaultBookmarks": false, "OverrideFirstRunPage": "", "OverridePostUpdatePage": "", "SearchEngines": { "Add": [ { "Name": "Google RU", "URLTemplate": "https://www.google.com/search?q={searchTerms}®ion=ru-RU", "Method": "GET", "Description": "metager", "IconURL": "https://www.google.com/favicon.ico" }, { "Name": "Metager", "URLTemplate": "https://metager.de/meta/meta.ger3?eingabe={searchTerms}", "Description": "metager", "IconURL": "https://metager.de/favicon.ico" } ], "Default": "Google RU" }, "Preferences": { "browser.search.update": false, "browser.search.newSearchConfig.enabled": false, "browser.warnOnQuitShortcut": false, "datareporting.policy.dataSubmissionPolicyBypassNotification": true, "extensions.blocklist.enabled": false, "extensions.getAddons.showPane": false, "extensions.experiments.enabled": true, "xpinstall.signatures.required": false, "extensions.legacy.enabled": true, "extensions.htmlaboutaddons.recommendations.enabled": false, "intl.accept_languages": "ru-RU,ru,en-US,en", "print.more-settings.open": true, "security.ssl.errorReporting.enabled": false, "browser.newtabpage.activity-stream.feeds.telemetry": false, "toolkit.legacyUserProfileCustomizations.stylesheets": true, "widget.macos.native-context-menus": false } } }
Отсутствует
Может, что то в config.js не так?
Антиподписячий код не выглядит как последний выкладывавшийся.
Проверил с последним на 136.0 RC build3, CB и ATB установились нормально.
Ещё, UCF-стафф не последний, но это к вопросу отношения не имеет.
Отсутствует
Dumby
Спасибо за подсказку. Теперь все работает.
Ну и нашел еще одну кнопку, которая перестала работать в 136
Консоль браузера
/*Initialization Code*/ ({ title: "Browser Console", url: "chrome://devtools/content/webconsole/index.html", icon: "chrome://devtools/skin/images/tool-webconsole.svg", init() { var trg = document.getElementById("browser"); trg && addEventListener("DOMContentLoaded", this, false, trg); var id = "viewBrowserConsoleSidebar"; var menuitem = this.element("menuitem", { type: "checkbox", label: this.title, id: "menu_browserConsoleSidebar", oncommand: `(globalThis.SidebarController || globalThis.SidebarUI).toggle("${id}");` }, document.getElementById("viewSidebarMenu")); var btn = this.element("toolbarbutton", { type: "checkbox", label: this.title, id: "sidebar-switcher-browserConsole", oncommand: `(globalThis.SidebarController || globalThis.SidebarUI).show("${id}");`, class: "subviewbutton subviewbutton-iconic" }); document.querySelector( parseInt(Services.appinfo.platformVersion) >= 116 ? 'menuitem[id^="sidebar-switcher-"] + menuseparator' : 'toolbarbutton[id^="sidebar-switcher-"] + toolbarseparator' ).before(btn); (globalThis.SidebarController || globalThis.SidebarUI).sidebars.set(id, { url: this.url, buttonId: btn.id, title: this.title, menuId: menuitem.id }); (globalThis.SidebarController || globalThis.SidebarUI).isOpen && (globalThis.SidebarController || globalThis.SidebarUI).currentID == id && (globalThis.SidebarController || globalThis.SidebarUI).selectMenuItem(id); var popupset = this.popupset = this.element("popupset", { id: `CB${_id.slice(20)}-browserConsole-popupset` }, document.documentElement); var css = `\ #${btn.id} > .toolbarbutton-icon, #sidebar-box[sidebarcommand="${id}"] > #sidebar-header > #sidebar-switcher-target > #sidebar-icon { list-style-image: url(${this.icon}); }`; var str = (cbu.cb || "") + "data:text/css," + encodeURIComponent(css), type = windowUtils.USER_SHEET; windowUtils.loadSheetUsingURIString(str, type); addDestructor(() => { (globalThis.SidebarController || globalThis.SidebarUI).sidebars.delete(id); btn.remove(); menuitem.remove(); popupset.remove(); windowUtils.removeSheetUsingURIString(str, type); }); parseInt(Services.appinfo.platformVersion) < 73 && "insertFTLIfNeeded" in MozXULElement && MozXULElement.insertFTLIfNeeded("toolkit/main-window/editmenu.ftl"); self.onclick = e => { if (e.button == 2) return; if (!e.button && !e.shiftKey) return (globalThis.SidebarController || globalThis.SidebarUI).toggle(id); var st = gBrowser.selectedTab, tab; if (!e.ctrlKey) tab = gBrowser.visibleTabs.find(tab => { var br = gBrowser.getBrowserForTab(tab); return br.currentURI.spec == this.url || ( "_cachedCurrentURI" in br && br._cachedCurrentURI.spec == this.url ) }); if (tab == st) return; if (!tab) tab = gBrowser.addTrustedTab(this.url); gBrowser.moveTabTo(tab, st._tPos + 1); gBrowser.selectedTab = tab; } for(var br of gBrowser.browsers) { if (br.currentURI.spec != this.url) continue; var doc = br.contentDocument; if (doc && ( doc.readyState == "complete" || doc.readyState == "interactive" )) doc.querySelector( "main#app-wrapper,div#output-container" ).childElementCount ? this.defineDocPopupset(doc) : this.handleEvent({target: doc}); } if (!btn.hasAttribute("checked")) return; var doc = (globalThis.SidebarController || globalThis.SidebarUI).browser.contentDocument; if (doc.documentURI != this.url) btn.doCommand(); else if (doc.readyState == "complete") this.defineDocPopupset(doc); }, defineDocPopupset(doc) { this.definePopupset( doc.querySelector("popupset") || doc.documentElement.appendChild(doc.createXULElement("popupset")) ); }, get definePopupset() { var append = customElements.get("menuitem") ? popup => { this.popupset.appendChild(popup); popup.setAttribute("oncommand", "event.target.cmd()"); for(var node of [...popup.querySelectorAll("menuitem")]) { var menuitem = document.importNode(node, true); menuitem.cmd = Services.els.getListenerInfoFor(node) .find(inf => inf.type == "command").listenerObject; popup.replaceChild(menuitem, node); } return popup; } : this.popupset.appendChild.bind(this.popupset); delete this.definePopupset; return this.definePopupset = popupset => popupset.appendChild = append; }, lss: Services.scriptloader.loadSubScript, async handleEvent({target: doc}) { if (!doc || doc.documentURI != this.url) return; var win = doc.defaultView; if ( win.docShell.name == "toolbox-panel-iframe-webconsole" || doc.DOMContentLoadedEventHandled ) return; doc.DOMContentLoadedEventHandled = true; if (this instanceof XULElement) // Custom Buttons "custombuttonsConsole" in win || this.lss( "chrome://custombuttons/content/consoleOverlay.js", win ); var cw = win.isChromeWindow, bc; if (!cw) { if (doc.visibilityState == "hidden") { var {focus} = win; win.focus = () => win.focus = focus; } doc.title = this.title; var link = doc.createElement("link"); link.setAttribute("rel", "shortcut icon"); link.setAttribute("href", this.icon); doc.head.prepend(link); var br = win.docShell.chromeEventHandler; var cmAttr = br.getAttribute("contextmenu"); cmAttr && br.removeAttribute("contextmenu"); win.onbeforeunload = () => { if (bc) bc.chromeWindow = {close() {}}; cmAttr && br.setAttribute("contextmenu", cmAttr); } } bc = await this.console(win); }, get console() { // Bug 1579090 - WebConsole should handle ObjectFront when needed (for non-primitive Console API args + Evaluation results) (Firefox 73+) https://bugzilla.mozilla.org/show_bug.cgi?id=1579090 var vers = parseInt(Services.appinfo.platformVersion); this.bug1579090 = vers > 73 || (vers == 73 && !( "_setCurrentURI" in gBrowser.selectedBrowser // https://bugzil.la/1431214 )); delete this.console; return this.console = this.bug1579090 ? async win => { //await this.loader.bcm._browserConsoleInitializing; var key = "CBBrowserConsolePromise", {wins} = this.loader; win[key] = win.Object.create(null); win[key].promise = new win.Promise(resolve => win[key].resolve = resolve); win[key].destroy = () => { win[key].resolve(); delete win[key]; wins.splice(wins.indexOf(win), 1); } wins.unshift(win); wins.length > 1 && await wins[1][key].promise; var bc = await new this.loader.console(win).toggleBrowserConsole(); win[key].destroy(); return bc; } : async win => { this.loader.Services.ww.wins.push(win); return await new this.loader.HUDService().toggleBrowserConsole(); } }, get loader() { delete this.loader; var url = parseInt(Services.appinfo.platformVersion) >= 96 ? "resource://devtools/shared/loader/Loader.jsm" : "resource://devtools/shared/Loader.jsm"; if (this.bug1579090) { var g = Cu.import(url, {}), key = "CBBrowserConsoleLoader"; addDestructor(reason => reason[5] == e && key in g && g[key].destroy()); if (key in g) return this.loader = g[key]; var {BrowserConsoleManager} = g.require( "devtools/client/webconsole/browser-console-manager" ); return this.loader = g[key] = { wins: [], bcm: BrowserConsoleManager, console: class extends BrowserConsoleManager.constructor { constructor(win) { super(); this.win = win; } openWindow() { var {win} = this; win.addEventListener("unload", () => { win.CBBrowserConsolePromise && win.CBBrowserConsolePromise.destroy(); this.closeBrowserConsole.call(this); }, {once: true}); delete this.win; return win; } }, destroy() { this.wins = null; delete g[key]; } }; } var id = _id + "-browser-console"; url += "?" + id; var loader = {exports: {}}, nsvo = Cu.import(url, loader); addDestructor(reason => reason[5] == "e" && Cu.unload(url)); if (id in nsvo) return this.loader = nsvo[id]; var dir = "resource://devtools/client/webconsole/"; try { this.lss(dir + "hudservice.js", loader); } catch(ex) { // Bug 1570320 - Rename hudservice.js into browser-console-manager.js (Firefox 70+) // https://bugzilla.mozilla.org/show_bug.cgi?id=1570320 this.lss(dir + "browser-console-manager.js", loader); this.lss("data:,this.HUDService=BrowserConsoleManager", loader); } var e = new CustomEvent("DOMContentLoaded", {bubbles: false}), ww = loader.Services.ww; loader.Services.ww = Cu.getGlobalForObject(nsvo).Object.create(ww, { wins: {value: []}, openWindow: {value: function() { var win = this.wins.shift(); win.setTimeout(() => win.dispatchEvent(e), 0); return win; }} }); return this.loader = nsvo[id] = loader; }, element(name, attrs, parent) { var node = document.createXULElement(name); for(var attr in attrs) node.setAttribute(attr, attrs[attr]); parent && parent.append(node); return node; } }).init(); this.tooltipText = "Консоль браузера" +"\n"+"\n"+ "ЛКМ: В боковой панели" +"\n"+ "СКМ: В новой вкладке" +"\n"+ "ПКМ: Стандартное меню "
Отсутствует
Ну и нашел еще одну кнопку, которая перестала работать в 136
Консоль браузера
Нее, от кнопки я решил отказаться.
На новых версиях, перехожу на скрипт для UCF.
Для сандбокса, custom_script.js, scriptsbackground
(в окна не совать!)
Локализация там, по сути, особо не нужна,
просто эксперимент с mock-fluent'ом.
(async url => { var img = "chrome://devtools/skin/images/tool-webconsole.svg"; var strings = { ru: { label: "Консоль браузера", tooltip: [ "Л: Сайдбар", "С: Вкладка", "П: Окно" ] }, def: { label: "Browser console", tooltip: [ "L: Sidebar", "M: Tab", "R: Window" ] }, }; var fluentLabel = "browser-console-label"; var fluentButton = "browser-console-button"; var fluentFile = "user/browser-console.ftl"; var version = parseInt(Services.appinfo.platformVersion); for (var [loc, data] of Object.entries(strings)) { var lab = data.label; strings[loc] = `${ fluentButton } =\n.label = ${lab}\n.tooltiptext = ${ data.tooltip.map(str => "\n " + str).join("") }\n${ fluentLabel } =\n.label = ${lab}`; } var registry = L10nRegistry.getInstance(); var sourceName = sfx => "u-browser-console-" + sfx; var getSource = (locs, meta, name) => { var sources = Array.from(locs, loc => ({ path: `/localization/${loc}/${fluentFile}`, source: strings[loc] || strings.def })); return L10nFileSource.createMock( name || sourceName("pkg"), meta, locs, "/localization/{locale}/", sources ); } registry.registerSources([ getSource(Services.locale.packagedLocales, "app") ]); var fileSources = new Map(); var register = langpacks => { var sourcesToReg = []; for(var langpack of langpacks) { var {langpackId, languages} = langpack.startupData; var name = sourceName(langpackId); if (registry.hasSource(name)) continue; var fileSource = fileSources.get(langpackId); fileSource || fileSources.set( langpackId, fileSource = getSource(languages, langpackId, name) ); sourcesToReg.push(fileSource); } registry.registerSources(sourcesToReg); } var file = Services.dirsvc.get("ProfD", Ci.nsIFile); file.append("extensions.json"); try { var langpacks = JSON.parse(Cu.readUTF8File(file)) .addons.filter(a => a.startupData?.langpackId && a.active); langpacks?.length && register(langpacks); } catch {} var unreg = addon => { if (addon.type != "locale") return; var name = sourceName(addon.__AddonInternal__.startupData.langpackId); registry.hasSource(name) && registry.removeSources([name]); } var addonListener = Object.create(null); for(var p of ["onDisabled", "onUninstalling", "onUninstalled"]) addonListener[p] = unreg; AddonManager.addAddonListener(addonListener); var topicLng = "webextension-langpack-startup"; var topicWin = "browser-delayed-startup-finished"; var {addObserver: add, removeObserver: rem} = Services.obs; var reg = subj => register([subj.wrappedJSObject.langpack]); add(reg, topicLng); add(onBrowserWin, topicWin); add(function quit(s, topic) { rem(quit, topic); rem(reg, topicLng); rem(onBrowserWin, topicWin); }, "quit-application-granted"); var addFtlLink = (doc, href) => { var link = doc.createElement("link"); link.rel = "localization"; link.href = href; doc.head.prepend(link); } var maybeInsertFTL = doc => !( doc.head.querySelector(`[href="${fluentFile}"]`) || addFtlLink(doc, fluentFile) ); var impl; CustomizableUI.createWidget(impl = { l10nId: fluentButton, id: "browser-console-button", defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { maybeInsertFTL(btn.ownerDocument); btn.image = img; for(var type of this.events) btn.addEventListener(type, this); }, events: ["command", "auxclick", "contextmenu"], handleEvent(e) { this[e.type](e); }, command(e) { e.view.SidebarController.toggle(id); }, auxclick(e) { if (e.button != 1) return; var gb = e.view.gBrowser; if (!e.ctrlKey && !e.shiftKey) for(var tab of gb.visibleTabs) if (tab.linkedBrowser?.currentURI.spec == url) return gb.selectedTab = tab; gb.selectedTab = gb.addTrustedTab(url, {index: gb.selectedTab._tPos + 1}); }, contextmenu(e) { if (!e.ctrlKey && !e.shiftKey) e.preventDefault(), this.bcm.openBrowserConsoleOrFocus(); }, get bcm() { delete this.bcm; return this.bcm = ChromeUtils.importESModule( "resource://devtools/shared/loader/Loader.sys.mjs" ).require( "devtools/client/webconsole/browser-console-manager" ).BrowserConsoleManager; } }); var revamp = true, pref = "sidebar.revamp"; if (Services.prefs.prefHasDefaultValue(pref)) { var obs = () => revamp = Services.prefs.getBoolPref(pref); Services.prefs.addObserver(pref, obs); obs(); } var id = "viewBrowserConsoleSidebar"; var addSidebar = version >= 135 ? (bars, sb) => bars.set(id, sb) : (bars, sb) => { // viewCustomizeSidebar breaks iteration in SidebarController.selectMenuItem() var arr = Array.from(bars); bars.clear(); bars.set(id, sb); for(var args of arr) bars.set(...args); } var maybeAddSidebar = (sc, sb) => { var bars = sc.sidebars; bars.has(id) || addSidebar(bars, sb); } var addFluentRes = sm => sm.fluentStrings.addResourceIds([fluentFile]); var ce = {configurable: true, enumerable: true}; function onBrowserWin(win) { win.addEventListener("DOMContentLoaded", onDOMContentLoaded); var doc = win.document; maybeInsertFTL(doc); var sc = win.SidebarController; var sep = doc.querySelector("#sidebarMenu-popup > menuseparator"); if (sep) { var switcher = doc.createXULElement("menuitem"); switcher.dataset.l10nId = fluentLabel; switcher.id = "sidebar-switcher-browser-console"; switcher.addEventListener("command", () => sc.toggle(id)); sep.before(switcher); } var sb = sc.makeSidebar({ url, iconUrl: img, elementId: switcher?.id, menuL10nId: fluentLabel, revampL10nId: fluentLabel, menuId: "menu_browserConsoleSidebar" }); var popup = doc.getElementById("viewSidebarMenu"); popup.insertBefore( sc.createMenuItem(id, sb), popup.querySelector(".webextension-menuitem") ); var o = win.Object; var def = (obj, prop, desc) => o.defineProperty(obj, prop, o.assign(desc, ce)); def(sb, "hasOwnProperty", {value(prop) { prop == "extensionId" && win.setTimeout(maybeAddSidebar, 0, sc, sb); return o.hasOwn(sb, prop); }}); addSidebar(sc.sidebars, sb); var br = sc.browser; def(UcfPrefs.dbg.ref("defaultTools", sc.init, win), id, {get() { var doc = br.contentDocument; var cust = doc?.querySelector("sidebar-customize"); cust && maybeInsertFTL(doc) && UcfPrefs.dbg.ref("l10nMap", cust.constructor, 0).set(id, fluentLabel); return "browserconsole"; }}); sc._toolsAndExtensions = null; var sm = sc.sidebarMain; if (revamp) addFluentRes(sm), sm.requestUpdate(); else win.customElements.whenDefined("sidebar-main").then(() => addFluentRes(sm)); } var noop = () => {}; var setSmall = hdr => hdr.shadowRoot .querySelector("moz-button").setAttribute("size", "small"); var addCloseBtn = async (doc, win) => { var main = doc.body.querySelector("main"); var {promise, resolve} = win.Promise.withResolvers(); var mo = new win.MutationObserver(resolve); mo.observe(main, {childList: true}); await promise; mo.disconnect(); var header = main.querySelector("header"); addFtlLink(doc, "browser/sidebar.ftl"); var url = "chrome://browser/content/sidebar/sidebar-panel-header.mjs"; UcfPrefs.dbg.makeGlobalObjectReference(win).executeInGlobal( `ChromeUtils.importESModule("${url}", {global: "current"});` ); var sph = doc.createElement("sidebar-panel-header"); header.append(sph); win.setTimeout(setSmall, 50, sph); var sheet = new win.CSSStyleSheet(); sheet.replaceSync(` h4 { display: none !important } :host { flex-grow: 1 !important; display: flex !important; justify-content: end !important; } moz-button, moz-button::part(button) { display: flex !important; height: 100% !important; min-height: 100% !important; } `); sph.shadowRoot.adoptedStyleSheets.push(sheet); } var onDOMContentLoaded = e => { var doc = e.target; if (doc?.documentURI != url) return; var win = doc.ownerGlobal, ds = win.docShell; ds.name != "toolbox-panel-iframe-webconsole" && onConsoleDOMContentLoaded(doc, win, ds); } var onConsoleDOMContentLoaded = async (doc, win, ds) => { try {Services.scriptloader.loadSubScript( "chrome://custombuttons/content/consoleOverlay.js", win )} catch {} var tabWin = !win.isChromeWindow; if (tabWin) { if (doc.visibilityState == "hidden") { var {focus} = win; win.focus = () => win.focus = focus; } win.browsingContext .currentWindowGlobal.windowGlobalChild .getActor("ContextMenu").handleEvent = noop; var br = ds.chromeEventHandler; var cmAttr = br.getAttribute("contextmenu"); var gb = br.ownerGlobal.gBrowser; gb.setIcon(gb.getTabForBrowser(br), img); } else if (revamp) addCloseBtn(doc, win); var bc = await getConsole(win); if (tabWin) { if (cmAttr) bc.cmAttr = cmAttr, (bc.br = br).removeAttribute("contextmenu"); bc.updateWindowTitle(win); } } var resolvers = []; var find = function(resolver) { return resolver.id == this; } var destroy = function() { this.resolve(); resolvers.splice(resolvers.indexOf(this), 1); } var getConsole = async win => { var resolver = Promise.withResolvers(); resolver.destroy = destroy; resolver.id = win.browsingContext.id; resolvers.unshift(resolver); resolvers.length > 1 && await resolvers[1].promise; var bc = await constructConsole(win); resolver.destroy(); return bc; } var constructConsole = win => { var closer = {close: noop}; var cc = class extends impl.bcm.constructor { constructor(win) { super(); this.win = win; } openWindow() { var {win} = this; win.addEventListener("unload", this, {once: true}); delete this.win; return win; } handleEvent(e) { resolvers.find(find, e.target.ownerGlobal.browsingContext.id)?.destroy(); var bc = this.getBrowserConsole(); bc.chromeWindow = closer; this.closeBrowserConsole(); bc.br?.isConnected && bc.br.setAttribute("contextmenu", bc.cmAttr); } } return (constructConsole = win => new cc(win).toggleBrowserConsole())(win); } })("chrome://devtools/content/webconsole/index.html");
Отредактировано Dumby (Вчера 19:15:11)
Отсутствует
А ты случайно не делал скрипт UserCSSLoader,
чето кнопка уменя не работает.
Нет. Я даже не знаю что это такое.
А не работает, скорее всего, из-за «on…» атрибутов
и/или C{u, hromeUtils}.import(). Это основной отвал на 136.
Отсутствует
"Ну и нашел еще одну кнопку, которая перестала работать в 136
Консоль браузера"
Прошу прощения, кнопка рабочая. Там был конфликт с одним раширением.
Отредактировано Garalf (Вчера 22:14:43)
Отсутствует