обновил Add Toolbar Buttons, почти все добавил, изменил то что спрашивали
Отредактировано Vitaliy V. (18-09-2020 16:42:20)
Отсутствует
Vitaliy V.
Может еще опций отображения добавить? Просто опишу свое видение этого меню:
В подсказке - описание и тип, как по мне, только место занимают. Заголовок "Разрешения" - выглядит лишним. И так понятно, что это разрешения. Например, у описания же нету заголовка "Описание". ID и UUID там понятно, без заголовка можно спутать.
Темы и лангпаки - тоже не всем нужны. Мне точно не нужны, английский лангпак только зря ширину меню увеличивает на десяток символов. Если конечно ширина зависит от длины имен элементов (лучше бы зависела, до определенного максимума).
И хорошо бы цветовое выделение добавить отключенным расширениям, в виде опции.
СКМ - "открыть менеджер дополнений". Ну почему СКМ? )
Для меня смысл меню не отобразить все, а отобразить то что может потребоваться отключить или быстро настроить. Ни тему, ни лангпак я никогда переключать не буду. А вот скрытые пригодятся, вдруг при обновлении удалить что то забуду.
Отсутствует
Если кому нужна отдельно кнопка Дополнения как в Add Toolbar Buttons то вот для custom_script.js
Отредактировано Vitaliy V. (07-05-2022 12:12:25)
Отсутствует
Если кому нужна отдельно кнопка Дополнения как в Add Toolbar Buttons то вот для custom_script.js
скрытый текстВыделить кодКод:
try {(() => { var id = "ucf-aom-button", label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nShift+ЛКМ: Меню дополнений + открыть менеджер\nСКМ: Открыть менеджер дополнений", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 24,4.5 18,12 3,23.7 12,32.7 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 26.1 L 34.8,12.9 31.8,12.3 Z'/><path style='fill:white;' d='M 19.88,3 C 16.93,3 14.55,4.662 14.55,6.701 14.63,7.474 15.11,8.438 15.37,8.762 16.59,10.41 16.59,11.44 16.29,12.06 H 6.299 C 4.476,12.06 3,13.53 3,15.35 V 23.68 C 3.625,24 4.65,24 6.299,22.77 6.625,22.52 7.587,22.02 8.363,21.94 10.4,21.94 12.06,24.35 12.06,27.29 12.06,30.24 10.4,32.65 8.363,32.65 7.725,32.63 6.774,32.07 6.299,31.82 4.65,30.59 3.625,30.59 3,30.91 V 41.71 C 3,43.53 4.476,45 6.299,45 H 19.58 C 19.88,44.38 19.88,43.35 18.65,41.71 18.4,41.38 17.91,40.42 17.82,39.65 17.82,37.6 20.23,35.94 23.18,35.94 26.14,35.94 28.55,37.6 28.55,39.65 28.53,40.28 27.97,41.23 27.71,41.71 26.47,43.35 26.47,44.38 26.79,45 H 32.65 C 34.47,45 35.96,43.53 35.96,41.71 V 32.55 C 36.56,32.23 37.59,32.23 39.23,33.47 39.72,33.73 40.68,34.29 41.29,34.29 43.35,34.29 45,31.91 45,28.94 45,25.99 43.35,23.59 41.29,23.59 40.54,23.67 39.58,24.17 39.23,24.41 37.59,25.65 36.56,25.65 35.96,25.33 V 15.35 C 35.96,13.53 34.47,12.06 32.65,12.06 H 23.49 C 23.19,11.44 23.19,10.41 24.41,8.762 24.66,8.287 25.22,7.337 25.23,6.713 25.23,4.662 22.85,3 19.88,3' /></g></svg>", checked = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='M 4,5 7.5,8.5 12,4 V 8 L 8,12 H 7 L 4,9 Z' style='fill:white'/></svg>", show_version = true, show_description = true, user_permissions = true, show_hidden = true, show_disabled = true, enabled_first = true, exceptions_listset = new Set([ ]); exceptions_type_listset = new Set([ ]); if (!("AddonManager" in this)) ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); if (!("GlobalManager" in this)) XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => { const { GlobalManager } = ChromeUtils.import("resource://gre/modules/Extension.jsm", null); return GlobalManager; }); var extensionOptionsMenu = { get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, get exceptions_type_listarr() { delete this.exceptions_type_listarr; var arr = ["extension", "theme", "locale", "dictionary"]; if (!exceptions_type_listset.size) return this.exceptions_type_listarr = arr; return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type)); }, populateMenu: async function(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(), setAttributesMenu = (mi, addon, extension) => { var permissions, uuid, props = { label: `${addon.name}${show_version ? ` ${addon.version}` : ""}`, class: "menuitem-iconic", tooltiptext: `${(show_description && addon.description) ? `${addon.description}\n` : ""}ID: ${addon.id}${addon.isActive && (uuid = extension?.uuid) ? `\nUUID: ${uuid}` : ""}${(user_permissions && (permissions = addon.userPermissions?.permissions)?.length) ? `\nРазрешения: ${permissions.join(", ")}` : ""}\n${addon.optionsURL ? "\nЛКМ: Настройки" : ""}\nCtrl+ЛКМ: Копировать ID${uuid ? "\nShift+ЛКМ: Копировать UUID" : ""}${addon.creator?.url ? "\nCtrl+Shift+ЛКМ: Автор" : ""}${addon.homepageURL ? "\nСКМ: Домашняя страница" : ""}${!addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : ""}\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${(!addon.isSystem && !addon.isBuiltin) ? "\nCtrl+ПКМ: Удалить" : ""}`, }; for (let p in props) mi.setAttribute(p, props[p]); if (addon.iconURL) mi.setAttribute("image", addon.iconURL); var cls = mi.classList; addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled"); addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions"); addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system"); cls.add(`ucf-type-${addon.type}`); }; addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => { var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`; var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`; return (ka < kb) ? -1 : 1; }).forEach(addon => { if (!exceptions_listset.has(addon.id) && (!addon.hidden || show_hidden) && (!addon.userDisabled || show_disabled)) { let extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.append(mi); addonsMap.set(addon, mi); } }); var click = (e) => { this.handleClick(e); }; popup.addEventListener("click", click); var listener = { onEnabled: addon => { var mi = addonsMap.get(addon); if (mi) setAttributesMenu(mi, addon, mi._Extension); }, onDisabled: addon => { listener.onEnabled(addon); }, onInstalled: addon => { var extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.prepend(mi); addonsMap.set(addon, mi); }, onUninstalled: addon => { var mi = addonsMap.get(addon); if (mi) { mi.remove(); addonsMap.delete(addon); } }, }; AddonManager.addAddonListener(listener); popup.addEventListener("popuphiding", (e) => { AddonManager.removeAddonListener(listener); popup.removeEventListener("click", click); addonsMap = null; while (popup.hasChildNodes()) popup.firstChild.remove(); }, { once: true }); }, handleClick: function(e) { var win = e.view, mi = e.target; if (!("_Addon" in mi) || !("_Extension" in mi)) return; var addon = mi._Addon, extension = mi._Extension; switch (e.button) { case 0: if (e.ctrlKey && e.shiftKey) { if (addon.creator?.url) win.gBrowser.selectedTab = this.addTab(win, addon.creator.url); } else if (e.ctrlKey) { this.clipboardHelp.copyString(addon.id); try { this.alertsService.showAlertNotification(`${img}`, "ID в буфере обмена!", addon.id, false); } catch(e) {} } else if (e.shiftKey) { if (extension?.uuid) { this.clipboardHelp.copyString(extension.uuid); try { this.alertsService.showAlertNotification(`${img}`, "UUID в буфере обмена!", extension.uuid, false); } catch(e) {} } } else if (addon.isActive && addon.optionsURL) this.openAddonOptions(addon, win); win.closeMenus(mi); break; case 1: if (e.ctrlKey) { if (!addon.isBuiltin) this.browseDir(addon); } else if (e.shiftKey) this.browseDir(addon, win); else if (addon.homepageURL) win.gBrowser.selectedTab = this.addTab(win, addon.homepageURL); win.closeMenus(mi); break; case 2: if (!e.ctrlKey) { let endis = addon.userDisabled ? "enable" : "disable"; if (addon.id == "screenshots@mozilla.org") Services.prefs.setBoolPref("extensions.screenshots.disabled", !addon.userDisabled); else if (addon.id == "webcompat-reporter@mozilla.org") Services.prefs.setBoolPref("extensions.webcompat-reporter.enabled", addon.userDisabled); addon[endis]({ allowSystemAddons: true }); } else if (!addon.isSystem && !addon.isBuiltin && Services.prompt.confirm(win, null, `Удалить ${addon.name}?`)) addon.uninstall(); break; } }, openAddonOptions: function(addon, win) { switch (addon.optionsType) { case 5: win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`); break; case 3: win.switchToTabHavingURI(addon.optionsURL, true); break; } }, browseDir: function(addon, win) { try { if (!win) { let file = Services.io.getProtocolHandler("file") .QueryInterface(Ci.nsIFileProtocolHandler) .getFileFromURLSpec(addon.getResourceURI().QueryInterface(Ci.nsIJARURI).JARFile.spec); if (file.exists()) file.launch(); } else win.gBrowser.selectedTab = this.addTab(win, addon.getResourceURI().spec); } catch (e) {} }, addTab: function(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.relatedToCurrent = true; return win.gBrowser.addTab(url, params); }, }; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView, props = { id: id, label: label, tooltiptext: tooltiptext, type: "menu", class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.addEventListener("click", (e) => { if (e.button == 0) { if (e.shiftKey) win.BrowserOpenAddonsMgr(); } else if (e.button == 1) win.BrowserOpenAddonsMgr(); }); var mp = doc.createXULElement("menupopup"); mp.id = `${id}-popup`; mp.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("contextmenu", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("popupshowing", (e) => { extensionOptionsMenu.populateMenu(e); }); btn.append(mp); var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}, #${id}-popup menuitem { list-style-image: url("${img}") !important; } #${id}-popup menuitem::after { display: -moz-box !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid rgb(0, 116, 232) !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: rgb(0, 116, 232) !important; background-image: url("${checked}") !important; opacity: 1 !important; } #${id}-popup menuitem.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .6 !important; } #${id}-popup menuitem.ucf-disabled > label, #${id}-popup menuitem.ucf-notoptions > label { opacity: .6 !important; } #${id}-popup menuitem.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } #${id}-popup menuitem > label { margin-inline-end: 0 !important; } #${id}-popup menuitem > .menu-accel-container { display: -moz-box !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel { display: -moz-box !important; margin: 0 !important; height: 8px !important; width: 8px !important; border-radius: 4px !important; background-color: transparent !important; opacity: 1 !important; font-size: 0 !important; } #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: rgb(227, 27, 93) !important; } #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: rgb(48, 172, 55) !important; } #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: rgb(219, 106, 0) !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })();} catch (e) {}
Конечно же нужна. Эта ещё круче прежней! Огромное Спасибо!
Обновлённый код с правкой для 101+
try {(() => { var id = "ucf-aom-button", label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nShift+ЛКМ: Меню дополнений + открыть менеджер\nСКМ: Открыть менеджер дополнений", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 48 48'><g><rect x='0' y='0' width='48' height='48' rx='3' ry='3' style='fill:rgb(0, 120, 173);'/><path style='opacity:0.25;fill:black;' d='M 24,4.5 18,12 3,23.7 12,32.7 3.9,44.1 7.8,48 H 45 C 46.7,48 48,46.7 48,45 V 26.1 L 34.8,12.9 31.8,12.3 Z'/><path style='fill:white;' d='M 19.88,3 C 16.93,3 14.55,4.662 14.55,6.701 14.63,7.474 15.11,8.438 15.37,8.762 16.59,10.41 16.59,11.44 16.29,12.06 H 6.299 C 4.476,12.06 3,13.53 3,15.35 V 23.68 C 3.625,24 4.65,24 6.299,22.77 6.625,22.52 7.587,22.02 8.363,21.94 10.4,21.94 12.06,24.35 12.06,27.29 12.06,30.24 10.4,32.65 8.363,32.65 7.725,32.63 6.774,32.07 6.299,31.82 4.65,30.59 3.625,30.59 3,30.91 V 41.71 C 3,43.53 4.476,45 6.299,45 H 19.58 C 19.88,44.38 19.88,43.35 18.65,41.71 18.4,41.38 17.91,40.42 17.82,39.65 17.82,37.6 20.23,35.94 23.18,35.94 26.14,35.94 28.55,37.6 28.55,39.65 28.53,40.28 27.97,41.23 27.71,41.71 26.47,43.35 26.47,44.38 26.79,45 H 32.65 C 34.47,45 35.96,43.53 35.96,41.71 V 32.55 C 36.56,32.23 37.59,32.23 39.23,33.47 39.72,33.73 40.68,34.29 41.29,34.29 43.35,34.29 45,31.91 45,28.94 45,25.99 43.35,23.59 41.29,23.59 40.54,23.67 39.58,24.17 39.23,24.41 37.59,25.65 36.56,25.65 35.96,25.33 V 15.35 C 35.96,13.53 34.47,12.06 32.65,12.06 H 23.49 C 23.19,11.44 23.19,10.41 24.41,8.762 24.66,8.287 25.22,7.337 25.23,6.713 25.23,4.662 22.85,3 19.88,3' /></g></svg>", checked = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><path d='M 4,5 7.5,8.5 12,4 V 8 L 8,12 H 7 L 4,9 Z' style='fill:white'/></svg>", show_version = true, show_description = true, user_permissions = true, show_hidden = true, show_disabled = true, enabled_first = true, exceptions_listset = new Set([ ]); exceptions_type_listset = new Set([ ]); if (!("AddonManager" in this)) ChromeUtils.defineModuleGetter(this, "AddonManager", "resource://gre/modules/AddonManager.jsm"); if (!("GlobalManager" in this)) XPCOMUtils.defineLazyGetter(this, "GlobalManager", () => ChromeUtils.import("resource://gre/modules/ExtensionParent.jsm").ExtensionParent.GlobalManager); var extensionOptionsMenu = { get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, get exceptions_type_listarr() { delete this.exceptions_type_listarr; var arr = ["extension", "theme", "locale", "dictionary"]; if (!exceptions_type_listset.size) return this.exceptions_type_listarr = arr; return this.exceptions_type_listarr = arr.filter(type => !exceptions_type_listset.has(type)); }, populateMenu: async function(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(), setAttributesMenu = (mi, addon, extension) => { var permissions, uuid, props = { label: `${addon.name}${show_version ? ` ${addon.version}` : ""}`, class: "menuitem-iconic", tooltiptext: `${(show_description && addon.description) ? `${addon.description}\n` : ""}ID: ${addon.id}${addon.isActive && (uuid = extension?.uuid) ? `\nUUID: ${uuid}` : ""}${(user_permissions && (permissions = addon.userPermissions?.permissions)?.length) ? `\nРазрешения: ${permissions.join(", ")}` : ""}\n${addon.optionsURL ? "\nЛКМ: Настройки" : ""}\nCtrl+ЛКМ: Копировать ID${uuid ? "\nShift+ЛКМ: Копировать UUID" : ""}${addon.creator?.url ? "\nCtrl+Shift+ЛКМ: Автор" : ""}${addon.homepageURL ? "\nСКМ: Домашняя страница" : ""}${!addon.isBuiltin ? "\nCtrl+СКМ: Просмотр источника" : ""}\nShift+СКМ: Просмотр источника во вкладке\nПКМ: Включить/Отключить${(!addon.isSystem && !addon.isBuiltin) ? "\nCtrl+ПКМ: Удалить" : ""}`, }; for (let p in props) mi.setAttribute(p, props[p]); if (addon.iconURL) mi.setAttribute("image", addon.iconURL); var cls = mi.classList; addon.isActive ? cls.remove("ucf-disabled") : cls.add("ucf-disabled"); addon.optionsURL ? cls.remove("ucf-notoptions") : cls.add("ucf-notoptions"); addon.isSystem ? cls.add("ucf-system") : cls.remove("ucf-system"); cls.add(`ucf-type-${addon.type}`); }; addons.filter(a => !(a.iconURL || "").startsWith("resource://search-extensions/")).sort((a, b) => { var ka = `${(enabled_first ? a.isActive ? "0" : "1" : "")}${a.type || ""}${a.name.toLowerCase()}`; var kb = `${(enabled_first ? b.isActive ? "0" : "1" : "")}${b.type || ""}${b.name.toLowerCase()}`; return (ka < kb) ? -1 : 1; }).forEach(addon => { if (!exceptions_listset.has(addon.id) && (!addon.hidden || show_hidden) && (!addon.userDisabled || show_disabled)) { let extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.append(mi); addonsMap.set(addon, mi); } }); var click = (e) => { this.handleClick(e); }; popup.addEventListener("click", click); var listener = { onEnabled: addon => { var mi = addonsMap.get(addon); if (mi) setAttributesMenu(mi, addon, mi._Extension); }, onDisabled: addon => { listener.onEnabled(addon); }, onInstalled: addon => { var extension = GlobalManager.extensionMap.get(addon.id), mi = doc.createXULElement("menuitem"); setAttributesMenu(mi, addon, extension); mi._Addon = addon; mi._Extension = extension; popup.prepend(mi); addonsMap.set(addon, mi); }, onUninstalled: addon => { var mi = addonsMap.get(addon); if (mi) { mi.remove(); addonsMap.delete(addon); } }, }; AddonManager.addAddonListener(listener); popup.addEventListener("popuphiding", (e) => { AddonManager.removeAddonListener(listener); popup.removeEventListener("click", click); addonsMap = null; while (popup.hasChildNodes()) popup.firstChild.remove(); }, { once: true }); }, handleClick: function(e) { var win = e.view, mi = e.target; if (!("_Addon" in mi) || !("_Extension" in mi)) return; var addon = mi._Addon, extension = mi._Extension; switch (e.button) { case 0: if (e.ctrlKey && e.shiftKey) { if (addon.creator?.url) win.gBrowser.selectedTab = this.addTab(win, addon.creator.url); } else if (e.ctrlKey) { this.clipboardHelp.copyString(addon.id); try { this.alertsService.showAlertNotification(`${img}`, "ID в буфере обмена!", addon.id, false); } catch(e) {} } else if (e.shiftKey) { if (extension?.uuid) { this.clipboardHelp.copyString(extension.uuid); try { this.alertsService.showAlertNotification(`${img}`, "UUID в буфере обмена!", extension.uuid, false); } catch(e) {} } } else if (addon.isActive && addon.optionsURL) this.openAddonOptions(addon, win); win.closeMenus(mi); break; case 1: if (e.ctrlKey) { if (!addon.isBuiltin) this.browseDir(addon); } else if (e.shiftKey) this.browseDir(addon, win); else if (addon.homepageURL) win.gBrowser.selectedTab = this.addTab(win, addon.homepageURL); win.closeMenus(mi); break; case 2: if (!e.ctrlKey) { let endis = addon.userDisabled ? "enable" : "disable"; if (addon.id == "screenshots@mozilla.org") Services.prefs.setBoolPref("extensions.screenshots.disabled", !addon.userDisabled); else if (addon.id == "webcompat-reporter@mozilla.org") Services.prefs.setBoolPref("extensions.webcompat-reporter.enabled", addon.userDisabled); addon[endis]({ allowSystemAddons: true }); } else if (!addon.isSystem && !addon.isBuiltin && Services.prompt.confirm(win, null, `Удалить ${addon.name}?`)) addon.uninstall(); break; } }, openAddonOptions: function(addon, win) { switch (addon.optionsType) { case 5: win.BrowserOpenAddonsMgr(`addons://detail/${encodeURIComponent(addon.id)}/preferences`); break; case 3: win.switchToTabHavingURI(addon.optionsURL, true); break; } }, browseDir: function(addon, win) { try { if (!win) { let file = Services.io.getProtocolHandler("file") .QueryInterface(Ci.nsIFileProtocolHandler) .getFileFromURLSpec(addon.getResourceURI().QueryInterface(Ci.nsIJARURI).JARFile.spec); if (file.exists()) file.launch(); } else win.gBrowser.selectedTab = this.addTab(win, addon.getResourceURI().spec); } catch (e) {} }, addTab: function(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.relatedToCurrent = true; return win.gBrowser.addTab(url, params); }, }; CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView, props = { id: id, label: label, tooltiptext: tooltiptext, type: "menu", class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.addEventListener("click", (e) => { if (e.button == 0) { if (e.shiftKey) win.BrowserOpenAddonsMgr(); } else if (e.button == 1) win.BrowserOpenAddonsMgr(); }); var mp = doc.createXULElement("menupopup"); mp.id = `${id}-popup`; mp.addEventListener("click", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("contextmenu", (e) => { e.preventDefault(); e.stopPropagation(); }); mp.addEventListener("popupshowing", (e) => { extensionOptionsMenu.populateMenu(e); }); btn.append(mp); var btnstyle = "data:text/css;charset=utf-8," + encodeURIComponent(` #${id}, #${id}-popup menuitem { list-style-image: url("${img}") !important; } #${id}-popup menuitem::after { display: -moz-box !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid rgb(0, 116, 232) !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: rgb(0, 116, 232) !important; background-image: url("${checked}") !important; opacity: 1 !important; } #${id}-popup menuitem.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .6 !important; } #${id}-popup menuitem.ucf-disabled > label, #${id}-popup menuitem.ucf-notoptions > label { opacity: .6 !important; } #${id}-popup menuitem.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } #${id}-popup menuitem > label { margin-inline-end: 0 !important; } #${id}-popup menuitem > .menu-accel-container { display: -moz-box !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } #${id}-popup menuitem > .menu-accel-container .menu-iconic-accel { display: -moz-box !important; margin: 0 !important; height: 8px !important; width: 8px !important; border-radius: 4px !important; background-color: transparent !important; opacity: 1 !important; font-size: 0 !important; } #${id}-popup menuitem.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: rgb(227, 27, 93) !important; } #${id}-popup menuitem.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: rgb(48, 172, 55) !important; } #${id}-popup menuitem.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: rgb(219, 106, 0) !important; } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })();} catch (e) {}
Отредактировано sandro79 (31-05-2022 13:17:51)
Отсутствует
обновил Add Toolbar Buttons, почти все добавил, изменил то что спрашивали
Круто, ну очень круто. Просто великолепная кнопка получилась. Темы теперь очень удобно переключать. Спасибо большое!
Отсутствует
Опять кнопка перезапуска в appmenu не работает на 81.0 есть ли у кого рабочая поделитесь пожалуйста
Отсутствует
egorsemenov06
https://forum.mozilla-russia.org/viewto … 07#p785107
Отредактировано Vitaliy V. (15-12-2021 15:03:02)
Отсутствует
egorsemenov06
ну если нет рабочих, тогда
ucf_custom_script_win.loadскрытый текстВыделить кодКод:
(() => { var afterbtn = document.querySelector("#appMenu-viewCache")?.content.querySelector("#appMenu-mainView #appMenu-quit-button") || document.querySelector("#appMenu-mainView #appMenu-quit-button"); if (!afterbtn) return; var btn = document.createXULElement("toolbarbutton"); btn.id = "ucf-appMenu-restart-button"; btn.className = "subviewbutton subviewbutton-iconic"; btn.setAttribute("label", "Перезагрузка"); btn.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nCtrl+ЛКМ: Отключить загрузку содержимого из кеша и перезапустить\nShift+ЛКМ: Перезапустить без дополнений"); btn.setAttribute("shortcut", "Ctrl+Alt+Q"); btn.style.setProperty("list-style-image", 'url("chrome://browser/skin/reload.svg")', "important"); afterbtn.before(btn); btn._restart_mozilla = function(nocache = false) { var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); if (cancelQuit.data) return false; if (nocache) Services.appinfo.invalidateCachesOnRestart(); var restart = Services.startup; restart.quit(restart.eAttemptQuit | restart.eRestart); }; var command = function(e) { if (e.ctrlKey) this._restart_mozilla(true); else if (e.shiftKey) e.view.safeModeRestart(); else this._restart_mozilla(); }.bind(btn); btn.addEventListener("command", command); var keydown = function(e) { if (e.keyCode == 81 && e.ctrlKey && e.altKey) this._restart_mozilla(); }.bind(btn); window.addEventListener("keydown", keydown); this.appmenurestartbutton = { destructor() { btn.removeEventListener("command", command); window.removeEventListener("keydown", keydown); } }; this.unloadlisteners.push("appmenurestartbutton"); })();
Спасибо!!!
Отредактировано egorsemenov06 (22-09-2020 01:34:17)
Отсутствует
egorsemenov06
UPD: или лучше так сделать
так у меня не заработали сочетания Ctrl+ЛКМ и Shift+ЛКМ
Отсутствует
так у меня не заработали сочетания Ctrl+ЛКМ и Shift+ЛКМ
Проверил ещё раз, всё работает,
только заменил #appMenu-viewCache на template#appMenu-viewCache чтобы в 74 - 79 тоже работало.
Отредактировано Vitaliy V. (22-09-2020 12:28:58)
Отсутствует
egorsemenov06 пишеттак у меня не заработали сочетания Ctrl+ЛКМ и Shift+ЛКМ
Проверил ещё раз, всё работает,
только заменил #appMenu-viewCache на template#appMenu-viewCache чтобы в74 - 79 тоже работало.
Спасибо работает!
Отсутствует
только заменил #appMenu-viewCache на template#appMenu-viewCache чтобы в
74 - 79 тоже работало
Виталий, а можно сделать чтоб было как в user_chrome_files, те же самые команды и в той же последовательности как в user_chrome_files, по ЛКМ, СКМ и ПКМ в appMenu для 78 - 80? Очень хочется заменить эту кнопку на Вашу.
Использую как резервную, если не туда мышкой попал, что частенько случается, одна в "Другие инструменты", другая в Гамбургер-меню.
// Restart item script for Firefox 60+ by Aris // // left-click on restart item: normal restart // middle-click on restart item: restart + clear caches // right-click on restart item: no special function // // based on 'addRestartButton.uc.js' script by Alice0775 // restart code from Classic Theme Restorer add-on // invalidate caches from Session Saver add-on var {Services} = Components.utils.import("resource://gre/modules/Services.jsm", {}); var appversion = parseInt(Services.appinfo.version); var RestartMenuFileAppItems = { init: function() { var button_label = "Перезапуск"; try { switch (document.getElementById("nav-bar").getAttribute("aria-label")) { case "Navigations-Symbolleiste": button_label = "Neustarten"; break; case "Панель навигации": button_label = "Перезапустить"; break; } } catch(e) {} try { if(appversion <= 62) restartitem_filemenu = document.createElement("menuitem"); else restartitem_filemenu = document.createXULElement("menuitem"); restartitem_filemenu.setAttribute("label", button_label); restartitem_filemenu.setAttribute("id","fileMenu-restart-item"); restartitem_filemenu.setAttribute("key", "R"); restartitem_filemenu.setAttribute("insertbefore", "menu_FileQuitItem"); restartitem_filemenu.setAttribute("onclick", "if (event.button == 0) {RestartMenuFileAppItems.restartApp(false);} else if (event.button == 1) {RestartMenuFileAppItems.restartApp(true)};"); restartitem_filemenu.setAttribute("oncommand", "RestartMenuFileAppItems.restartApp(false);"); if(document.getElementById("menu_FileQuitItem").previousSibling.id != "fileMenu-restart-item" ) document.getElementById("menu_FileQuitItem").parentNode.insertBefore(restartitem_filemenu,document.getElementById("menu_FileQuitItem")); } catch(e) {} try { if(appversion <= 62) restartitem_appmenu = document.createElement("toolbarbutton"); else restartitem_appmenu = document.createXULElement("toolbarbutton"); restartitem_appmenu.setAttribute("label", button_label); restartitem_appmenu.setAttribute("id","appMenu-restart-button"); restartitem_appmenu.setAttribute("class","subviewbutton subviewbutton-iconic"); restartitem_appmenu.setAttribute("key", "R"); restartitem_appmenu.setAttribute("insertbefore", "appMenu-quit-button"); restartitem_appmenu.setAttribute("onclick", "if (event.button == 0) {RestartMenuFileAppItems.restartApp(false);} else if (event.button == 1) {RestartMenuFileAppItems.restartApp(true)};"); restartitem_appmenu.setAttribute("oncommand", "RestartMenuFileAppItems.restartApp(false);"); if(document.getElementById("appMenu-quit-button").previousSibling.id != "appMenu-restart-button" ) document.getElementById("appMenu-quit-button").parentNode.insertBefore(restartitem_appmenu,document.getElementById("appMenu-quit-button")); } catch(e) {} var sss = Components.classes["@mozilla.org/content/style-sheet-service;1"].getService(Components.interfaces.nsIStyleSheetService); // style button icon var uri = Services.io.newURI("data:text/css;charset=utf-8," + encodeURIComponent('\ \ #appMenu-restart-button {\ list-style-image: url("chrome://browser/skin/reload.svg"); /* icon / path to icon */ \ }\ #appMenu-restart-button .toolbarbutton-icon {\ color: red; /* icon color name/code */\ }\ \ '), null, null); sss.loadAndRegisterSheet(uri, sss.AGENT_SHEET); }, restartApp: function(clearcaches) { var cancelQuit = Components.classes["@mozilla.org/supports-PRBool;1"].createInstance(Components.interfaces.nsISupportsPRBool); var observerSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); if(clearcaches) { Components.classes["@mozilla.org/xre/app-info;1"].getService(Components.interfaces.nsIXULRuntime).invalidateCachesOnRestart(); } observerSvc.notifyObservers(cancelQuit, "quit-application-requested", "restart"); if(cancelQuit.data) return false; Services.startup.quit(Services.startup.eRestart | Services.startup.eAttemptQuit); } } RestartMenuFileAppItems.init();
Виталий, и можно чтоб кнопка была красного цвета, как у Aris-a. Спасибо заранее.
Отредактировано sandro79 (22-09-2020 20:58:24)
Отсутствует
sandro79
про классическое меню ничего не сказано но добавил и туда на всякий случай
(this.menusrestartitems = { init(that) { var btnClass = "ucf-appmenu-restart-button", muimID = "ucf_menu_FileRestartItem", ucf_script = (window.ucf_custom_script_win == that) ? "ucf_custom_script_win" : "ucf_custom_script_all_win"; var abtns = document.querySelector("template#appMenu-viewCache")?.content.querySelectorAll("#appMenu-quit-button, #appMenu-quit-button2") || document.querySelectorAll("#appMenu-quit-button"); for (let abtn of abtns) { let frag = MozXULElement.parseXULToFragment(`<toolbarbutton/>`); let btn = frag.firstElementChild; btn.className = `${btnClass} subviewbutton${!abtn.classList.contains("subviewbutton-iconic") ? "" : " subviewbutton-iconic"}`; btn.setAttribute("label", "Перезапуск"); btn.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска"); btn.setAttribute("shortcut", "Ctrl+Alt+Q"); btn.setAttribute("onclick", `${ucf_script}.menusrestartitems.restart_mozilla(event)`); abtn.before(frag); } var aftermuim = document.querySelector("#menu_FilePopup #menu_FileQuitItem"); if (aftermuim) { let muim = document.createXULElement("menuitem"); muim.id = muimID; muim.className = "menuitem-iconic"; muim.setAttribute("label", "Перезапуск"); muim.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска"); muim.setAttribute("acceltext", "Ctrl+Alt+Q"); muim.setAttribute("context", ""); muim.setAttribute("onclick", `${ucf_script}.menusrestartitems.restart_mozilla(event)`); aftermuim.before(muim); } var style = "data:text/css;charset=utf-8," + encodeURIComponent(` .${btnClass}.subviewbutton-iconic, #${muimID} { list-style-image: url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16'><path style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M11.4 5.6h4v-4M14.8 5C14.1 3.5 12 .6 8 .6S.6 4 .6 8 4 15.4 8 15.4s6.3-2.9 7-5'/></svg>") !important; } .${btnClass}.subviewbutton-iconic .toolbarbutton-icon, #${muimID} .menu-iconic-icon { -moz-context-properties: fill !important; fill: color-mix(in srgb, currentColor 20%, #f38525) !important; } `); try { windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); } catch (e) {} window.addEventListener("keydown", this); that.unloadlisteners?.push("menusrestartitems"); }, restart_mozilla(e) { if (e.button == 0) this._restart_mozilla(); else if (e.button == 1) e.view.safeModeRestart(); else if (e.button == 2) this._restart_mozilla(true); }, _restart_mozilla(nocache = false) { var cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancelQuit, "quit-application-requested", "restart"); if (cancelQuit.data) return false; if (nocache) Services.appinfo.invalidateCachesOnRestart(); var restart = Services.startup; restart.quit(restart.eAttemptQuit | restart.eRestart); }, handleEvent(e) { if (e.code == "KeyQ" && e.ctrlKey && e.altKey) this._restart_mozilla(); }, destructor() { window.removeEventListener("keydown", this); } }).init(this);
Отредактировано Vitaliy V. (24-09-2021 13:29:54)
Отсутствует
sandro79
про классическое меню ничего не сказано но добавил и туда на всякий случай
Да-да, там тоже лишним не будет. Огромное Вам Спасибо, подключил, всё отлично работает
Отсутствует
Vitaliy V.
Подскажите пожалуйста селектор сепараторов закладок в сайдбаре. Не пойму как его получить.
_ztс
скрытый текстВыделить кодКод:
treechildren.sidebar-placesTreechildren::-moz-tree-separator { border-top: 1px solid currentColor !important; border-bottom: none !important; }
Спасибо.
Отредактировано _zt (25-09-2020 00:19:05)
Отсутствует
_zt
treechildren.sidebar-placesTreechildren::-moz-tree-separator { border-top: 1px solid currentColor !important; border-bottom: none !important; }
Отсутствует
Всем хорошего дня.
Укажите как "донастроить". FF 81.0 (тема тёмная стандарт) + Aris-t2 3.1.7.
1. Вкладка "Дополнения" - сделать тёмный фон (ранее имелось).
2. Вкладки "Настройки", "Логины и пароли) - - сделать тёмный фон (если это возможно).
3. В выпадающем списке адресной строки не выравнивать ресурсы - что бы сразу за поисковым запросом через тире.
И, если это возможно для текущей версии ФФ, - очень хотелось бы прозрачность фона меню (в идеале - градиентная прозрачность).
Спасибо.
Отсутствует
Всем хорошего дня.
Взаимно.
Укажите как "донастроить". FF 81.0 (тема тёмная стандарт) + Aris-t2 3.1.7.
1. Вкладка "Дополнения" - сделать тёмный фон (ранее имелось).
2. Вкладки "Настройки", "Логины и пароли) - - сделать тёмный фон (если это возможно).
Создать числовой параметр ui.systemUsesDarkTheme = 1
И, если это возможно для текущей версии ФФ, - очень хотелось бы прозрачность фона меню
Пробовал недавно в виде эксперимента этот стиль с добавлением menupopup, получилось вроде неплохо.
/* Тултипы */ tooltip, menupopup { -moz-appearance: none !important; color: rgb(244,244,245) !important; background: rgba(11,11,12,0.7) !important; border: 1px solid rgba(0,0,0,0.1) !important; outline: 1px solid rgba(255,255,255,0.4) !important; border-radius: 0px !important; /* радиус */ -moz-outline-radius: 0px !important; /* радиус */ overflow: hidden !important; outline-offset: -2px !important; padding: 3px !important; } tooltip description:not([style]) { color: inherit !important; } tooltip .text-link { color: rgb(69, 161, 255) !important; }
Отсутствует
Создать числовой параметр ui.systemUsesDarkTheme = 1
Сработало только для "Дополнения". Спасибо.
Ещё прозрачность выпадающего списка - V2 для firefox 71+ и часть кода после комментария /* Прозрачность */
Очень спасибо.
Пробовал недавно в виде эксперимента этот стиль с добавлением menupopup, получилось вроде неплохо.
Не понял где сам стиль. Прошу подробней (что/куда).
Отсутствует
Сработало только для "Дополнения". Спасибо.
Должно сработать на всех служебных страницах. Или не там нужно?
Не понял где сам стиль.
Ну в моём сообщении выше, под первым спойлером.
Отсутствует
Vitaliy V.Подскажите, какой префикс для окна инструментов браузера?
Хотя, это же отдельное окно.
Как контекстное меню настроить в инструментах браузера?
Отредактировано _zt (26-09-2020 10:14:03)
Отсутствует
Должно сработать на всех служебных страницах.
Сработало на чистом профиле. Видать что-то из Aris-t2 3.1.7 мешает...
Ну в моём сообщении выше, под первым спойлером.
tooltip description:not([style]) {
color: inherit !important;
}
tooltip .text-link {
color: rgb(69, 161, 255) !important;
}
Прошу подробней (что/куда).
Отсутствует
Прошу подробней (что/куда)
В userChrome.css. Если не сработало, то не знаю что мешает, вот на чистом профиле в userChrome.css:
Отредактировано sandro79 (26-09-2020 12:06:55)
Отсутствует
Подскажите, какой префикс для окна инструментов браузера?
Хотя, это же отдельное окно.
Окно и что? Это окно с отдельным профилем и процессом
@-moz-document url-prefix("chrome://devtools/content/")
Как контекстное меню настроить в инструментах браузера?
В профиле для удаленного отладчика, папка chrome_debugger_profile,
как и в основном создаете папку chrome и т.д., даже можно туда добавить user_chrome_files (кстати обновил вчера)
В инструментах браузера кликните по какой-нибудь ссылке (например кнопка меню в виде многоточия, пункт документация) откроется окно браузера (с профилем chrome_debugger_profile)
Отредактировано Vitaliy V. (26-09-2020 13:24:16)
Отсутствует
В профиле для удаленного отладчика, папка chrome_debugger_profile,
как и в основном создаете папку chrome и т.д.,даже можно туда добавить user_chrome_files (кстати обновил вчера)
Спасибо!!!
Add, другое дело:
Отредактировано kokoss (26-09-2020 23:20:34)
Win7
Отсутствует