Но мне никогда и не казалось, что это может быть хоть сколько-нибудь как-то верно подсчитано.
Может возврат на старый код красные строки Bug 1665318 даст более правдоподобный результат, но не хочу усложнять.
Сделал в ucf_hookClicks.js при mouseenter на кнопку "Расширения" вывод в статус "Занято ОЗУ примерно ~(результат/делённый на 1.2)".
Отсутствует
Здравствуйте,
добавил панель Sidebar tabs https://forum.mozilla-russia.org/viewtopic.php?pid=784824#p784824
появилось пара вопросов
не как не могу понять как правильно добавить кнопку для панели - скрывать/показывать
кнопку добавляю в custom_script_win.js (как в инструкции в custom_script.js не работает) - кнопка появляется - но не работает - нажатие на нее нечего не дает
если скрыть панель крестиком на самой панели - то доставать её обратно не понятно как... кроме как сделать новый профиль
подскажите - как правильно кнопку добавить чтоб работала?
и можно ли в эту панель "Sidebar tabs" добавить вкладки?? или по аналогии с chrome браузерами - в этой панели открывать сайта - чтобы в 1м окне сразу 2 сайта смотреть? (родная панель сейчас занята tree style tabs)
Отсутствует
gg.user
Пользуюсь кнопкой и Sidebar tabs, чтобы посмотреть загрузки (ПКМ на стандартной кнопке, открывает Sidebar tabs на соответствующей вкладке). Может, пригодится. Кнопка здесь под спойлером.
Отсутствует
gg.user
Пользуюсь кнопкой и Sidebar tabs, чтобы посмотреть загрузки (ПКМ на стандартной кнопке, открывает Sidebar tabs на соответствующей вкладке). Может, пригодится. Кнопка здесь под спойлером.
пойдет) работает!) так тоже сойдет - спасибо!!
Отсутствует
Вопрос: как открыть сайт в Sidebar из скрипта ?
в документации и расширении open-link-in-sidebar это работает, но из скрипта нет.
Это API только для расширений. Но как это в скрипте сделать ?
Подключал панель Sidebar tabs от Vitaliy V., но открыть в ней сайт не получилось.
// в scriptschrome: и scriptsbackground: не работает. через DOM Inspector глянуть не могу, он опять «вылетает» browser.sidebarAction.setPanel({ panel: 'about:blank' }); browser.sidebarAction.setPanel({ panel: 'https://meteo7.ru' });
Отредактировано Dobrov (07-06-2024 01:02:56)
Отсутствует
если скрыть панель крестиком на самой панели - то доставать её обратно не понятно как... кроме как сделать новый профиль
Кроме кнопки есть настраиваемые Сочетания клавиш, по умолчанию это Ctrl + Alt + B
в этой панели открывать сайта - чтобы в 1м окне сразу 2 сайта смотреть?
Подключал панель Sidebar tabs от Vitaliy V., но открыть в ней сайт не получилось.
Тестируйте, подключать в scriptschrome.domload , кнопка уже встроена в данный скрипт
https://github.com/VitaliyVstyle/Vitali … ar_tabs.js
Отредактировано Vitaliy V. (13-06-2024 13:36:10)
Отсутствует
Vitaliy V. превосходно! Хорошая замена для Open in Sidebar и Tile Tabs !
если Sidebar закрыт, контекст-меню «Открыть ссылку» даёт ошибку: sender.tab is undefined
Просьба «прижать» имена вкладок влево, они скачут по сторонам на разной ширине Sidebar при смене вкладок. (у меня не получилось)
Вопрос: как из другого кода открыть сайт в твоей Sidebar ?
надо по RMouse на identity-icon-box открыть адрес в Sidebar, т.к. в ucf_hookClicks проще назначать клики.
Отредактировано Dobrov (08-06-2024 04:37:58)
Отсутствует
Просьба «прижать» имена вкладок влево, они скачут по сторонам на разной ширине Sidebar при смене вкладок
У меня не было такого на
, не знаю может на
и так, обновил проверь помогло или нет.
Вопрос: как из другого кода открыть сайт в твоей Sidebar ?
Нужно знать индекс вкладки в которой открывать, например так
ucf_custom_script_win.ucf_sidebar_tabs.setPanel(4, "https://forum.mozilla-russia.org");
или индекс можно поискать в menus если есть один или более пункта меню
ucf_custom_script_win.ucf_sidebar_tabs.menus[0].aIndex
Отсутствует
Vitaliy V. после удаления .jsm этот скрипт отвалиться?просьба переделайте его пожалуйста для .mjs
//Кнопка пауза в загрузках...................... (async ({DownloadsViewUI}) => { var origfunc = DownloadsViewUI.DownloadElementShell.prototype.connect; DownloadsViewUI.DownloadElementShell.prototype.connect = function connect() { var _origfunc = origfunc.apply(this, arguments); if (!this.element || !this._downloadButton) return _origfunc; var doc = this.element.ownerDocument; var button = doc.createXULElement("button"); button.setAttribute("class", "downloadButton downloadPauseResumeButton"); if (this.isPanel) button.addEventListener("mouseover", e => { e.preventDefault(); e.stopPropagation(); }, true); else button.setAttribute("tooltiptext", "Пауза/Продолжить"); button.addEventListener("command", e => { if (!this.element._shell?.isCommandEnabled("downloadsCmd_pauseResume")) return; e.preventDefault(); e.stopPropagation(); this.element._shell.doCommand("downloadsCmd_pauseResume"); }); this._downloadButton.before(button); return _origfunc; }; })(ChromeUtils.import("resource:///modules/DownloadsViewUI.jsm"));
@-moz-document url-prefix("chrome:"), url("about:downloads") { richlistbox > richlistitem.download-state[state="0"] > .downloadPauseResumeButton { list-style-image: url("../svg/download-pause.svg") !important; } richlistbox > richlistitem.download-state[state="4"] > .downloadPauseResumeButton { list-style-image: url("../svg/download-resume.svg") !important; } richlistbox > richlistitem.download-state[buttonhidden] .downloadPauseResumeButton, richlistbox > richlistitem.download-state:not(:is([state="0"],[state="4"])) .downloadPauseResumeButton { display: none !important; } }
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" fill="context-fill black"> <path d="M 5,13.5 V 2.5 C 5,1.8 4,1.8 4,2.5 V 13.5 C 4,14.2 5,14.2 5,13.5 Z M 12,13.5 V 2.5 C 12,1.8 11,1.8 11,2.5 V 13.5 C 11,14.2 12,14.2 12,13.5 Z"/> </svg>
<?xml version="1.0" encoding="UTF-8"?> <svg xmlns="http://www.w3.org/2000/svg" height="16" width="16" fill="context-fill black"> <path d="M 4,13 12,8.02 4,3 Z M 3,13 V 3 A 1,1 0 0 1 4.53,2.15 L 12.5,7.17 A 1,1 0 0 1 12.5,8.88 L 4.53,13.8 A 1,1 0 0 1 3,13 Z" fill-rule="evenodd"/> </svg>
Отсутствует
setUnloadMap(ID, () => this.destructor());
Разве метод setUnloadMap() не разработан, чтобы писать так:
setUnloadMap(ID, this.destructor, this); а не создавать ненужную функцию.
Тестируйте
Что-то у меня наблюдается какой-то слегка неожиданный outline
на Sidebar Tabs'ских табах в tab > hbox.tab-middle
Воспроизводится при запуске браузера с ранее открытым Sidebar Tabs.
Щёлкаешь по другому табу, и такая вот картина:
data:image/png;base64,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
Просто, в таком случае, ссылка должна бы открыться в том же контейнере,
но этого не будет.
А такое, возможно, представляет некую чувствительность для тех,
кто пользуется контейнерной фичей.
Или, наоборот — чётко заявить в описании:
«Ссылка из контейнера откроется вне контейнера, вас предупредили.»
И ничего тогда не делать.
Отсутствует
Vitaliy V.
Спасибо за новый Sidebar Tabs! Вот во что это вылилось, а вы когда то делать его не хотели.
Очень навязчивый пункт контекстного меню, сделайте его пожалуйста только для контекста страницы и контекста ссылок.
Добавлено 08-06-2024 22:02:49
Dumby
#st_toolbox tab[selected="true"] { --default-focusring: 0px solid !important; border-bottom-color: color-mix(in srgb, currentColor 80%, transparent) !important; }
Отредактировано _zt (08-06-2024 22:03:05)
Отсутствует
Vitaliy V.
Сделайте пожалуйста новый код для открытия вкладки загрузок по ПКМ на стандартной кнопке загрузок. Вот старый код
Отсутствует
У меня не было такого на
![]()
, не знаю может на
и так, обновил проверь помогло или нет.
1) как вызвать ucf_custom_script_win.ucf_sidebar_tabs… из scriptsbackground: ? (из твоего скрипта ЮзерМеню)
2) лучше прижать id="sbar_tabs" влево, иначе на разной ширине SideBar при выборе вкладок "sbar_tabs" прыгает влево/вправо и смещаются заголовки.
Отредактировано Dobrov (09-06-2024 05:57:18)
Отсутствует
egorsemenov06
пока так пробуйте
// })(ChromeUtils.import("resource:///modules/DownloadsViewUI.jsm"));
})(ChromeUtils.importESModule("resource:///modules/DownloadsViewUI.sys.mjs"));
Разве метод setUnloadMap() не разработан, чтобы писать так:
setUnloadMap(ID, this.destructor, this); а не создавать ненужную функцию.
Да но работает и так без контекста, а так да фунций внутри фунций лучше меньше
Просто, в таком случае, ссылка должна бы открыться в том же контейнере,
но этого не будет.
Хорошо что напомнил про контейнеры, вроде как сделал чтобы открывалось в том же контейнере, посмотри можно ли сделать без browser.remove();
Сделайте пожалуйста новый код для открытия вкладки загрузок по ПКМ на стандартной кнопке загрузок.
// var st = window.ucf_custom_script_win?.sidebar_tabs || window.ucf_custom_script_all_win?.sidebar_tabs;
var st = window.ucf_custom_script_win?.ucf_sidebar_tabs;
как вызвать ucf_custom_script_win.ucf_sidebar_tabs… из scriptsbackground:
Ну как, добавляешь вначале объект window текущего окна
он может быть получен из event клика по кнопке или пункту меню
var win = e.view;
win.ucf_custom_script_win.ucf_sidebar_tabs…
лучше прижать id="sbar_tabs" влево, иначе на разной ширине SideBar при выборе вкладок "sbar_tabs" прыгает влево/вправо и смещаются заголовки.
Так они и прижаты влево что в что в
добавил такой код для левого spacer, пробуй
#st_toolbox tabs > spacer:first-of-type {
display: none !important;
}
Отсутствует
egorsemenov06
пока так пробуйте
// })(ChromeUtils.import("resource:///modules/DownloadsViewUI.jsm"));
})(ChromeUtils.importESModule("resource:///modules/DownloadsViewUI.sys.mjs"));
Спасибо!!!!Работает.
Отсутствует
посмотри можно ли сделать без browser.remove();
В смысле без использования именно этого метода?
Тогда да, browser.replaceWith() прямо напрашивается.
А если в смысле вообще без удаления, то тогда, наверно, нет.
Вот, попробовал так
/* browser.destroy(); let container = this[`st_container_${aIndex}`] ||= browser.parentElement; browser.remove(); browser = this[`st_browser_${aIndex}`] = (this[`cn_browser_${aIndex}`] ||= this.fragment.querySelector(`#st_browser_${aIndex}`)).cloneNode(false); if ("userContextId" in options) browser.setAttribute("usercontextid", options.userContextId); container.append(browser); */ // Just test var d = browser.destroy; if (d.name != "brd") browser.destroy = function brd() { d.call(browser); console.log("BROWSER DESTROY!"); } var id = options.userContextId; id ? browser.setAttribute("usercontextid", id) : browser.removeAttribute("usercontextid"); browser.replaceWith(browser);
Первый раз — при манипуляции с атрибутом "usercontextid".
Второй раз — при пере-подвешивании браузера на DOM-дерево.
Проверяю, запуская с консоли
st_browser_4.browsingContext.originAttributes.userContextId
Вроде, показывает то, что должно быть.
А без пере-подвешивания браузера на DOM-дерево, атрибут-то есть,
но с проверочной строки консоль далеко не всегда показывает то, что надо.
Отсутствует
Vitaliy V. - спасибо! Все заработало в scriptsbackground: и заголовки вкладок не смещаются.
Помогите сделать глобальную функцию для кода в receiveMessage()
Опять у меня та же проблема, не работает через globalThis[Symbol.for(……) для ucb_SaveHTML.mjs)
/* SingleHtml вызов: Cu.getGlobalForObject(Cu)[Symbol.for("UcfGlob")].SingleHTML(1) */ var self, name = "SingleHTML", EXPORTED_SYMBOLS = [`${name}Child`], {io, focus, obs, prefs, dirsvc} = Services; export class SingleHTMLChild extends JSWindowActorChild { //класс = name + Child receiveMessage() {return htmlAndName(this.contentWindow);} } ChromeUtils.domProcessChild.childID || ({ init(topic) { ………… globalThis[Symbol.for('UcfGlob')] = this.UcfGlob; //общие функции }, ………… UcfGlob: { ………… } }).init("browser-delayed-startup-finished"); var htmlAndName = async mainWin => { здесь нужен вызов функции из UcfGlob ………… }
Отсутствует
А если в смысле вообще без удаления, то тогда, наверно, нет.
Да это и имел ввиду про replaceWith что то и забыл, спасибо заменил.
Тестовый кусок внутри этого кода показывает,
что browser.destroy() вызывается дважды.
Да проверил ещё browser.construct() он не вызывается значит и destroy() не нужно принудительно вызывать,
сделал теперь destroy() один раз вызывается.
Добавлено 10-06-2024 12:10:14
Dobrov
Зымысел то какой, чтобы получить contentWindow ? Думаю это плохая идея...
Очень навязчивый пункт контекстного меню, сделайте его пожалуйста только для контекста страницы и контекста ссылок.
Не совсем так, но теперь должно быть менее навязчивым.
Отредактировано Vitaliy V. (10-06-2024 13:03:54)
Отсутствует
Зымысел то какой, чтобы получить contentWindow ? Думаю это плохая идея...
Я уже решил задачу другим способом. Хотел получить URL вкладки, учитывая ReaderMode и расширения.
Общие функции из ucb_SaveHTML.mjs вызываю из двух скриптов - так проще и экономия кода.
ещё в Sidebar Tabs не обозначено действие по клику колёсиком. Может так добавить:
mitem.setAttribute("label", label); вставить после этой строки:
mitem.tooltipText = "Колёсико откроет ссылку из буфера обмена";
Отредактировано Dobrov (10-06-2024 17:03:31)
Отсутствует
Не совсем так, но теперь должно быть менее навязчивым.
Уже лучше, но... щелкаешь по изображению >> "Открыть в SidebarTabs", ожидается открытие изображения, а открывается страница.
И слово "ссылку" у вас лишнее, ведь пункт и страницу открывает.
Мне кажется тут надо либо изображения к открытию добавить, либо использовать контексты, как вы это делали для старой версии скрипта OpenWith... и почему то не сделали в новой.
Как заставить расширения работать в сайдбаре, например Dark Reader?
Отсутствует
Получить текущий URL
Что такое текущий URL, фрейма? На текущей странице может быть много фреймов,
если нужно получить URL документа верхнего уровня зачем искать его в JSWindowActorChild,
так что я пас не ясна задача.
щелкаешь по изображению >> "Открыть в SidebarTabs", ожидается открытие изображения, а открывается страница
О нет, если так сделать то например на этой же странице не найти свободного места, везде изображения открываются.
И слово "ссылку" у вас лишнее
Да это же настройки юзера запишите как надо. Там можно вообще удалять или добавлять нужные вкладки если не поняли.
Как заставить расширения работать в сайдбаре, например Dark Reader?
В оригинальном сайдбаре не работает почему в моем должно, это ж api расширений нужно подключать, а вкладки где взять их нет для сайдбара
Отредактировано Vitaliy V. (10-06-2024 18:32:07)
Отсутствует
О нет
А было бы прикольно, картинки там открывать.
Ну так просто исключения сделайте, я не знаю как. Вот код из старого OpenWith
... funcpopupshowing = () => { var link = gContextMenu.onLink || gContextMenu.onMailtoLink; for(let arr of this._eventlisteners) { if (arr[2].name === "page") // Исходно //arr[0].hidden = link; // др. селекторы - gContextMenu(.onImage, .onCanvas, .onVideo, .onAudio) arr[0].hidden = link || gContextMenu.onTextInput || gContextMenu.isContentSelected; else if (arr[2].name === "link") arr[0].hidden = !link || gContextMenu.onTextInput; } }; funcpopuphiding = () => { for(let arr of this._eventlisteners) { if (arr[1] === "command") arr[0].hidden = true; } };
Отредактировано _zt (10-06-2024 20:15:00)
Отсутствует
Dumby посмотрите пожалуйста кнопку
//Дополнения.................................. (async () => CustomizableUI.createWidget({ label: "Дополнения", id: "ucf-cbbtn-ToggleRestartlessAddons", localized: false, get initCode() { this.event = Object.create(null); delete this.initCode; return this.initCode = Cu.readUTF8URI(Services.io.newURI( "chrome://user_chrome_files/content/custom_scripts/custom_script/ucf-cbbtn-ToggleRestartlessAddons.js" )); }, get icon() { var icon = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><path style='fill:none;stroke:context-fill rgb(39, 174, 129);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M12.9 15.3H3.2c-.88 0-1.6-.6-1.6-1.4v-2.7c0-.4.33-.6.74-.6h1.72c.7 0 1.25-.64 1.25-1.2 0-.64-.55-1.15-1.25-1.15H2.34c-.41 0-.74-.32-.74-.68V5.84c0-.81.72-1.48 1.6-1.48h2.36V3.13c0-1.21.93-2.297 2.21-2.419C9.23.57 10.5 1.62 10.5 2.98v1.38h2.4c.9 0 1.5.67 1.5 1.48v8.06c0 .8-.6 1.4-1.5 1.4z'/></svg>"; var subst = this.id.toLowerCase() + "-icon"; Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(subst, Services.io.newURI(icon)); delete this.icon; return this.icon = "resource://" + subst; }, onCreated(btn) { btn.setAttribute("image", this.icon); new btn.ownerGlobal.Function("self,event,_phase", this.initCode) .call(btn, btn, this.event, "init"); } }))();
// http://infocatcher.ucoz.net/js/cb/toggleRestartlessAddons.js // https://forum.mozilla-russia.org/viewtopic.php?id=57948 // https://github.com/Infocatcher/Custom_Buttons/tree/master/Toggle_Restartless_Add-ons // Toggle Restartless Add-ons button for Custom Buttons // (code for "initialization" section) // Also the code can be used from main window context (as Mouse Gestures code, for example) // Also you can check for add-ons updates using right-click: // copy all code from // https://github.com/Infocatcher/Custom_Buttons/blob/master/Check_for_Addons_Updates/checkForAddonsUpdates.js // after "//== Check for Addons Updates begin" // See "var style = " to modify styles for specific add-ons // (c) Infocatcher 2013-2019 // version 0.1.3pre4 - 2020-01-01 var options = { addonTypes: ["extension", "plugin"], // Possible values: "extension", "plugin" // From extensions: "userstyle" (Stylish), "greasemonkey-user-script" (Greasemonkey), "userscript" (Scriptish) // (swap to reorder in the menu) showVersions: 1, // 0 - don't show versions // 1 - show after name: "Addon Name 1.2" // 2 - show as "acceltext" (in place for hotkey text) showHidden: 0, // 0 - don't show hidden add-ons // -1 - show only enabled hidden add-ons (e.g. to track new items) // 1 - show all hidden add-ons sort: { enabled: 0, clickToPlay: 0, disabled: 1 // Sort order: // 0, 0, 0 - sort add-ons of each type alphabetically // 0, 0, 1 - show enabled add-ons (of each type) first // 0, 1, 2 - enabled add-ons, then click-to-play and then disabled }, closeMenu: false, // Close menu after left-click closeMenuClickToPlay: false // Close menu after left-click, for click to play plugins // Use Shift+click to invert closeMenu* behavior }; var xulns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var mp = document.createElementNS(xulns, "menupopup"); mp.setAttribute("onpopupshowing", "this.updateMenu();"); mp.setAttribute("oncommand", "if(!event.button) this.handleEvent(event);"); // Ignore middle-click in Firefox 89+ mp.setAttribute("onmousedown", "if(event.button == 0) this.handleEvent(event);"); mp.setAttribute("onclick", "if(event.button > 0) this.handleEvent(event);"); mp.setAttribute("oncontextmenu", "return false;"); mp.setAttribute("onpopuphidden", "this.destroyMenu();"); var tb = this.parentNode; if(tb && tb.getAttribute("orient") == "vertical") { // https://addons.mozilla.org/firefox/addon/vertical-toolbar/ var isRight = tb.parentNode.getAttribute("placement") == "right"; mp.setAttribute("position", isRight ? "start_before" : "end_before"); } var cleanupTimer = 0; mp.updateMenu = function() { clearTimeout(cleanupTimer); addStyle(); getRestartlessAddons(options.addonTypes, function(addons) { var df = document.createDocumentFragment(); var prevType; function sortPosition(addon) { if("STATE_ASK_TO_ACTIVATE" in AddonManager && addon.userDisabled == AddonManager.STATE_ASK_TO_ACTIVATE) return options.sort.clickToPlay; if(addon.isActive) return options.sort.enabled; return options.sort.disabled; } function key(addon) { return options.addonTypes.indexOf(addon.type) + "\n" + sortPosition(addon) + "\n" + addon.name.toLowerCase(); } addons.sort(function(a, b) { var ka = key(a); var kb = key(b); return ka == kb ? 0 : ka < kb ? -1 : 1; }).forEach(function(addon) { var type = addon.type; if(prevType && type != prevType) df.appendChild(document.createElementNS(xulns, "menuseparator")); prevType = type; var icon = addon.iconURL || addon.icon64URL; var mi = document.createElementNS(xulns, "menuitem"); mi.className = "menuitem-iconic"; var label = addon.name; if(options.showVersions == 1) label += " " + addon.version; else if(options.showVersions == 2) mi.setAttribute("acceltext", addon.version); mi.setAttribute("label", label); mi.setAttribute("image", icon || mp.icons[type] || ""); if(!icon && mp.icons.useSVG) mi.style.fill = "#15c"; var tip = addon.description || ""; var delay = "delayedStartupAddons" in Services && Services.delayedStartupAddons[addon.id] || null; var isDelayed = delay !== null; mi.classList.toggle("toggleRestartlessAddons-isDelayed", isDelayed); if(isDelayed) tip = "[Delayed Startup: " + delay.toLocaleString() + "]" + (tip ? "\n" + tip : ""); tip && mi.setAttribute("tooltiptext", tip); mi.classList.toggle("toggleRestartlessAddons-isHidden", addon.hidden || false); setDisabled(mi, addon.userDisabled); mi._cbAddon = addon; df.appendChild(mi); }); mp.textContent = ""; mp.appendChild(df); }); }; mp.handleEvent = function(e) { var mi = e.target; if(!("_cbAddon" in mi)) return; var addon = mi._cbAddon; if(e.type == "mousedown") { var closeMenu = isAskToActivateAddon(addon) ? options.closeMenuClickToPlay : options.closeMenu; if(e.shiftKey) closeMenu = !closeMenu; mi.setAttribute("closemenu", closeMenu ? "auto" : "none"); return; } var hasMdf = hasModifier(e); if(e.type == "command" && (!hasMdf || e.shiftKey)) { let newDis = setNewDisabled(addon); setDisabled(mi, newDis); } else if(e.type == "command" && hasMdf || e.type == "click" && e.button == 1) { openAddonPage(addon); closeMenus(mi); } else if(e.type == "click" && e.button == 2) { if(openAddonOptions(addon)) closeMenus(mi); } }; mp.destroyMenu = function() { removeStyle(); clearTimeout(cleanupTimer); cleanupTimer = setTimeout(function() { mp.textContent = ""; }, 5000); }; mp.icons = { get platformVersion() { delete this.platformVersion; return this.platformVersion = parseFloat(Services.appinfo.platformVersion); }, get useSVG() { delete this.useSVG; return this.useSVG = Services.appinfo.name == "Firefox" && this.platformVersion >= 57; }, get plugin() { delete this.plugin; return this.plugin = this.useSVG ? this.platformVersion >= 65 ? "chrome://global/skin/plugins/pluginGeneric.svg" : "chrome://mozapps/skin/plugins/pluginGeneric.svg" : "chrome://mozapps/skin/plugins/pluginGeneric-16.png"; }, get extension() { delete this.extension; return this.extension = this.useSVG ? this.platformVersion >= 76 ? "chrome://mozapps/skin/extensions/extensionGeneric.svg" // Or chrome://mozapps/skin/extensions/extension.svg : "chrome://mozapps/skin/extensions/extensionGeneric-16.svg" : "chrome://mozapps/skin/extensions/extensionGeneric-16.png"; } }; function isAskToActivateAddon(addon) { return addon.type == "plugin" && "STATE_ASK_TO_ACTIVATE" in AddonManager && Services.prefs.getBoolPref("plugins.click_to_play", true); } function setNewDisabled(addon) { var newDis = getNewDisabled(addon); var oldDis = addon.userDisabled; if(Components.interfaces.nsIWebTransportHash) { // random, Fx 123+ var func = function() { func = false; } var thread = Services.tm.currentThread; var meth = newDis ? "disable" : "enable"; addon[meth]({allowSystemAddons: true}).finally(func); while(func) thread.processNextEvent(true); } else try { addon.userDisabled = newDis; } catch(e) { // Error: Cannot disable hidden add-on firefox@getpocket.com _log("Can't set addon.userDisabled to " + newDis + ", error:\n" + e); if(addon.hidden) setNewDisabledRaw(addon, newDis); } var realDis = addon.userDisabled; if(realDis != newDis && addon.type == "extension") { // Firefox 62+? Weird things happens setNewDisabledRaw(addon, newDis); realDis = addon.userDisabled; } if(realDis != newDis) { // We can't enable vulnerable plugins let err = "Can't set addon.userDisabled to " + newDis + ", real value: " + realDis; if(newDis) { _log(err + "\nSTATE_ASK_TO_ACTIVATE not supported?"); newDis = false; } else { _log(err + "\nVulnerable plugin?"); if(oldDis == AddonManager.STATE_ASK_TO_ACTIVATE) newDis = true; else newDis = AddonManager.STATE_ASK_TO_ACTIVATE; } addon.userDisabled = newDis; } ensureSpecialDisabled(addon, newDis); return addon.userDisabled; } function getNewDisabled(addon) { // disabled -> STATE_ASK_TO_ACTIVATE -> enabled -> ... var curDis = addon.userDisabled; var newDis; if("STATE_ASK_TO_ACTIVATE" in AddonManager && curDis == AddonManager.STATE_ASK_TO_ACTIVATE) newDis = false; else if(!curDis) newDis = true; else { if(isAskToActivateAddon(addon)) newDis = AddonManager.STATE_ASK_TO_ACTIVATE; else newDis = false; } return newDis; } function setNewDisabledRaw(addon, newDis) { _log("Let's try set addon.userDisabled using raw hack"); if("lazy" in g) g = g.lazy; if("XPIDatabase" in g && "updateAddonDisabledState" in g.XPIDatabase) { // Firefox 61+ let rawAddon = g.XPIDatabase.getAddons().find(function(rawAddon) { return rawAddon.id == addon.id; }); g.XPIDatabase.updateAddonDisabledState( rawAddon, g.XPIDatabase.updateAddonDisabledState.length == 1 // Firefox 74+ ? { userDisabled: newDis } : newDis ); } else if("eval" in g) { // See "set userDisabled(val)" let addonFor = g.eval("addonFor"); let rawAddon = addonFor(addon); //rawAddon.userDisabled = newDis; g.XPIProvider.updateAddonDisabledState(rawAddon, newDis); } else { // Firefox 57+? See https://forum.mozilla-russia.org/viewtopic.php?pid=745272#p745272 updateAddonDisabledState(addon, newDis); } } function updateAddonDisabledState(addon, newDis) { var key = "_cbToggleRestartlessAddonsData"; var url = URL.createObjectURL(new Blob([ "XPIProvider.updateAddonDisabledState(addonFor(this." + key + "[0]), this." + key + "[1]); delete this." + key + ";" ])); addDestructor(function() { URL.revokeObjectURL(url); }); (updateAddonDisabledState = function(addon, newDis) { nsvo[key] = [addon, newDis]; Services.scriptloader.loadSubScript(url, nsvo); })(addon, newDis); } function setDisabled(mi, disabled) { var askToActivate = "STATE_ASK_TO_ACTIVATE" in AddonManager && disabled == AddonManager.STATE_ASK_TO_ACTIVATE; var cl = mi.classList; cl.toggle("toggleRestartlessAddons-askToActivate", askToActivate); cl.toggle("toggleRestartlessAddons-disabled", disabled && !askToActivate); } function ensureSpecialDisabled(addon, newDis) { if(addon.id == "screenshots@mozilla.org") Services.prefs.setBoolPref("extensions.screenshots.disabled", newDis); } if( this instanceof XULElement // Custom Buttons && typeof event == "object" && !("type" in event) && typeof _phase == "string" && _phase == "init" // Initialization ) { this.type = "menu"; this.orient = "horizontal"; this.appendChild(mp); this.onmouseover = function(e) { if(e.target != this) return; Array.prototype.some.call( this.parentNode.getElementsByTagName("*"), function(node) { if( node != this && node.namespaceURI == xulns // See https://github.com/Infocatcher/Custom_Buttons/issues/28 //&& node.boxObject //&& node.boxObject instanceof Components.interfaces.nsIMenuBoxObject && "open" in node && node.open && node.getElementsByTagName("menupopup").length ) { node.open = false; this.open = true; return true; } return false; }, this ); }; this.onmousedown = function(e) { if(e.target == this && e.button == 0 && hasModifier(e)) e.preventDefault(); }; this.oncontextmenu = function(e) { if(e.target == this && !hasModifier(e) && hasUpdater()) e.preventDefault(); }; this.onclick = function(e) { if(e.target != this) return; if(e.button == 0 && hasModifier(e) || e.button == 1) openAddonsManager(); else if(e.button == 2 && !hasModifier(e) && hasUpdater()) checkForAddonsUpdates.call(this); }; } else { // Mouse gestures or something other... let e; if(typeof event == "object" && event instanceof Event && "screenX" in event) // FireGestures e = event; else if( this instanceof Components.interfaces.nsIDOMChromeWindow && "mgGestureState" in window && "endEvent" in mgGestureState // Mouse Gestures Redox ) e = mgGestureState.endEvent; else { let anchor = this instanceof XULElement && this || window.gBrowser && gBrowser.selectedBrowser || document.documentElement; if("boxObject" in anchor) { let bo = anchor.boxObject; e = { screenX: bo.screenX, screenY: bo.screenY }; if(this instanceof XULElement) e.screenY += bo.height; } } if(!e || !("screenX" in e)) throw new Error("[Toggle Restartless Add-ons]: Can't get event object"); document.documentElement.appendChild(mp); mp.addEventListener("popuphidden", function destroy(e) { mp.removeEventListener(e.type, destroy, false); setTimeout(function() { mp.destroyMenu(); mp.parentNode.removeChild(mp); }, 0); }, false); mp.openPopupAtScreen(e.screenX, e.screenY); } function getRestartlessAddons(addonTypes, callback, context) { if(!("AddonManager" in window)); var then, promise = AddonManager.getAddonsByTypes(addonTypes, then = function(addons) { callback.call(context, addons.filter(function(addon) { var ops = addon.operationsRequiringRestart; return !addon.appDisabled && !(ops & AddonManager.OP_NEEDS_RESTART_ENABLE || ops & AddonManager.OP_NEEDS_RESTART_DISABLE) && ( !addon.hidden || options.showHidden > 0 || options.showHidden == -1 && !addon.userDisabled ) && (addon.iconURL || "").substr(0, 29) != "resource://search-extensions/"; })); }); promise && typeof promise.then == "function" && promise.then(then, Components.utils.reportError); // Firefox 61+ } function openAddonOptions(addon) { // Based on code from chrome://mozapps/content/extensions/extensions.js // Firefox 21.0a1 (2013-01-27) var optionsURL = addon.optionsURL; if(!addon.isActive || !optionsURL) return false; if(addon.type == "plugin") // No options for now! return false; if( addon.optionsType == (AddonManager.OPTIONS_TYPE_INLINE || NaN) || addon.optionsType == (AddonManager.OPTIONS_TYPE_INLINE_INFO || NaN) || addon.optionsType == (AddonManager.OPTIONS_TYPE_INLINE_BROWSER || NaN) ) openAddonPage(addon, true); else if(addon.optionsType == AddonManager.OPTIONS_TYPE_TAB && "switchToTabHavingURI" in window) switchToTabHavingURI(optionsURL, true); else { let windows = Services.wm.getEnumerator(null); while(windows.hasMoreElements()) { let win = windows.getNext(); if(win.document.documentURI == optionsURL) { win.focus(); return true; } } // Note: original code checks browser.preferences.instantApply and may open modal windows window.openDialog(optionsURL, "", "chrome,titlebar,toolbar,centerscreen,dialog=no"); } return true; } function openAddonsManager(view) { var openAddonsMgr = window.BrowserOpenAddonsMgr // Firefox || window.openAddonsMgr // Thunderbird || window.toEM; // SeaMonkey openAddonsMgr(view); } function openAddonPage(addon, scrollToPreferences) { var platformVersion = parseFloat( Services.appinfo.name == "Pale Moon" ? Services.appinfo.version : Services.appinfo.platformVersion ); scrollToPreferences = scrollToPreferences && platformVersion >= 12 ? "/preferences" : ""; openAddonsManager("addons://detail/" + encodeURIComponent(addon.id) + scrollToPreferences); } function hasModifier(e) { return e.ctrlKey || e.shiftKey || e.altKey || e.metaKey; } function addStyle() { if(addStyle.hasOwnProperty("_style")) return; var style = '\ .toggleRestartlessAddons-isDelayed > .menu-iconic-text {\n\ opacity: 0.75;\n\ color: #070;\n\ }\n\ .toggleRestartlessAddons-isHidden > .menu-iconic-text {\n\ color: #609;\n\ }\n\ .toggleRestartlessAddons-disabled > .menu-iconic-left {\n\ opacity: 0.4;\n\ }\n\ .toggleRestartlessAddons-disabled > .menu-iconic-text,\n\ .toggleRestartlessAddons-disabled > .menu-accel-container {\n\ opacity: 0.5;\n\ }\n\ .toggleRestartlessAddons-askToActivate {\n\ color: -moz-nativehyperlinktext;\n\ }'; addStyle._style = document.insertBefore( document.createProcessingInstruction( "xml-stylesheet", 'href="' + "data:text/css," + encodeURIComponent(style) + '" type="text/css"' ), document.documentElement ); } function removeStyle() { if(!addStyle.hasOwnProperty("_style")) return; var s = addStyle._style; s.parentNode.removeChild(s); delete addStyle._style; } function closeMenus(node) { // Based on function closeMenus from chrome://browser/content/utilityOverlay.js for(; node && "tagName" in node; node = node.parentNode) { if( node.namespaceURI == "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" && (node.localName == "menupopup" || node.localName == "popup") ) node.hidePopup(); } } function _log(s) { if(typeof LOG == "function") // Custom Buttons LOG(s); else // Or something else Services.console.logStringMessage("Toggle Restartless Add-ons: " + s); } function hasUpdater() { var has = checkForAddonsUpdates.toString().indexOf("about:addons") != -1; hasUpdater = function() { return has; }; return has; } function checkForAddonsUpdates() { //== Check for Addons Updates begin // http://infocatcher.ucoz.net/js/cb/checkForAddonsUpdates.js // https://forum.mozilla-russia.org/viewtopic.php?id=57958 // https://github.com/Infocatcher/Custom_Buttons/tree/master/Check_for_Addons_Updates // Check for Addons Updates button for Custom Buttons // (code for "code" section) // (c) Infocatcher 2012-2021 // version 0.1.6pre4 - 2021-03-28 // Button just open hidden tab with about:addons and trigger built-in "Check for Updates" function. // And show tab, if found updates. (function() { var btn = this instanceof XULElement ? this : { // Launched not from custom button image: "", // Base64-encoded icon (if empty, will be used "imgLoading") label: "Check for Addons Updates", tooltipText: "" }; if("_cb_disabled" in btn) return; btn._cb_disabled = true; var app = Services.appinfo.name; var pv = parseFloat(Services.appinfo.platformVersion); var ADDONS_URL = "about:addons"; var progressIcon = new ProgressIcon(btn); var image = btn.image || progressIcon.imgLoading; var tip = btn.tooltipText; btn.tooltipText = "Open " + ADDONS_URL + "…"; var tab, browser, gBrowser; var tbTabInfo, tbTab; var trgWindow = Services.wm.getMostRecentWindow("navigator:browser") || app == "Thunderbird" && Services.wm.getMostRecentWindow("mail:3pane") || window; var trgDocument = trgWindow.document; var tabmail = trgDocument.getElementById("tabmail"); if(tabmail && app == "Thunderbird") { // Note: SeaMonkey doesn't support content tabs in mail window let addonsWin; let receivePong = function(subject, topic, data) { addonsWin = subject; }; Services.obs.addObserver(receivePong, "EM-pong", false); Services.obs.notifyObservers(null, "EM-ping", ""); Services.obs.removeObserver(receivePong, "EM-pong"); if(addonsWin) { let rootWindow = addonsWin .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIWebNavigation) .QueryInterface(Components.interfaces.nsIDocShellTreeItem) .rootTreeItem .QueryInterface(Components.interfaces.nsIInterfaceRequestor) .getInterface(Components.interfaces.nsIDOMWindow); tabmail = rootWindow.document.getElementById("tabmail"); tbTabInfo = tabmail.getBrowserForDocument(addonsWin); tbTab = tab = tbTabInfo.tabNode; processAddonsTab(addonsWin); } else { Services.obs.addObserver(function observer(subject, topic, data) { Services.obs.removeObserver(observer, topic); if(subject.document.readyState == "complete") processAddonsTab(subject); else { subject.addEventListener("load", function onLoad(e) { subject.removeEventListener(e.type, onLoad, false); processAddonsTab(subject); }, false); } }, "EM-loaded", false); // See openAddonsMgr() -> openContentTab() tbTabInfo = tabmail.openTab("contentTab", { contentPage: ADDONS_URL, clickHandler: "specialTabs.siteClickHandler(event, /addons\.mozilla\.org/);", background: true }); tbTab = tab = tbTabInfo.tabNode; tbTab.collapsed = true; // Note: dontSelectHiddenTab() not implemented } } else if("gBrowser" in trgWindow && trgWindow.gBrowser.tabs) { let isPending = false; let ws = Services.wm.getEnumerator("navigator:browser"); windowsLoop: while(ws.hasMoreElements()) { let w = ws.getNext(); let tabs = w.gBrowser.tabs; for(let i = 0, l = tabs.length; i < l; ++i) { let t = tabs[i]; if( !t.closing && t.linkedBrowser && t.linkedBrowser.currentURI.spec == ADDONS_URL ) { tab = t; break windowsLoop; } } } gBrowser = trgWindow.gBrowser; if(!tab) { tab = gBrowser.addTab(ADDONS_URL, { triggeringPrincipal: "Services" in window // Firefox 63+ && Services.scriptSecurityManager && Services.scriptSecurityManager.getSystemPrincipal() }); tab.collapsed = true; tab.closing = true; // See "visibleTabs" getter in chrome://browser/content/tabbrowser.xml trgWindow.addEventListener("TabSelect", dontSelectHiddenTab, false); } else if( tab.getAttribute("pending") == "true" // Gecko >= 9.0 || tab.linkedBrowser.contentDocument.readyState == "uninitialized" // || tab.linkedBrowser.__SS_restoreState == 1 ) isPending = true; browser = tab.linkedBrowser; if( isPending || browser.webProgress.isLoadingDocument || browser.currentURI.spec == "about:blank" // Firefox 79+ ) { browser.addEventListener("load", processAddonsTab, true); if(isPending) { if(pv >= 41) { // Workaround to correctly restore pending tab // See https://github.com/Infocatcher/Custom_Buttons/issues/39 let selTab = gBrowser.selectedTab; gBrowser.selectedTab = tab; gBrowser.selectedTab = selTab; } else { browser.reload(); } } } else { processAddonsTab(); } } else { progressIcon.restore(); btn.tooltipText = tip; delete btn._cb_disabled; Services.prompt.alert(window, btn.label, "Error: Can't find supported window!"); return; } function processAddonsTab(e, again) { var doc; if(e && e instanceof Components.interfaces.nsIDOMWindow) { doc = e.document; } else if(e) { doc = e.target; if(doc.location != ADDONS_URL) return; browser.removeEventListener(e.type, processAddonsTab, true); } else { doc = browser.contentDocument; } btn.tooltipText = "Process " + ADDONS_URL + "…"; progressIcon.loading(); var origAttr = "_cb_checkForAddonsUpdates_origImage"; if(!tab.hasAttribute(origAttr)) { var link = doc.querySelector('link[rel="shortcut icon"]'); // Not loaded yet? tab.setAttribute(origAttr, link && link.href || tab.image); } tab.image = image; var fu = $("cmd_findAllUpdates"); if(!fu) { // Firefox 72+ var win = doc.defaultView; var vb = doc.getElementById("html-view-browser"); if(!vb) { if(!HTMLHtmlElement.isInstance(doc.documentElement)) { // Firefox 87+ win.setTimeout(processAddonsTab, 20, win); return; } vb = browser; } if(!again) { // Strange errors happens // chrome://mozapps/content/extensions/aboutaddons.js // getTelemetryViewName() -> el.closest(...) is null win.setTimeout(processAddonsTab, 20, win, true); return; } var vbDoc = vb.contentDocument; fu = vbDoc.querySelector('[action="check-for-updates"]'); var um = vbDoc.getElementById("updates-message"); } var notFound = $("updates-noneFound") || { get hidden() { return um.getAttribute("state") != "none-found"; } }; var updated = $("updates-installed") || { get hidden() { return um.getAttribute("state") != "installed"; } }; // Avoid getting false results from the past update check (may not be required for "noneFound") if(um) { // Firefox 72+ um.hidden = true; um.removeAttribute("state"); } else { notFound.hidden = updated.hidden = true; } //fu.doCommand(); fu.click(); function localize(node, key, callback) { if(um) { // Firefox 72+ doc.l10n.formatValue(key).then(function(s) { callback(s || key); }, Components.utils.reportError); return; } callback(node.getAttribute("value") || key); } var inProgress = $("updates-progress") || { get hidden() { return um.getAttribute("state") != "updating"; } }; localize(inProgress, "addon-updates-updating", function(s) { btn.tooltipText = s; }); var waitTimer = setInterval(function() { if(!doc.defaultView || doc.defaultView.closed) { stopWait(); notify("Tab with add-ons manager was closed!"); return; } if(!inProgress.hidden) return; var autoUpdate = $("utils-autoUpdateDefault") || vbDoc.querySelector('[action="set-update-automatically"]'); var autoUpdateChecked = autoUpdate.getAttribute("checked") == "true" || autoUpdate.checked; var found = $("updates-manualUpdatesFound-btn") || { get hidden() { return um.getAttribute("state") != "manual-updates-found"; } }; if( autoUpdateChecked ? notFound.hidden && updated.hidden : notFound.hidden && found.hidden ) // Too early? return; stopWait(); if(!tbTab) tab.closing = false; function removeTab() { if(!tab.collapsed) return; if(tbTab) { tabmail.closeTab(tbTabInfo, true /*aNoUndo*/); return; } gBrowser.removeTab(tab); (function forgetClosedTab(isSecondTry) { var ss = "nsISessionStore" in Components.interfaces ? ( Components.classes["@mozilla.org/browser/sessionstore;1"] || Components.classes["@mozilla.org/suite/sessionstore;1"] ).getService(Components.interfaces.nsISessionStore) : trgWindow.SessionStore; // Firefox 61+ https://bugzilla.mozilla.org/show_bug.cgi?id=1450559 if(!("forgetClosedTab" in ss)) return; var closedTabs = (ss.getClosedTabDataForWindow(window)); for(let i = 0, l = closedTabs.length; i < l; ++i) { let closedTab = closedTabs[i]; let state = closedTab.state; if(state.entries[state.index - 1].url == ADDONS_URL) { ss.forgetClosedTab(window, i); return; } } if(!isSecondTry) // May be needed in SeaMonkey setTimeout(forgetClosedTab, 0, true); })(); } if(!notFound.hidden) { removeTab(); localize(notFound, "addon-updates-none-found", function(s) { notify(s); }); return; } if(autoUpdateChecked) { removeTab(); localize(updated, "addon-updates-installed", function(s) { notify(s); }); return; } tab.collapsed = false; var cats = $("categories"); var upds = $("category-availableUpdates"); if(cats && upds) { if(vb && cats.selectedItem == upds) // Only for Firefox 72+ cats.selectedItem = $("category-extension"); // Trick to force update cats.selectedItem = upds; } else { // Firefox 76+ ? vbDoc.querySelector('.category[name="available-updates"]').click(); } var tabWin = tab.ownerDocument.defaultView; if(tbTab) tabmail.switchToTab(tbTabInfo); else tabWin.gBrowser.selectedTab = tab; setTimeout(function() { tabWin.focus(); doc.defaultView.focus(); var al = $("addon-list") || vb; al.focus(); }, 0); }, 50); function $(id) { return doc.getElementById(id); } function stopWait() { clearInterval(waitTimer); progressIcon.restore(); btn.tooltipText = tip; if(tab.image == image) tab.image = tab.getAttribute(origAttr); tab.removeAttribute(origAttr); trgWindow.removeEventListener("TabSelect", dontSelectHiddenTab, false); setTimeout(function() { delete btn._cb_disabled; }, 500); } function notify(msg) { Components.classes["@mozilla.org/alerts-service;1"] .getService(Components.interfaces.nsIAlertsService) .showAlertNotification( app == "Firefox" && pv >= 57 ? "chrome://mozapps/skin/extensions/extensionGeneric.svg" : "chrome://mozapps/skin/extensions/extensionGeneric.png", btn.label, msg, false, "", null ); } } function dontSelectHiddenTab(e) { // <tab /><tab collapsed="true" /> // Close first tab: collapsed tab becomes selected var trgTab = e.originalTarget || e.target; if(trgTab != tab) return; if(/\n(?:BrowserOpenAddonsMgr|toEM)@chrome:\/\//.test(new Error().stack)) { // User open Add-ons Manager, show tab trgWindow.removeEventListener("TabSelect", dontSelectHiddenTab, false); setTimeout(function() { // Hidden tab can't be selected, so select it manually... tab.collapsed = tab.closing = false; gBrowser.selectedTab = tab; }, 0); } function done(t) { if(!t.hidden && !t.closing) { e.preventDefault(); e.stopPropagation(); return gBrowser.selectedTab = t; } return false; } for(var t = tab.nextSibling; t; t = t.nextSibling) if(done(t)) return; for(var t = tab.previousSibling; t; t = t.previousSibling) if(done(t)) return; } function ProgressIcon(btn) { var app = Services.appinfo.name; var pv = parseFloat(Services.appinfo.platformVersion); if(app == "SeaMonkey") this.imgConnecting = this.imgLoading = "chrome://communicator/skin/icons/loading.gif"; else if(app == "Thunderbird") { this.imgConnecting = "chrome://messenger/skin/icons/connecting.png"; this.imgLoading = "chrome://messenger/skin/icons/loading.png"; } else { this.imgConnecting = app == "Firefox" && pv >= 58 ? "chrome://browser/skin/tabbrowser/tab-connecting.png" : "chrome://browser/skin/tabbrowser/connecting.png"; this.imgLoading = app == "Firefox" && pv >= 48 ? "chrome://global/skin/icons/loading.png" : "chrome://browser/skin/tabbrowser/loading.png"; } if(!(btn instanceof XULElement)) { this.loading = this.restore = function() {}; return; } var useAnimation = app == "Firefox" && pv >= 32 && pv < 48; var btnIcon = btn.icon || btn.ownerDocument.getAnonymousElementByAttribute(btn, "class", "toolbarbutton-icon"); var origIcon = btnIcon.src; btnIcon.src = this.imgConnecting; if(useAnimation) { let cs = btnIcon.ownerDocument.defaultView.getComputedStyle(btnIcon, null); let s = btnIcon.style; s.margin = [cs.marginTop, cs.marginRight, cs.marginBottom, cs.marginLeft].join(" "); s.padding = [cs.paddingTop, cs.paddingRight, cs.paddingBottom, cs.paddingLeft].join(" "); s.width = cs.width; s.height = cs.height; s.boxShadow = "none"; s.borderColor = s.background = "transparent"; btnIcon.setAttribute("fadein", "true"); btnIcon.setAttribute("busy", "true"); btnIcon.classList.add("tab-throbber"); btnIcon._restore = function() { delete btnIcon._restore; btnIcon.removeAttribute("busy"); btnIcon.removeAttribute("progress"); setTimeout(function() { btnIcon.classList.remove("tab-throbber"); btnIcon.removeAttribute("style"); btnIcon.removeAttribute("fadein"); }, 0); }; } this.loading = function() { btnIcon.src = this.imgLoading; if(useAnimation) btnIcon.setAttribute("progress", "true"); }; this.restore = function() { btnIcon.src = origIcon; if(useAnimation) btnIcon._restore(); }; } }).call(this); //== Check for Addons Updates end } this.tooltipText = "Переключатель джетпаков" + "\nПКМ – проверить обновления" + "\nСКМ – открыть страницу дополнений" + "\nShift+ПКМ – меню кнопки" + "\n\nВ меню: \nЛКМ – включить/выключить дополнение без закрытия меню" + "\nShift+ЛКМ – включить/выключить дополнение" + "\nСКМ – открыть страницу дополнения в управлении дополнениями" + "\nПКМ – открыть настройки дополнения (если есть)"; // Autoopen/close feature var openDelay = 200; var closeDelay = 350; var _openTimer = 0; var _closeTimer = 0; this.onmouseover = function(e) { clearTimeout(_closeTimer); if(e.target == this && closeOtherMenus()) { this.open = true; return; } _openTimer = setTimeout(function() { self.open = true; }, openDelay); }; this.onmouseout = function(e) { clearTimeout(_openTimer); _closeTimer = setTimeout(function() { if(!isContextOpened()) self.open = false; }, closeDelay); }; function closeOtherMenus() { return Array.prototype.some.call( self.parentNode.getElementsByTagName("*"), function(node) { if( node != self && node.namespaceURI == xulns // See https://github.com/Infocatcher/Custom_Buttons/issues/28 //&& node.boxObject //&& node.boxObject instanceof Components.interfaces.nsIMenuBoxObject && "open" in node && node.open && node.getElementsByTagName("menupopup").length ) { node.open = false; return true; } return false; } ); } function isContextOpened() { return inBtn(document.popupNode); } function inBtn(node) { for(; node; node = node.parentNode) if(node == self) return true; return false; }
Uncaught TypeError: openAddonsMgr is not a function openAddonsManager chrome://user_chrome_files/content/custom_scripts/custom_script.js line 179 > Function:433 onclick chrome://user_chrome_files/content/custom_scripts/custom_script.js line 179 > Function:341 2 custom_script.js line 179 > Function:433:15 openAddonsManager chrome://user_chrome_files/content/custom_scripts/custom_script.js line 179 > Function:433 onclick chrome://user_chrome_files/content/custom_scripts/custom_script.js line 179 > Function:341
Отредактировано egorsemenov06 (10-06-2024 21:53:36)
Отсутствует