razoo
Если используете Custom Buttons здесь или здесь подробнее.
Отсутствует
xrun1
Спасибо, дельный совет. Но, при всём уважении к CB (использовал на c 3 по 52), пока воздержусь их прикручивать. На альтернативном профиле предложенную вами кнопку попробовал: это фактически реплика опции почившей TM+. Мощно, но многовато функций. )
Мне нужно максимально просто: клик > список.
Отсутствует
Как сделать, чтобы new-tab-button был всегда прижат в крайнее правое положение
А воткнуть между вкладками и new-tab-button в Персонализация... --> Растягивающийся интервал?
Отсутствует
Растягивающийся интервал?
У меня эту кнопку сейчас просто спейсинг подпирает с минусовым отступом
Это он и есть, а обратный отступ, чтобы минимизировать пространство недоступное для двойного клика, т.к. на special-spring не работает pointer-events: none. Привык вызывать таб даблкликом по таббару. Ради него вся канитель.
Отсутствует
Sidebar Tabs (бывший SidebarModoki, теперь полностью переписанный)
78 +
/** Подключение: CustomStylesScripts.jsm: scriptschrome: load: { path: "ucf_SidebarTabs.js", ucfobj: true, }, */ var sidebar_tabs = { // -- Настройки Sidebar Tabs --> ST_RIGHT: false, // Расположение панели ST_WIDTH: 260, ST_AUTOHIDE: true, // Скрывать в полноэкранном режиме ST_NAME: "Sidebar Tabs", CLOSE_BTN_TOOLTIP: "Закрыть панель", ST_HIDE_HEADER: false, TAB_SRC_0: "chrome://browser/content/places/bookmarksSidebar.xhtml", TAB_LABEL_0: "Закладки", TAB_SRC_1: "chrome://browser/content/places/historySidebar.xhtml", TAB_LABEL_1: "История", TAB_SRC_2: "chrome://browser/content/downloads/contentAreaDownloadsView.xhtml", TAB_LABEL_2: "Загрузки", KEY: "KeyB_true_true_false", // Сочетание клавиш для для переключения Sidebar Tabs - code ctrlKey altKey shiftKey // <-- Настройки Sidebar Tabs -- last_open: "extensions.ucf.sidebar_tabs.last_open", last_index: "extensions.ucf.sidebar_tabs.last_index", toolbox_width: "extensions.ucf.sidebar_tabs.toolbox_width", toolbox: null, button: null, get prefs() { delete this.prefs; return this.prefs = Services.prefs; }, init(that) { var docElm = document.documentElement, sidebar; if (docElm.matches("[chromehidden~='extrachrome']") || !(sidebar = document.querySelector("#sidebar-box"))) return; var style = "data:text/css;charset=utf-8," + encodeURIComponent(` #st_toolbox { background-color: var(--toolbar-bgcolor, -moz-Dialog) !important; color: var(--toolbar-color, -moz-DialogText) !important; text-shadow: inherit !important; -moz-box-ordinal-group: ${this.ST_RIGHT ? "101" : "0"} !important; } #st_toolbox :is(tabs,tabpanels,tab) { -moz-appearance: none !important; appearance: none !important; background-color: transparent !important; color: inherit !important; margin: 0 !important; padding: 0 !important; border: none !important; } #st_splitter { -moz-appearance: none !important; appearance: none !important; padding-inline: 4px !important; min-width: 9px !important; margin-inline: -4px !important; position: relative !important; z-index: 2 !important; -moz-box-ordinal-group: ${this.ST_RIGHT ? "100" : "0"} !important; -moz-box-orient: vertical !important; border: none !important; background: none !important; } #st_splitter::after { content: ""; display: inline-block; -moz-box-flex: 1; width: 1px; border-left: 1px solid var(--chrome-content-separator-color, rgba(127,127,137,.5)) !important; } #st_toolbox tab { margin-top: 2px !important; padding: 3px 6px !important; outline: none !important; border-bottom: 2px solid transparent !important; } #st_toolbox tab:hover { border-bottom-color: rgba(127,127,127,.3) !important; } #st_toolbox tab[visuallyselected="true"] { border-bottom-color: #0074E8 !important; } #ucf-additional-vertical-container[v_vertical_bar_start="true"], #browser-border-start { -moz-box-ordinal-group: 0 !important; } #ucf-additional-vertical-container[v_vertical_bar_start="false"], #browser-border-end { -moz-box-ordinal-group: 102 !important; } ${this.ST_AUTOHIDE ? ":root[inFullscreen] :is(#st_toolbox,#st_splitter)," : ""} :root[inDOMFullscreen] :is(#st_toolbox,#st_splitter), :root[chromehidden~="extrachrome"] :is(#st_toolbox,#st_splitter) { visibility: collapse !important; } ${this.ST_HIDE_HEADER ? `#st_header { display: none !important; }` : ""} `); try { windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); } catch (e) {} docElm.setAttribute("sidebar_tabs_right", `${this.ST_RIGHT}`); var template = document.importNode(MozXULElement.parseXULToFragment(` <vbox id="st_toolbox" class="chromeclass-extrachrome"> <hbox id="st_header" align="center"> <label>${this.ST_NAME}</label> <spacer flex="1000"/> <toolbarbutton id="st_close_button" class="close-icon tabbable" tooltiptext="${this.CLOSE_BTN_TOOLTIP}"/> </hbox> <tabbox id="st_tabbox" flex="1"> <tabs id="sbar_tabs"> <tab id="st_tab0" label="${this.TAB_LABEL_0}"/> <tab id="st_tab1" label="${this.TAB_LABEL_1}"/> <tab id="st_tab2" label="${this.TAB_LABEL_2}"/> </tabs> <tabpanels id="st_tabpanels" flex="1"> <vbox id="st_tab_container_0" flex="1"> <browser id="st_browser_0" flex="1" autoscroll="false"/> </vbox> <vbox id="st_tab_container_1" flex="1"> <browser id="st_browser_1" flex="1" autoscroll="false"/> </vbox> <vbox id="st_tab_container_2" flex="1"> <browser id="st_browser_2" flex="1" autoscroll="false"/> </vbox> </tabpanels> </tabbox> </vbox> <splitter id="st_splitter" class="chromeclass-extrachrome"></splitter> `), true); sidebar.before(template); this.toolbox = document.querySelector("#st_toolbox"); this.splitter = document.querySelector("#st_splitter"); this.st_browser_0 = this.toolbox.querySelector("#st_browser_0"); this.st_browser_1 = this.toolbox.querySelector("#st_browser_1"); this.st_browser_2 = this.toolbox.querySelector("#st_browser_2"); this.st_tabpanels = this.toolbox.querySelector("#st_tabpanels"); this.st_tabbox = this.toolbox.querySelector("#st_tabbox"); this.st_close_btn = this.toolbox.querySelector("#st_close_button"); this.st_tabbox.selectedIndex = this.aIndex = this.prefs.getIntPref(this.last_index, 0); this._open = this.prefs.getBoolPref(this.last_open, true); this.st_tabbox.handleEvent = function handleEvent() {}; this.toggle(true); window.addEventListener("keydown", this); this.st_close_btn.addEventListener("command", this); that.unloadlisteners?.push("sidebar_tabs"); }, select(e, aIndex) { if (e.target != this.st_tabpanels || (aIndex = this.st_tabpanels.selectedIndex) == this.aIndex) return; this[`st_browser_${this.aIndex}`].setAttribute("src", "about:blank"); this.aIndex = aIndex; this.prefs.setIntPref(this.last_index, aIndex); this.toolbox.width = this.prefs.getIntPref(`${this.toolbox_width}${aIndex}`, this.ST_WIDTH); this[`st_browser_${aIndex}`].setAttribute("src", this[`TAB_SRC_${aIndex}`]); }, toggle(force) { var tog = !force ? !this._open : this._open; if (tog) { if (this.button = CustomizableUI.getWidget("sidebar_tabs_button")?.forWindow(window).node) { this.button.checked = true; if (!this.button.sidebar_tabs_toggle) this.button.sidebar_tabs_toggle = () => { this.toggle(); }; } this.toolbox.hidden = false; this.splitter.hidden = false; this.toolbox.width = this.prefs.getIntPref(`${this.toolbox_width}${this.aIndex}`, this.ST_WIDTH); this.prefs.setBoolPref(this.last_open, true); this._open = true; this.st_tabpanels.addEventListener("select", this); this.toolbox.addEventListener("resize", this); this[`st_browser_${this.aIndex}`].setAttribute("src", this[`TAB_SRC_${this.aIndex}`]); } else this.close(); }, close() { this.st_tabpanels.removeEventListener("select", this); this.toolbox.removeEventListener("resize", this); if (this.button = CustomizableUI.getWidget("sidebar_tabs_button")?.forWindow(window).node) { this.button.checked = false; if (!this.button.sidebar_tabs_toggle) this.button.sidebar_tabs_toggle = () => { this.toggle(); }; } this.toolbox.hidden = true; this.splitter.hidden = true; this.prefs.setBoolPref(this.last_open, false); this._open = false; this.st_browser_0.setAttribute("src", "about:blank"); this.st_browser_1.setAttribute("src", "about:blank"); this.st_browser_2.setAttribute("src", "about:blank"); }, resize() { this.prefs.setIntPref(`${this.toolbox_width}${this.aIndex}`, this.toolbox.getBoundingClientRect().width); }, keydown(e) { if (this.KEY === `${e.code}_${e.ctrlKey}_${e.altKey}_${e.shiftKey}`) this.toggle(); }, command() { this.close(); }, handleEvent(e) { this[e.type](e); }, destructor() { window.removeEventListener("keydown", this); this.st_close_btn.removeEventListener("command", this); this.st_tabpanels.removeEventListener("select", this); this.toolbox.removeEventListener("resize", this); }, }; sidebar_tabs.init(this);
кнопка (необязательно) для него в custom_script.js
try { CustomizableUI.createWidget({ id: "sidebar_tabs_button", label: "Sidebar Tabs", tooltiptext: "Открыть / Закрыть Sidebar Tabs", defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onCreated(btn) { btn.style.setProperty("list-style-image", `url("data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' fill='context-fill rgb(142, 142, 152)'> <path d='M2 2C.892 2 0 2.89 0 4v9.1a2 2 0 0 0 2 2h12c1.1 0 2-.9 2-2V4a2 2 0 0 0-2-2Zm0 1h12c.6 0 1 .45 1 1v9.1c0 .5-.5.9-1 .9H1.99c-.55 0-.99-.4-.99-.9V4c0-.55.45-1 1-1Z'/> <rect width='14' height='1' x='1' y='6'/> <rect width='1' height='7' x='5' y='7'/> </svg>")`); }, onCommand(e) { e.target.sidebar_tabs_toggle(); } }); } catch(e) {}
new-tab-button был всегда прижат в крайнее правое положение
так и есть если не путать #tabs-newtab-button
#tabs-newtab-button { display: none !important; } #new-tab-button { display: -moz-box !important; }
Отредактировано Vitaliy V. (16-10-2021 12:00:16)
Отсутствует
Vitaliy V.
Отлично Спасибо огромное.
А отдельную кнопку, открывающую его поверх страницы, никак не сделать? С автоскрытием после действия.
Хотелось бы иметь такую возможность, не теряя возможность открывать его рядом со страницей без автоскрытия.
Или ЛКМ/ПКМ на существующей кнопке.
Отсутствует
Или ЛКМ/ПКМ на существующей кнопке.
try {(() => { var label = "Sidebar Tabs", tooltiptext = "ЛКМ: Открыть / Закрыть Sidebar Tabs\nShift+ЛКМ: AutoHide Sidebar Tabs Откл/Вкл", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16'><g><rect x='0' y='0' width='16' height='16' rx='1' ry='1' style='fill:rgb(0, 120, 173);'/><path style='fill:white;' d='M 3.62,1 H 12.4 C 13.8,1 15,2.35 15,4 V 12 C 15,13.7 13.8,15 12.4,15 H 3.62 C 2.18,15 1,13.7 1,12 V 4 C 1.01,2.35 2.18,1.01 3.62,1 Z M 13.2,12 V 4 C 13.2,3.44 12.9,3 12.4,3 H 8 V 13 H 12.4 C 12.9,13 13.2,12.5 13.2,12 Z M 2.75,12 C 2.75,12.5 3.14,13 3.62,13 H 7.12 V 3 H 3.62 C 3.14,3 2.75,3.44 2.75,4 Z' /><path style='fill:white;' d='M 4.33,5 H 5.67 C 5.85,5 6,4.78 6,4.5 6,4.22 5.85,4 5.67,4 H 4.33 C 4.15,4 4,4.22 4,4.5 4,4.78 4.15,5 4.33,5 Z M 4.33,7 H 5.67 C 5.85,7 6,6.77 6,6.5 6,6.23 5.85,6 5.67,6 H 4.33 C 4.15,6 4,6.23 4,6.5 4,6.77 4.15,7 4.33,7 Z M 5,9 H 5.67 C 5.85,9 6,8.78 6,8.5 6,8.23 5.85,8 5.67,8 H 5 C 4.82,8 4.67,8.23 4.67,8.5 4.67,8.78 4.82,9 5,9 Z' /></g></svg>", pref = "extensions.ucf.sidebar_tabs.auto_hide"; var sidebar_tabs_button = { get style() { delete this.style; return this.style = "data:text/css;charset=utf-8," + encodeURIComponent(` #st_toolbox { --v-sidebar-min-width: 2px; --v-sidebar-min-width-normal: 5px; --v-sidebar-max-width: 30em; --v-sidebar-transition-delay-show: .3s; --v-sidebar-transition-delay-hide: .6s; --v-sidebar-transition-duration: .3s; /* ********************************************** */ position: relative !important; z-index: 1 !important; min-width: var(--v-sidebar-max-width) !important; width: var(--v-sidebar-max-width) !important; max-width: var(--v-sidebar-max-width) !important; overflow: hidden !important; opacity: 0 !important; --v-sidebar-margin-max-width: calc(-1 * var(--v-sidebar-max-width)); --v-sidebar-margin-left-locale-dir: 0; --v-sidebar-margin-right-locale-dir: var(--v-sidebar-margin-max-width); --v-sidebar-transform-locale-dir: -1; --v-sidebar-transform-locale-dir-visible: 1; margin-left: var(--v-sidebar-margin-left-locale-dir) !important; margin-right: var(--v-sidebar-margin-right-locale-dir) !important; transform: translateX(calc(var(--v-sidebar-transform-locale-dir) * (var(--v-sidebar-max-width) - var(--v-sidebar-min-width)))) !important; transition-timing-function: linear, step-start !important; transition-delay: var(--v-sidebar-transition-delay-hide), calc(var(--v-sidebar-transition-delay-hide) + var(--v-sidebar-transition-duration)) !important; transition-duration: var(--v-sidebar-transition-duration), 0s !important; transition-property: transform, opacity !important; border-inline-end: 1px solid var(--chrome-content-separator-color, rgba(127,127,127,.5)) !important; } *|*:root[sidebar_tabs_right="true"] #st_toolbox { border-inline-start: 1px solid var(--chrome-content-separator-color, rgba(127,127,127,.5)) !important; border-inline-end: none !important; } *|*:root[sidebar_tabs_right="true"] #st_toolbox, #st_toolbox:-moz-locale-dir(rtl) { --v-sidebar-margin-left-locale-dir: var(--v-sidebar-margin-max-width); --v-sidebar-margin-right-locale-dir: 0; --v-sidebar-transform-locale-dir: 1; --v-sidebar-transform-locale-dir-visible: -1; } *|*:root[sidebar_tabs_right="true"] #st_toolbox:-moz-locale-dir(rtl) { --v-sidebar-margin-left-locale-dir: 0; --v-sidebar-margin-right-locale-dir: var(--v-sidebar-margin-max-width); --v-sidebar-transform-locale-dir: -1; --v-sidebar-transform-locale-dir-visible: 1; } *|*:root[sizemode="normal"] #st_toolbox { --v-sidebar-min-width: var(--v-sidebar-min-width-normal) !important; } #st_toolbox:hover, #st_toolbox[sidebardrag] { transform: translateX(0px) !important; opacity: 1 !important; transition-delay: var(--v-sidebar-transition-delay-show) !important; } *|*:root[v_vertical_bar_visible][v_vertical_bar_start="true"][sidebar_tabs_right="false"] #st_toolbox, *|*:root[v_vertical_bar_visible][v_vertical_bar_start="false"][sidebar_tabs_right="true"] #st_toolbox { transform: translateX(calc(var(--v-sidebar-transform-locale-dir-visible) * var(--v-vertical_bar_width, 0px))) !important; opacity: 1 !important; transition-delay: 0s !important; } #browser > #st_splitter { display: none !important; } `); }, loadstyle(win) { try { win.windowUtils.loadSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); } catch (e) {} }, removestyle(win) { try { win.windowUtils.removeSheetUsingURIString(this.style, win.windowUtils.USER_SHEET); } catch (e) {} }, }; CustomizableUI.createWidget({ id: "sidebar_tabs_button", label: label, tooltiptext: tooltiptext, defaultArea: CustomizableUI.AREA_NAVBAR, localized: false, onBeforeCreated(doc) { if (Services.prefs.getBoolPref(pref, true)) sidebar_tabs_button.loadstyle(doc.defaultView); }, onCreated: function(btn) { btn.style.setProperty("list-style-image", `url("${img}")`); }, onCommand: function(e) { if (!e.shiftKey) e.target.sidebar_tabs_toggle(); else { let prf = Services.prefs.getBoolPref(pref, true), loadremove = !prf ? "loadstyle" : "removestyle"; Services.prefs.setBoolPref(pref, !prf); for (let win of CustomizableUI.windows) sidebar_tabs_button[loadremove](win); } } }); })();} catch(e) {}
и обновите ucf_SidebarTabs.js
Отредактировано Vitaliy V. (10-09-2020 01:26:12)
Отсутствует
Vitaliy V.
А для Save-To-Read можете сделать тёмную тему?
Отсутствует
если не путать #tabs-newtab-button
Холмс, но как?!...
Получается, в интерфейсе спрятаны две совершенно одинаковые по виду и функции кнопки, отличающиеся лишь поведением... Прямо "Сокровища Агры" с близнецами.
Vitaliy V.
Ещё одно Глобальное Спасибо.
А что насчет превращения "Recently Closed Tabs" в дропмаркер на тулбаре? Если скажете "невозможно", значит невозможно.
Отсутствует
Vitaliy V.
Спасибо. Так тоже хорошо.
Заметил, что ширина заданная в ucf_SidebarTabs.js не влияет на вкладку закладок, она всегда шире чем другие вкладки, после перезагрузки скрипта.
Отсутствует
voqabuhe
@-moz-document regexp("moz-extension:\/\/.*\/(?:src\/sidebar|src\/popup)\.html") { html { background: #f5f6f7 !important; color: #18191a !important; --v-input-border-color: #cccccc; --v-input-background-color: rgba(255,255,255,0.8); --v-input-background-color-hover: rgba(204,204,204,.35); --v-input-background-color-active: rgba(204,204,204,.5); --v-input-background-color-focus: #ffffff; --v-highlight-background-color: #0074e8; --v-highlight-background-color-hover: #178bff; --v-highlight-background-color-active: #0059e8; --v-highlight-color: #ffffff; --v-scrollbar-color: var(--v-highlight-background-color) #ffffff; font: message-box; margin: 0 !important; } @media (prefers-color-scheme: dark) { html { background: #18181a !important; color: #b1b1b3 !important; --v-input-border-color: #3c3c3d; --v-input-background-color: rgba(0,0,0,0.5); --v-input-background-color-hover: rgba(249,249,250,.1); --v-input-background-color-active: rgba(249,249,250,.15); --v-input-background-color-focus: #000000; --v-scrollbar-color: var(--v-highlight-background-color) #000000; } } body { margin: 0 !important; background: none !important; color: inherit !important; } html, body, .s2r-table-container { scrollbar-width: thin !important; scrollbar-color: var(--v-scrollbar-color) !important; } input[type="search"], select { -moz-appearance: none !important; border: 1px solid var(--v-input-border-color) !important; background-color: var(--v-input-background-color) !important; background-clip: border-box !important; color: inherit !important; padding: 1px 2px !important; height: auto !important; min-height: 22px !important; box-shadow: none !important; border-radius: 0 !important; outline: none !important; font-size: inherit !important; font-family: inherit !important; margin: 0 !important; } select { -moz-appearance: none !important; background: none !important; } input[type="search"]:focus { border-color: var(--v-highlight-background-color) !important; background-color: var(--v-input-background-color-focus) !important; } select:focus { border-color: var(--v-highlight-background-color) !important; } select:hover { border-color: var(--v-input-border-color) !important; background-color: var(--v-input-background-color-hover) !important; } select:hover:active { background-color: var(--v-input-background-color-active) !important; } input[type="search"]::selection { background-color: var(--v-highlight-background-color) !important; color: var(--v-highlight-color) !important; } .s2r-table-container { border-color: var(--v-input-border-color) !important; } .filter-sort { padding: 2px; margin: 0 !important; width: auto !important; } .sort { margin-left: 2px !important; } .cell { min-height: 16px; margin-block: 2px !important; } }
А что насчет превращения "Recently Closed Tabs" в дропмаркер на тулбаре? Если скажете "невозможно", значит невозможно.
Стилем что-ли? конечно невозможно, а если скриптом то я выкладывал уже кнопку https://forum.mozilla-russia.org/viewto … 32#p784332
Заметил, что ширина заданная в ucf_SidebarTabs.js не влияет на вкладку закладок, она всегда шире чем другие вкладки, после перезагрузки скрипта
Ширина заданная в ucf_SidebarTabs.js влияет только на дефолтное состояние когда ещё нет настроек в about:config - extensions.ucf.sidebar_tabs.toolbox_width(0|1|2) для каждого таба. Просто мышкой при перетаскивании за splitter настройте ширину какую надо для каждого таба и она сохранится в about:config, кстати обновил опять ucf_SidebarTabs.js, убрал атрибут collapse у splitter чтобы не сворачивал панель.
А если включен стиль auto hide то ширину надо настраивать в нём.
Отредактировано Vitaliy V. (10-09-2020 13:34:06)
Отсутствует
Добрый день всем.
Если добавить chrome://browser/content/places/places.xhtml в закладки, то Library будет открываться не в новом окне, а в табе. При этом всё работает, кроме создания новой папки. Похоже, что окошко bookmarkProperties просто не вызывается, если журнал открыт во вкладке.
(Из-за невызываемого окошка создание нового букмарка вручную там тоже не работает, но это практически неиспользуемая функция, ибо шорткат унд драг-энд-дроп.)
Если bookmarkProperties.xhtml все же вызывается, но где-то прячется, то можно ли с помощью стиля показать его "на поверхности"? Или это только инжектом скриптов чинится?
Отсутствует
Vitaliy V.
Спасибо большое за обновление Add Toolbar Buttons и добавление кнопки Дополнения. Прикольно что добавили в кнопку возможность управления темами. Вот только хотелось, чтоб меню не закрывалось при каждом переключение темы. И на мой взгляд хорошо бы их отсортировать в низ списка, под дополнениями, чтоб они были все в одном месте и не путались с расширеними.
Отредактировано voqabuhe (17-09-2020 01:45:25)
Отсутствует
обновил 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, почти все добавил, изменил то что спрашивали
Круто, ну очень круто. Просто великолепная кнопка получилась. Темы теперь очень удобно переключать. Спасибо большое!
Отсутствует
egorsemenov06
https://forum.mozilla-russia.org/viewto … 07#p785107
Отредактировано Vitaliy V. (15-12-2021 15:03:02)
Отсутствует
так у меня не заработали сочетания Ctrl+ЛКМ и Shift+ЛКМ
Проверил ещё раз, всё работает,
только заменил #appMenu-viewCache на template#appMenu-viewCache чтобы в 74 - 79 тоже работало.
Отредактировано Vitaliy V. (22-09-2020 12:28:58)
Отсутствует
только заменил #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
про классическое меню ничего не сказано но добавил и туда на всякий случай
(async ( id = Symbol("menusrestartitems"), btnID = "ucf-appmenu-restart-button", muimID = "ucf_menu_FileRestartItem", ) => (this[id] = { init() { var abtn = document.querySelector("template#appMenu-viewCache")?.content.querySelector("#appMenu-quit-button2"); if (abtn) { let frag = MozXULElement.parseXULToFragment(`<toolbarbutton/>`); let btn = this.btn = frag.firstElementChild; btn.id = btnID; btn.className = "subviewbutton"; btn.setAttribute("label", "Перезапуск"); btn.setAttribute("tooltiptext", "ЛКМ: Перезапустить приложение\nСКМ: Перезапустить без дополнений\nПКМ: Перезапустить и заново создать кэш быстрого запуска"); btn.setAttribute("shortcut", "Ctrl+Alt+Q"); btn.addEventListener("click", this); abtn.before(frag); } var aftermuim = document.querySelector("#menu_FilePopup #menu_FileQuitItem"); if (aftermuim) { let muim = this.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.addEventListener("click", this); aftermuim.before(muim); } var style = "data:text/css;charset=utf-8," + encodeURIComponent(` #${btnID}, #${muimID} { list-style-image: url("chrome://global/skin/icons/reload.svg") !important; -moz-context-properties: fill; fill: color-mix(in srgb, currentColor 20%, #f38525) !important; } `); try { windowUtils.loadSheetUsingURIString(style, windowUtils.USER_SHEET); } catch (e) {} window.addEventListener("keydown", this); setUnloadMap(id, this.destructor, this); }, click(e) { switch (e.button) { case 0: this._restart_mozilla(); break; case 1: e.view.safeModeRestart(); break; case 2: this._restart_mozilla(true); break; } }, keydown(e) { if (e.code == "KeyQ" && e.ctrlKey && e.altKey) this._restart_mozilla(); }, _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 {startup} = Services; startup.quit(startup.eAttemptQuit | startup.eRestart); }, handleEvent(e) { this[e.type](e); }, destructor() { window.removeEventListener("keydown", this); this.btn?.removeEventListener("click", this); this.muim?.removeEventListener("click", this); }, }).init())();
Отредактировано Vitaliy V. (Сегодня 18:07:53)
Отсутствует
sandro79
про классическое меню ничего не сказано но добавил и туда на всякий случай
Да-да, там тоже лишним не будет. Огромное Вам Спасибо, подключил, всё отлично работает
Отсутствует