Я так переделал, и всё работает
Нет я же написал это не пойдет, открой второе окно и понажимай там пункт, перезагружаться будет в первом окне
Отредактировано Vitaliy V. (21-04-2024 17:07:46)
Отсутствует
Vitaliy V. || Спасибо, обновился.
Здраствуйте. Хотел выдернуть с ATB "меню с дополнениями" и "восстановить фавиконки". Но у меня не выходит, туповат для этого. Просто там какие-то изменения все же уже имеются, вот и хотел скрипты обновить. Можно их как-то вытащить в отдельные скрипты в ucf? Как раньше. Другие кнопки особо не нужны как и ATB.
add:
Можно добавить в "Long Left Click", функцию клика ПКМ, чтобы быстро открывать несколько ссылок, например на новостных сайтах. По типу дополнения "Right Links We"? Ну или отдельным скриптом, если можно. Хотя наверно с просьбами уже запарил.
Просто ATB бесит тем, что он горит красным в about:addons, плюс правки в about:config, плюс лишние кнопки тоже мозолят(у меня ноут) в "Настройка панели инструментов". Насчет "Long Left Click", может его добавить в AMO? Если бы еще добавить правый клик. Отдельным скриптом тоже будет норм. Ладно, в общем, если завал просьбами то пойму. Оставлю как есть, пока работает.
Отредактировано b0ttle (22-04-2024 19:38:42)
Отсутствует
b0ttle
Так это "эксперимент", он будет гореть пока плашку не скроете стилем. Подозреваю, что, по этой же причине, на AMO их не будет.
А так да, прикольная функция, но мне так и не пригодилась - Snap Links Plus
Отсутствует
_zt
Интересное дополнение, не знал что можно таким образом открывать несколько вкладок. ПКМ все же привычнее, заметил, что вообще в контекстное меню не заглядывал продолжительное время, может пол года. По идее и ПКМ не нужен, если через Ctrl кликать, но это же руку надо тянуть к клавиатуре. Плюс контекстным меню все равно не пользуюсь.
Кстати, вроде есть настройка about:config, которая по клику открывает все ссылки в новой вкладке. Может он тоже сойдет. Обычно, в том же окне открываю лишь закладки. На самих вкладках наоборот, редко, там обычно ПКМ и в новой вкладке.
Отредактировано b0ttle (22-04-2024 12:40:44)
Отсутствует
Можно их как-то вытащить в отдельные скрипты в ucf?
Ну хорошо, только сначала нужно обновить UCF, незначительное обновление добавлен модуль ExtensionParent, может пригодится и для других скриптов.
Upd: + файл настроек CustomStylesScripts.mjs вынесен в корень user_chrome_files
(async ( id = "ucf-aom-button", label = "Дополнения", tooltiptext = "ЛКМ: Меню дополнений\nСКМ: Отладка дополнений\nПКМ: Открыть менеджер дополнений", img = "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>", checkbox_img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' height='16' width='16' viewBox='0 0 16 16'><path d='M 3,7 7,11 13,5' style='fill:none;stroke:white;stroke-width:1;'/></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([ ]), 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)); }, async populateMenu(e) { var popup = e.target, doc = e.view.document; var addons = await AddonManager.getAddonsByTypes(this.exceptions_type_listarr); var addonsMap = new WeakMap(); var setAttributesMenu = (mi, addon, extension) => { var permissions, uuid; var 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}`); }; var {GlobalManager} = ExtensionParent; 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 => { e.preventDefault(); e.stopPropagation(); 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", () => { AddonManager.removeAddonListener(listener); popup.removeEventListener("click", click); addonsMap = null; for (let item of popup.querySelectorAll("menuitem")) item.remove(); }, { once: true }); }, handleClick(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); win.setTimeout(() => { this.alertsService.showAlertNotification(null, "ID в буфере обмена!", addon.id, false); }, 100); } else if (e.shiftKey) { if (extension?.uuid) { this.clipboardHelp.copyString(extension.uuid); win.setTimeout(() => { this.alertsService.showAlertNotification(null, "UUID в буфере обмена!", extension.uuid, false); }, 100); } } 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) { win.closeMenus(mi); if (Services.prompt.confirm(win, null, `Удалить ${addon.name}?`)) addon.uninstall(); } break; } }, openAddonOptions(addon, win) { switch (addon.optionsType) { case 5: let viewID = `addons://detail/${encodeURIComponent(addon.id)}/preferences`; if ("openAddonsMgr" in win.BrowserAddonUI) win.BrowserAddonUI.openAddonsMgr(viewID); else win.BrowserOpenAddonsMgr(viewID); break; case 3: win.switchToTabHavingURI(addon.optionsURL, true); break; } }, browseDir(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(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.relatedToCurrent = true; return win.gBrowser.addTab(url, params); }, } ) => { Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(`${id}-img`, Services.io.newURI(img)); CustomizableUI.createWidget({ id, type: "custom", label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild(doc) { var btn = doc.createXULElement("toolbarbutton"), win = doc.defaultView; var props = { id, label, context: "", 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 == 1) e.view.switchToTabHavingURI("about:debugging#/runtime/this-firefox", true, { ignoreFragment: "whenComparing", triggeringPrincipal: Services.scriptSecurityManager.getSystemPrincipal(), }); else if (e.button == 2) { let win = e.view, viewID = "addons://list/extension"; if ("openAddonsMgr" in win.BrowserAddonUI) win.BrowserAddonUI.openAddonsMgr(viewID); else win.BrowserOpenAddonsMgr(viewID); } }); var mp = doc.createXULElement("menupopup"); mp.id = `${id}-popup`; 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} { list-style-image: url("resource://${id}-img") !important; } #${id}-popup menuitem { fill: currentColor; fill-opacity: .8; list-style-image: url("resource://${id}-img") !important; &::after { display: flex !important; content: "" !important; height: 16px !important; width: 16px !important; padding: 0 !important; border: 1px solid #0074e8 !important; border-radius: 0 !important; background-repeat: no-repeat !important; background-position: center !important; background-size: 16px !important; background-color: #0074e8 !important; background-image: url("${checkbox_img}") !important; opacity: 1 !important; } &.ucf-disabled::after { border-color: currentColor !important; background-color: transparent !important; background-image: none !important; opacity: .25 !important; } &.ucf-disabled > label, &.ucf-notoptions > label { opacity: .6 !important; } &.ucf-system > label { text-decoration: underline !important; text-decoration-style: dotted !important; } & > label { margin-inline-end: 0 !important; } & > .menu-accel-container { display: flex !important; padding: 4px !important; margin: 0 !important; opacity: 1 !important; } & > .menu-accel-container .menu-iconic-accel { display: flex !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; } &.ucf-type-dictionary > .menu-accel-container .menu-iconic-accel { background-color: #e31b5d !important; } &.ucf-type-locale > .menu-accel-container .menu-iconic-accel { background-color: #27ae81 !important; } &.ucf-type-theme > .menu-accel-container .menu-iconic-accel { background-color: #f38525 !important; } } `); try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} return btn; }, }); })();
(async ( id = "ucf-loads-favicons", label = "Восстановить фавиконки", tooltiptext = "Восстановить фавиконки закладок", img = "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(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M3.6.6v14.8L8 11l4.4 4.4V.6z'/></svg>", maxrequests = 50, // Максимальное количество параллельных запросов maxtimeout = 30, // Длительность до прерывания запроса в секундах alertnotification = true, // Уведомление о завершении поиска фавиконок для закладок favicons = { _favrunning: false, get alertsService() { delete this.alertsService; return this.alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); }, showAlert(title, val) { try { this.alertsService.showAlertNotification(null, title, val, false); } catch(e) {} }, favSearchStart() { if (this._favrunning) return; this._favrunning = true; this.callWithEachWindow(id, {fill: "color-mix(in srgb, currentColor 20%, #e31b5d)"}); PlacesUtils.promiseBookmarksTree(PlacesUtils.bookmarks.rootGuid).then(root => { var urlsList = []; var convert = (node, url) => { if (node.children) node.children.map(convert); else if ((url = node.uri) && /^(?:https?|ftp|file):/.test(url)) urlsList.push(url); }; convert(root); var favForPage = siteURI => { return new Promise(resolve => { try { siteURI = Services.io.newURI(siteURI); } catch(e) { resolve(null); } PlacesUtils.favicons.getFaviconURLForPage(siteURI, uri => { if (uri === null) resolve(siteURI); else resolve(null); }); }); }; Promise.all(urlsList.map(favForPage)).then(results => this.favSearchResults(results.filter(url => url !== null))); }); }, favComplete(favsuccesslength, favmaxlength) { this._favrunning = false; this.callWithEachWindow(id, {fill: ""}); if (alertnotification) this.showAlert("Поиск фавиконок", `Успешно обработано - ${favsuccesslength}, не удалось обработать - ${favmaxlength - favsuccesslength}`); }, favSearchResults(results) { var favmaxlength = results.length; var favsuccesslength = 0; if (!favmaxlength) { this.favComplete(0, 0); return; } var favmaxtimeout = maxtimeout * 1000; var _favmaxlength = favmaxlength; var splice = results.splice(0, maxrequests); var favSearchPage = siteURI => { (new Promise(resolve => { try { let req = new XMLHttpRequest(); req.mozBackgroundRequest = true; req.open("GET", siteURI.spec, true); req.responseType = "document"; req.overrideMimeType("text/html"); req.timeout = favmaxtimeout; req.onload = () => {console.log(req) try { let doc = req.responseXML, favURI; if (doc) { let links = doc.querySelectorAll("head link[href][rel~='icon']"), lastlink, is16, is32, isany; for (let link of links) { if (link.sizes.length === 1) { let size = link.sizes[0]; if (/any/i.test(size)) isany = link; else if (/32x32/i.test(size)) is32 = link; else if (/16x16/i.test(size)) is16 = link; } lastlink = link; } links = isany || is32 || is16 || lastlink; if (links) favURI = links.href; } if (!favURI) favURI = `${req.responseURL ? Services.io.newURI(req.responseURL).prePath : siteURI.prePath}/favicon.ico`; let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); let request = PlacesUtils.favicons.setAndFetchFaviconForPage(siteURI, Services.io.newURI(favURI), false, PlacesUtils.favicons.FAVICON_LOAD_NON_PRIVATE, { onComplete() { ++favsuccesslength; resolve(); timer.cancel(); timer = null; request = null; }, }, Services.scriptSecurityManager.getSystemPrincipal()); if (!request) { resolve(); timer = null; return; } timer.initWithCallback(() => { resolve(); try { request.cancel(); } catch(e) {} timer = null; request = null; }, favmaxtimeout, timer.TYPE_ONE_SHOT); } catch(e) { resolve(); } }; req.onabort = () => { resolve(); }; req.onerror = req.ontimeout = () => { resolve(); req.abort(); }; req.send(null); } catch(e) { resolve(); } })).then(() => { if (!(--_favmaxlength)) { this.favComplete(favsuccesslength, favmaxlength); return; } if (!results.length) return; favSearchPage(results.shift()); }); }; splice.map(favSearchPage); }, callWithEachWindow(buttonID, atr) { var getW = CustomizableUI.getWidget(buttonID); if (getW.instances.length) for (let {node} of getW.instances) { if (!node) continue; for (let a in atr) node.style.setProperty(a, atr[a]); } else for (let win of CustomizableUI.windows) { let node = getW.forWindow(win).node; if (!node) continue; for (let a in atr) node.style.setProperty(a, atr[a]); } }, } ) => {Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(`${id}-img`, Services.io.newURI(img)); CustomizableUI.createWidget({ id, label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important"); if (favicons._favrunning) btn.style.setProperty("fill", "color-mix(in srgb, currentColor 20%, #e31b5d)"); }, onCommand(e) { favicons.favSearchStart(); }, }); })();
Добавлено 22-04-2024 15:52:41
Можно добавить в "Long Left Click", функцию клика ПКМ
Не планирую, не заинтеросован в данной функции
Насчет "Long Left Click", может его добавить в AMO?
Experimental WebExtensions APIs невозможно добавить на AMO, и также нельзя просто подписать подобное расширение.
Из того что можно добавить на AMO у меня только New Tab Page и уже подписано.
Отредактировано Vitaliy V. (22-04-2024 21:55:09)
Отсутствует
egorsemenov06
//Ссылки кликабельны (async ( id = "ucf-text-to-link", label = "Текст URL в кликабельные ссылки", tooltiptext = "Превратить текст URL в кликабельные ссылки", img = "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(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='m5.6 10.4 4.8-4.8m-8.9 4.9c-2.6 2.6 1.4 6.6 4 4l1-1c2.6-2.6-1.4-6.6-4-4zm9-9c2.6-2.6 6.6 1.4 4 4l-1 1c-2.6 2.6-6.6-1.4-4-4z'/></svg>", texttolink = { _registerActor() { if (this.registerActor) return; ChromeUtils.registerWindowActor("UcfTextToLinkActor", { child: { esModuleURI: "chrome://user_chrome_files/content/custom_scripts/UcfTextToLinkActorChild.mjs" }, allFrames: true, messageManagerGroups: ["browsers"], }); this.registerActor = true; }, sendAsyncMessages(win, message, data) { this._registerActor(); this.sendAsyncMessages = this._sendAsyncMessages; this.sendAsyncMessages(win, message, data); }, _sendAsyncMessages(win, message, data) { var {browsingContext} = win.gBrowser.selectedBrowser; ({ "UcfTextToLinkActor:TextToLink"() { for (let actor of this) actor.sendAsyncMessage(message); }, *[Symbol.iterator]() { var contextsToVisit = [browsingContext]; while (contextsToVisit.length) { let currentContext = contextsToVisit.pop(); let global = currentContext?.currentWindowGlobal; if (!global) continue; yield global.getActor("UcfTextToLinkActor"); contextsToVisit.push(...currentContext.children); } }, })[message]?.(); }, } ) => { Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(`${id}-img`, Services.io.newURI(img)); CustomizableUI.createWidget({ id, label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important"); }, onCommand(e) { texttolink.sendAsyncMessages(e.view, "UcfTextToLinkActor:TextToLink"); }, }); })();
const lazy = { get excludedTags() { delete this.excludedTags; return this.excludedTags = new Set(["a","svg","canvas","applet","input","button","area","embed","noembed","frame","frameset","head","iframe","img","select","option","datalist","map","meta","noscript","video","audio","object","param","script","style","textarea","code"]); }, }; export class UcfTextToLinkActorChild extends JSWindowActorChild { receiveMessage(msg) { return ({ "UcfTextToLinkActor:TextToLink": () => { this.textToLink(); }, })[msg.name]?.(); } textToLink() { if (this.running || !this.document?.body) return; this.running = true; var url_regexp = /(^|[\s(,;'"`“\[\]=_])((?:(?:https?|ftp):\/\/[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]|www\d{0,3}[.][a-zа-яё0-9.-]{2,249}|[a-zа-яё0-9.-]{2,250}[.][a-zа-яё]{2,4}\/)[-\wа-яё.!~*'();,/?:@&=+$#%_\u2300-\u23FF\u2600-\u27BF]*)/gim; var email_regexp = /(^|mailto:|[\s(,;'"`“\[\]=])([\w!#$%&'*+/=?^`{|}~.-]{2,}@[\[\]a-z0-9.-]+)/gim; var elList = []; var setEmail = (node, text) => { var repl = text.replace(email_regexp, '$1<a href="mailto:$2" class="add__TextToEmail">$2</a>'); if (text.length == repl.length) return; var span = node.ownerDocument.createElement("span"); span["innerHTML"] = repl; node.replaceWith(span); }; var setLink = (node, text) => { if (!(text = node.textContent)) return; text = text.replace(/</g, "<").replace(/>/g, ">"); var repl = text.replace(url_regexp, '$1<a href="$2" target="_blank" class="add__TextToLink">$2</a>'); if (text.length == repl.length) { setEmail(node, text); return; } var span = node.ownerDocument.createElement("span"); span["innerHTML"] = repl; for (let el of span.querySelectorAll("a.add__TextToLink[href]:not([href^='http']):not([href^='ftp'])")) el.setAttribute("href", `http://${el.getAttribute("href")}`); node.replaceWith(span); var txtnode = Node.TEXT_NODE; for (let child of span.childNodes) { let txt; if (child.nodeType === txtnode && (txt = child.textContent)) setEmail(child, txt); } }; var getWalker = elem => { var doc = elem.ownerDocument, reject = NodeFilter.FILTER_REJECT, skip = NodeFilter.FILTER_SKIP, accept = NodeFilter.FILTER_ACCEPT, txtnode = Node.TEXT_NODE; var walker = doc.createTreeWalker(elem, NodeFilter.SHOW_ALL, { acceptNode(node) { if (lazy.excludedTags.has(node.localName)) return reject; if (node.nodeType !== txtnode && !node.shadowRoot) return skip; return accept; } }, false); while (walker.nextNode()) { let currnode = walker.currentNode; if (!currnode.shadowRoot) elList.push(currnode); else getWalker(currnode.shadowRoot); } }; getWalker(this.document.body); for (let el of elList) setLink(el); elList = []; this.running = false; } }
//Переключить Куки (async ( id = "ucf-cookie-toggle", label = "Переключить Куки", tooltiptext = "ЛКМ: Переключить Куки\nСКМ: Удалить куки домена текущей страницы\nПКМ: Управление куками", gpref = "network.cookie.cookieBehavior", img = "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(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M12.5 10.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1h-1v-1M8 .6C8 5 11 8 15.4 8c0 4-3.4 7.4-7.4 7.4S.6 12 .6 8 4 .6 8 .6M12.5 26.5v-1h-1v1h1m-4-4h1v1h-1v-1m0 7h1v-1h-1v1m-6-7h1v1h-1v-1m4 4v-1h-1v1h1m-3 3v-1h-1m3-9h1v1m2-3.5v.5h1V17m2 2.5v1h1v-1h-1m3.5 3h-.5v1h.5m-8.5-3h-1v-1M8 16.6c4 0 7.4 3.4 7.4 7.4S12 31.4 8 31.4.6 28 .6 24 4 16.6 8 16.6'/></svg>", tbarbtns = { initialised: false, get network_cookie_cookieBehavior() { delete this.network_cookie_cookieBehavior; try { return this.network_cookie_cookieBehavior = Services.prefs.getIntPref(gpref); } catch(e) { } return this.network_cookie_cookieBehavior = null; }, init() { if (this.initialised) return; this.initialised = true; Services.prefs.addObserver(gpref, this); }, prefToggleNumber(pref, next) { Services.prefs.setIntPref(pref, next[Services.prefs.getIntPref(pref)]); }, getETDL(uri) { var eTLD = ""; try { eTLD = Services.eTLD.getBaseDomain(uri); } catch (e) { try { eTLD = uri.asciiHost; } catch (e) {} } return eTLD; }, async viewCookies(win) { var uri = win.gBrowser.selectedBrowser.currentURI; try { let _uri = win.ReaderMode.getOriginalUrl(uri.spec); if (_uri) uri = Services.io.newURI(_uri); } catch(e) {} uri = this.getETDL(uri); var type = "Browser:SiteDataSettings", id = "SiteDataSettingsDialog"; var _win = Services.wm.getMostRecentWindow(type); if (!_win) { await win.SiteDataManager.updateSites(); let url = "chrome://browser/content/preferences/dialogs/siteDataSettings.xhtml", {xulStore: xs} = Services; let sx = +xs.getValue(url, id, "screenX") || xs.setValue(url, id, "screenX", 1) || 1; let sy = +xs.getValue(url, id, "screenY") || xs.setValue(url, id, "screenY", 1) || 1; let wh = +xs.getValue(url, id, "width") || xs.setValue(url, id, "width", 600) || 600; let ht = +xs.getValue(url, id, "height") || xs.setValue(url, id, "height", 500) || 500; let sm = xs.getValue(url, id, "sizemode"); let features = `chrome,dialog=no,resizable,${`screenX=${sx},screenY=${sy}`}${`,width=${wh},height=${ht}`}`; _win = win.openDialog(url, type, features); await new Promise(resolve => { _win.windowRoot.addEventListener("DOMContentLoaded", () => { _win.windowRoot.addEventListener("MozUpdateWindowPos", () => { if (sm === "maximized") _win.maximize(); }, { once: true, capture: true }); resolve(); }, { once: true }); }); let docEl = _win.document.documentElement; docEl.setAttribute("windowtype", type); docEl.id = id; docEl.setAttribute("persist", "screenX screenY width height sizemode"); } _win.focus(); var filter = _win.document.querySelector("#searchBox"); if (!filter) return; filter.value = uri; filter.focus(); filter.dispatchEvent(new _win.Event("input", { bubbles: true })); }, callWithEachWindow(buttonID, atr) { var getW = CustomizableUI.getWidget(buttonID); if (getW.instances.length) for (let {node} of getW.instances) { if (!node) continue; for (let a in atr) node.setAttribute(a, atr[a]); } else for (let win of CustomizableUI.windows) { let node = getW.forWindow(win).node; if (!node) continue; for (let a in atr) node.setAttribute(a, atr[a]); } }, observe(subject, topic, pref) { if (pref == gpref) { delete this.network_cookie_cookieBehavior; let network_cookie_cookieBehavior = this.network_cookie_cookieBehavior = Services.prefs.getIntPref(pref); this.callWithEachWindow(id, {badge: network_cookie_cookieBehavior, badgeStyle: `background: ${network_cookie_cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`}); } }, uninit() { if (!this.initialised) return; Services.prefs.removeObserver(gpref, this); this.initialised = false; }, }, protocolHandler = Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) ) => { protocolHandler.setSubstitution(`${id}-img`, Services.io.newURI(img)); protocolHandler.setSubstitution(`${id}-img-0`, Services.io.newURI(img.replace("viewBox='0 0 16 16'", "viewBox='0 16 16 16'"))); CustomizableUI.createWidget({ id, type: "custom", label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild(document) { var win = document.defaultView, trbn = document.createXULElement("toolbarbutton"); var props = { id, label, context: "", tooltiptext, class: "toolbarbutton-1 chromeclass-toolbar-additional badged-button", badged: "true", "constrain-size": "true", }; for (let p in props) trbn.setAttribute(p, props[p]); var cookieBehavior = tbarbtns.network_cookie_cookieBehavior; if (cookieBehavior !== null) { trbn.setAttribute("badge", cookieBehavior); trbn.setAttribute("badgeStyle", `background: ${cookieBehavior !== 2 ? "#0074e8" : "#e31b5d"}; color: #ffffff; font-size: 10px; line-height: 10px; box-shadow: none; text-shadow: none; padding-block: 0 1px !important; padding-inline: 2px !important; min-width: 0 !important;`); trbn.addEventListener("click", e => { if (e.button == 0) tbarbtns.prefToggleNumber(gpref, [1,2,3,4,5,0]); else if (e.button == 1) { if (!win.gIdentityHandler?._uriHasHost || win.gIdentityHandler._pageExtensionPolicy) return; let baseDomain = win.SiteDataManager.getBaseDomainFromHost(win.gIdentityHandler._uri.host); win.SiteDataManager.hasSiteData(baseDomain).then(hasData => { if (hasData && win.SiteDataManager.promptSiteDataRemoval(win, [baseDomain])) win.SiteDataManager.remove(baseDomain); }); } else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); tbarbtns.viewCookies(win); } }); } var btnstyle = `data:text/css;charset=utf-8,${encodeURIComponent(` #${id} { list-style-image: url("resource://${id}-img") !important; } #${id}[badge="0"] { list-style-image: url("resource://${id}-img-0") !important; } #${id}[badge="2"] { fill: color-mix(in srgb, currentColor 20%, #e31b5d) !important; } `)}`; try { win.windowUtils.loadSheetUsingURIString(btnstyle, win.windowUtils.USER_SHEET); } catch (e) {} tbarbtns.init(); return trbn; }, onDestroyed(doc) { tbarbtns.uninit(); }, }); })();
Отсутствует
Vitaliy V.
Просто пожелание, ATB все время обновляется, а что обновляется не ясно. Стоит качать или нет, не понятно. Может changelog? Хотя, его наверно не все поймут. Сейчас дошло, что можно скачивать и в распакованном виде сравнить с предыдущим) Но changelog, если будет понятный, то наверно было бы неплохо. Если никто не поймет, то ладно.
Отсутствует
Скрипт "Переключить куки" под третим спойлером https://forum.mozilla-russia.org/viewto … 11#p809311 , по ЛКМ пять опций, опишите, плиз, их назначение.
Отсутствует
Нечаянно забрел, и увидел такое. С каких пор в путях можно прописывать %ProfD%\\..\\..\\? Возможно у него это реализовано в самом Handy_Clicks?
Это обычный массив, который обрабатывает расширение Handy_Clicks
для Handy_Clicks это %ProfD%\\..\\..\\ а для получиться Services.dirsvc.get("ProfD", Ci.nsIFile).parent.parent.path;
Жизнь иногда такое выкидывает, что хочется подобрать...
На форуме
fuchsfan
Это исключительно для персональной схемы защиты от отслеживания about:preferences#privacy или browser.contentblocking.category = custom, в других схемах переключение не работает.
Интересен только один пункт "Блокировать межсайтовые отслеживающие куки, а другие изолировать" или network.cookie.cookieBehavior = 5, этот режим включает изоляцию кук друг от друга.
В строгой схеме защиты он включен по умолчанию.
Основная межсайтовая регистрация остается доступной, а если кажется, что работа сайта нарушена, то читаем
Остальные пункты и так понятны. Они или превращают браузер в решето, или ломают сайты, или создают проблемы с межсайтовой регистрацией.
Добавлено 24-04-2024 11:30:08
Кстати, должно быть не 5, а 6, видимо network.cookie.cookieBehavior = 0 нет. Что аналогично снятой галке в настройках.
Отредактировано _zt (24-04-2024 11:30:08)
Отсутствует
Можно еще пару кнопок обновить
//about_config.......................................... (async ( id = "ucf-open-about-config", label = "about:config", tooltiptext = "ЛКМ: Открыть about:config\nСКМ: Искать выделенное в about:config\nПКМ: Открыть about:about", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;'><path d='m 8.66,15.4 h -1.2 c -0.69,0 -1.3,-0.5 -1.5,-1.2 L 5.58,13 C 5.32,12.9 5.07,12.7 4.82,12.5 L 3.41,12.9 C 2.76,13 2.04,12.8 1.69,12.1 L 1.09,11.2 C 0.748,10.5 0.838,9.75 1.31,9.33 l 1,-1 V 7.52 L 1.32,6.55 C 0.842,6.06 0.748,5.36 1.1,4.78 L 1.7,3.8 C 2.04,3.22 2.75,2.93 3.4,3.08 L 4.84,3.4 C 5.1,3.24 5.34,3.1 5.58,2.99 L 5.96,1.72 C 6.16,1.08 6.77,0.631 7.46,0.629 h 1.2 C 9.35,0.629 9.94,1.07 10,1.7 L 10.4,3 c 0.3,0.11 0.5,0.25 0.8,0.4 L 12.5,3.08 C 13.2,2.93 14,3.22 14.3,3.8 l 0.6,0.98 c 0.4,0.57 0.3,1.28 -0.2,1.77 l -1,0.97 v 0.81 l 1,1 c 0.5,0.42 0.6,1.17 0.2,1.87 l -0.6,0.9 C 14,12.8 13.2,13 12.5,12.9 l -1.3,-0.4 c -0.3,0.2 -0.5,0.4 -0.8,0.5 L 10,14.2 c -0.1,0.7 -0.64,1.2 -1.34,1.2 z'/><circle cx='8' cy='8' r='2.4'/></g></svg>", about_config = { get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, openClipboardConfigTab(win, clip = "", copy) { var filter = this.readFromClipboard(win), nowarn = false, pref = "browser.aboutConfig.showWarning"; if (copy && clip != filter) this.clipboardHelp.copyString(clip); if (Services.prefs.getBoolPref(pref, false)) { Services.prefs.setBoolPref(pref, false); nowarn = true; } win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, "about:config")) .addEventListener("pageshow", e => { var doc = e.target; var input = doc?.querySelector("input#about-config-search"); if (input && filter) { input.value = filter; input.focus(); input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true })); } if (nowarn) win.setTimeout(() => { Services.prefs.setBoolPref(pref, true); }, 200); }, { once: true }); }, openSelectedConfigTab(win) { var clip = this.readFromClipboard(win); win.goDoCommand("cmd_copy"); win.setTimeout(() => { this.openClipboardConfigTab(win, clip, true); }, 100); }, addTab(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.index = win.gBrowser.selectedTab._tPos + 1; return win.gBrowser.addTab(url, params); }, readFromClipboard(win) { var url = ""; try { let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(win.docShell.QueryInterface(Ci.nsILoadContext)); trans.addDataFlavor("text/plain"); let {clipboard} = Services; clipboard.getData(trans, clipboard.kGlobalClipboard); let data = {}; trans.getTransferData("text/plain", data); if (data.value) url = data.value.QueryInterface(Ci.nsISupportsString).data; } catch (ex) {} return url; }, } ) => { Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(`${id}-img`, Services.io.newURI(img)); CustomizableUI.createWidget({ id, type: "custom", label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var btn = doc.createXULElement("toolbarbutton"); var props = { id, label, context: "", tooltiptext, class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important"); btn.addEventListener("click", e => { var win = e.view; if (e.button == 0) win.gBrowser.selectedTab = about_config.addTab(win, "about:config"); else if (e.button == 1) about_config.openSelectedConfigTab(win); else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); win.gBrowser.selectedTab = about_config.addTab(win, "about:about"); } }); return btn; }, }); })();
//Очистить историю (async ( id = "ucf-clear-history", label = "Очистить историю", tooltiptext = "Очистить историю", img = "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(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;' d='M5.5.7c1.1 0 1.1 1.6 0 1.6S4.4.7 5.5.7zm8.3.5L9.5 5.5s-1.24.1-2.68.12C5.18 7.15 4.12 7.66.822 8.01v1.2C3.35 13.3 4.97 15.2 9.21 15.2h1.09c1.4-1.7 2-2.9 2.5-4.9V9.21c-.5-1.19-1.6-2.41-1.6-2.41l4.1-4.1zm-10.3 2c1.7 0 1.7 2.6 0 2.6s-1.7-2.6 0-2.6z'/></svg>", ) => { Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(`${id}-img`, Services.io.newURI(img)); CustomizableUI.createWidget({ id, label, tooltiptext, defaultArea: CustomizableUI.AREA_NAVBAR, onCreated(btn) { btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important"); }, onCommand(e) { var win = e.view; var itemsToClear = [ "history", "sessions", "formdata", "cache", "downloads", "offlineApps", "pluginData" ]; var range = win.Sanitizer.getClearRange(0); win.Sanitizer.sanitize(itemsToClear, { ignoreTimespan: !range, range, }).then(() => { var alertsService = Cc["@mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService); alertsService.showAlertNotification(null, "История Очищена!", "", false); win.setTimeout(()=> alertsService.closeAlert(), 2000); }); }, }); })();
Кстати, должно быть не 5, а 6, видимо network.cookie.cookieBehavior = 0 нет.
Где нет? В кнопке есть network.cookie.cookieBehavior = 0,
номер на значке toolbarbutton-badge соответствует настройке в about:config
Отредактировано Vitaliy V. (24-04-2024 16:51:06)
Отсутствует
Где нет?
Да я не смотрел скрипт, выше написали что пунктов пять.
А с about:cfg можете исправить
(async ( id = "ucf-open-about-config", label = "about:config", tooltiptext = " ЛКМ Открыть about:config\n Ctrl+ЛКМ Искать выделенное / буфер в about:config\n ПКМ Открыть окно about:cfg\n Ctrl+ПКМ Искать выделенное / буфер в окне about:cfg", img = "chrome://user_chrome_files/content/custom_styles/svg/about-config-16.svg", aboutoldurl = "about:cfg", about_config = { get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, // https://forum.mozilla-russia.org/viewtopic.php?pid=804061#p804061 readFromClipboard() { var {getData, kGlobalClipboard: kGK} = Services.clipboard; var flavor = `text/${parseInt(Services.appinfo.platformVersion) >= 111 ? "plain" : "unicode"}`; var transferable = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); transferable.init(null); transferable.addDataFlavor(flavor); return (this.readFromClipboard = () => { try { getData(transferable, kGK); var out = {}; transferable.getTransferData(flavor, out); var url = out.value.QueryInterface(Ci.nsISupportsString).data; } finally { transferable.setTransferData(flavor, null); return url || ""; } })(); }, openClipboardConfigTab(win, clip = "", copy, url = "about:config") { var filter = this.readFromClipboard(win), nowarn = false, pref = url === "about:config" ? "browser.aboutConfig.showWarning" : "general.warnOnAboutConfig"; if (copy && clip != filter) this.clipboardHelp.copyString(clip); if (Services.prefs.getBoolPref(pref, true)) { Services.prefs.setBoolPref(pref, false); nowarn = true; } var browser = win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, url)); browser.addEventListener("pageshow", e => { var doc = e.target; var input = doc && doc.querySelector("input#about-config-search, search-textbox#textbox"); if (input && filter) { input.value = filter; input.focus(); input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true })); } if (nowarn) win.setTimeout(() => { Services.prefs.setBoolPref(pref, true); }, 200); }, { once: true }); }, openSelectedConfig(win, url, oldwin) { var clip = this.readFromClipboard(win); win.goDoCommand("cmd_copy"); win.setTimeout(() => { if (!oldwin) this.openClipboardConfigTab(win, clip, true, url); else this.openOldConfigWin(win, clip, true); }, 100); }, addTab(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.index = win.gBrowser.selectedTab._tPos + 1; return win.gBrowser.addTab(url, params); }, get configoldurl() { delete this.configoldurl; var mod = Cc[`@mozilla.org/network/protocol/about;1?what=${aboutoldurl.split(":")[1]}`].getService(Ci.nsIAboutModule); var url; try { url = mod.getChromeURI(Services.io.newURI(aboutoldurl)).spec; } catch (e) { url = mod.wrappedJSObject.uri?.spec; } return this.configoldurl = url || aboutoldurl; }, async openOldConfigWin(win, clip = "", copy) { var filter, input; if (copy) { filter = this.readFromClipboard(win); if (clip != filter) this.clipboardHelp.copyString(clip); } var type = "Preferences:ConfigManager", id = "config"; var _win = Services.wm.getMostRecentWindow(type); if (!_win) { let nowarn = false, pref = "general.warnOnAboutConfig"; if (copy && Services.prefs.getBoolPref(pref, true)) { Services.prefs.setBoolPref(pref, false); nowarn = true; } let url = this.configoldurl; let xs = Services.xulStore; let sx = xs.getValue(url, id, "screenX"); let sy = xs.getValue(url, id, "screenY"); let wh = xs.getValue(url, id, "width"); let ht = xs.getValue(url, id, "height"); let sm = xs.getValue(url, id, "sizemode"); let features = `chrome,dialog=no,resizable,${sx && sy ? `screenX=${sx !== "0" ? sx : "1"},screenY=${sy !== "0" ? sy : "1"}` : "centerscreen"}${wh && ht ? `,width=${wh},height=${ht}` : ""}`; _win = win.openDialog(url, type, features); await new Promise(resolve => { _win.windowRoot.addEventListener("DOMContentLoaded", () => { _win.windowRoot.addEventListener("MozUpdateWindowPos", () => { if (sm === "maximized") _win.maximize(); }, { once: true, capture: true }); resolve(); }, { once: true }); }); if (copy && nowarn) _win.setTimeout(() => { Services.prefs.setBoolPref(pref, true); }, 200); } var doc = _win.document; var docEl = doc.documentElement; docEl.setAttribute("windowtype", type); docEl.id = id; docEl.setAttribute("persist", "screenX screenY width height sizemode"); _win.focus(); if (!copy || !(input = doc.querySelector("search-textbox#textbox"))) return; input.value = filter; input.focus(); input.dispatchEvent(new _win.Event("input", { bubbles: true })); }, }) => { CustomizableUI.createWidget({ id: id, type: "custom", label: label, tooltiptext: tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild(doc) { var win = doc.defaultView; var trbn = doc.createXULElement("toolbarbutton"); trbn.id = id; trbn.className = "toolbarbutton-1 chromeclass-toolbar-additional"; trbn.setAttribute("label", label); trbn.setAttribute("context", ""); trbn.setAttribute("tooltiptext", tooltiptext); trbn.style.setProperty("list-style-image", `url("${img}")`, "important"); trbn.addEventListener("click", e => { if (e.button == 0) { if (e.getModifierState("Accel")) about_config.openSelectedConfig(win); else win.gBrowser.selectedTab = about_config.addTab(win, "about:config"); } else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); if (e.getModifierState("Accel")) about_config.openSelectedConfig(win, undefined, true); else about_config.openOldConfigWin(win); } }); return trbn; } }); })();
Отсутствует
А с about:cfg можете исправить
Если только about:config, без доп. бантиков, то работает это (изменить в конце третьей строки снизу на желаемое)
https://forum.mozilla-russia.org/viewto … 74#p804474
Отсутствует
с about:cfg
Пока Vitaliy V. не пришёл, сделает лучше, можно попробовать такой вариант:
// by Vitaly V. https://forum.mozilla-russia.org/viewtopic.php?pid=809326#p809326 (async ( id = "ucf-open-about-config", label = "about:config", tooltiptext = Services.locale.requestedLocale.startsWith("ru") ? "ЛКМ: Открыть about:config\nЛКМ+Shift: Открыть about:cfg\nСКМ: Искать выделенное в about:config\nСКМ+Shift: Искать выделенное в about:cfg\nПКМ: Открыть about:about" : "Left-click: Open about:config\nLeft-click+Shift: Open about:cfg\nMidle-click: Search for the highlighted in about:config\nMidle-click+Shift: Search for the highlighted in about:cfg\nRight-click: Open about:about", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;'><path d='m 8.66,15.4 h -1.2 c -0.69,0 -1.3,-0.5 -1.5,-1.2 L 5.58,13 C 5.32,12.9 5.07,12.7 4.82,12.5 L 3.41,12.9 C 2.76,13 2.04,12.8 1.69,12.1 L 1.09,11.2 C 0.748,10.5 0.838,9.75 1.31,9.33 l 1,-1 V 7.52 L 1.32,6.55 C 0.842,6.06 0.748,5.36 1.1,4.78 L 1.7,3.8 C 2.04,3.22 2.75,2.93 3.4,3.08 L 4.84,3.4 C 5.1,3.24 5.34,3.1 5.58,2.99 L 5.96,1.72 C 6.16,1.08 6.77,0.631 7.46,0.629 h 1.2 C 9.35,0.629 9.94,1.07 10,1.7 L 10.4,3 c 0.3,0.11 0.5,0.25 0.8,0.4 L 12.5,3.08 C 13.2,2.93 14,3.22 14.3,3.8 l 0.6,0.98 c 0.4,0.57 0.3,1.28 -0.2,1.77 l -1,0.97 v 0.81 l 1,1 c 0.5,0.42 0.6,1.17 0.2,1.87 l -0.6,0.9 C 14,12.8 13.2,13 12.5,12.9 l -1.3,-0.4 c -0.3,0.2 -0.5,0.4 -0.8,0.5 L 10,14.2 c -0.1,0.7 -0.64,1.2 -1.34,1.2 z'/><circle cx='8' cy='8' r='2.4'/></g></svg>", about_config = { get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, openClipboardConfigTab(win, url, clip = "", copy) { var filter = this.readFromClipboard(win), nowarn = false, pref = "browser.aboutConfig.showWarning", prefOld = "general.warnOnAboutConfig"; if (copy && clip != filter) this.clipboardHelp.copyString(clip); switch (url) { case "about:config": if (Services.prefs.getBoolPref(pref, false)) { Services.prefs.setBoolPref(pref, false); nowarn = true; } break; case "about:cfg": if (Services.prefs.getBoolPref(prefOld, false)) { Services.prefs.setBoolPref(prefOld, false); nowarn = true; } break; } win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, url)) .addEventListener("pageshow", e => { var doc = e.target; var input = doc?.querySelector("input#about-config-search") || doc?.querySelector("#textbox"); if (input && filter) { input.value = filter; input.focus(); input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true })); } if (nowarn) win.setTimeout(() => { switch (url) { case "about:config": Services.prefs.setBoolPref(pref, true); break; case "about:cfg": Services.prefs.setBoolPref(prefOld, true); break; } }, 200); }, { once: true }); }, openSelectedConfigTab(win, url) { var clip = this.readFromClipboard(win); win.goDoCommand("cmd_copy"); win.setTimeout(() => { this.openClipboardConfigTab(win, url, clip, true); }, 100); }, addTab(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.index = win.gBrowser.selectedTab._tPos + 1; return win.gBrowser.addTab(url, params); }, readFromClipboard(win) { var url = ""; try { let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(win.docShell.QueryInterface(Ci.nsILoadContext)); trans.addDataFlavor("text/plain"); let {clipboard} = Services; clipboard.getData(trans, clipboard.kGlobalClipboard); let data = {}; trans.getTransferData("text/plain", data); if (data.value) url = data.value.QueryInterface(Ci.nsISupportsString).data; } catch (ex) {} return url; }, } ) => { Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(`${id}-img`, Services.io.newURI(img)); CustomizableUI.createWidget({ id, type: "custom", label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild: function(doc) { var btn = doc.createXULElement("toolbarbutton"); var props = { id, label, context: "", tooltiptext, class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important"); btn.addEventListener("click", e => { var win = e.view; if (e.button == 0) if (!e.shiftKey) win.gBrowser.selectedTab = about_config.addTab(win, "about:config"); else win.gBrowser.selectedTab = about_config.addTab(win, "about:cfg"); else if (e.button == 1) if (!e.shiftKey) about_config.openSelectedConfigTab(win, "about:config"); else about_config.openSelectedConfigTab(win, "about:cfg"); else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); win.gBrowser.selectedTab = about_config.addTab(win, "about:about"); } }); return btn; }, }); })();
Жизнь иногда такое выкидывает, что хочется подобрать...
На форуме
А с about:cfg
Надо было выложить сам about:cfg полностью, а то ссылки недействительны кроме https://forum.mozilla-russia.org/viewto … 48#p806748
а там нет папки locale.
Вариант как и было с окном about:cfg
(async ( id = "ucf-open-old-about-config", label = "about:config", tooltiptext = "ЛКМ: Открыть about:config\nCtrl+ЛКМ: Искать выделенное / буфер в about:config\nПКМ: Открыть окно about:cfg\nCtrl+ПКМ: Искать выделенное / буфер в окне about:cfg", img = "data:image/svg+xml;charset=utf-8,<svg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 16 16'><g style='fill:none;stroke:context-fill rgb(142, 142, 152);stroke-opacity:context-fill-opacity;stroke-width:1.2;stroke-linecap:round;stroke-linejoin:round;'><path d='m 8.66,15.4 h -1.2 c -0.69,0 -1.3,-0.5 -1.5,-1.2 L 5.58,13 C 5.32,12.9 5.07,12.7 4.82,12.5 L 3.41,12.9 C 2.76,13 2.04,12.8 1.69,12.1 L 1.09,11.2 C 0.748,10.5 0.838,9.75 1.31,9.33 l 1,-1 V 7.52 L 1.32,6.55 C 0.842,6.06 0.748,5.36 1.1,4.78 L 1.7,3.8 C 2.04,3.22 2.75,2.93 3.4,3.08 L 4.84,3.4 C 5.1,3.24 5.34,3.1 5.58,2.99 L 5.96,1.72 C 6.16,1.08 6.77,0.631 7.46,0.629 h 1.2 C 9.35,0.629 9.94,1.07 10,1.7 L 10.4,3 c 0.3,0.11 0.5,0.25 0.8,0.4 L 12.5,3.08 C 13.2,2.93 14,3.22 14.3,3.8 l 0.6,0.98 c 0.4,0.57 0.3,1.28 -0.2,1.77 l -1,0.97 v 0.81 l 1,1 c 0.5,0.42 0.6,1.17 0.2,1.87 l -0.6,0.9 C 14,12.8 13.2,13 12.5,12.9 l -1.3,-0.4 c -0.3,0.2 -0.5,0.4 -0.8,0.5 L 10,14.2 c -0.1,0.7 -0.64,1.2 -1.34,1.2 z'/><circle cx='8' cy='8' r='2.4'/></g></svg>", aboutoldurl = "about:cfg", about_config = { get clipboardHelp() { delete this.clipboardHelp; return this.clipboardHelp = Cc["@mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper); }, readFromClipboard(win) { var url = ""; try { let trans = Cc["@mozilla.org/widget/transferable;1"].createInstance(Ci.nsITransferable); trans.init(win.docShell.QueryInterface(Ci.nsILoadContext)); trans.addDataFlavor("text/plain"); let {clipboard} = Services; clipboard.getData(trans, clipboard.kGlobalClipboard); let data = {}; trans.getTransferData("text/plain", data); if (data.value) url = data.value.QueryInterface(Ci.nsISupportsString).data; } catch (ex) {} return url; }, openClipboardConfigTab(win, clip = "", copy, url = "about:config") { var filter = this.readFromClipboard(win), nowarn = false, pref = url === "about:config" ? "browser.aboutConfig.showWarning" : "general.warnOnAboutConfig"; if (copy && clip != filter) this.clipboardHelp.copyString(clip); if (Services.prefs.getBoolPref(pref, true)) { Services.prefs.setBoolPref(pref, false); nowarn = true; } win.gBrowser.getBrowserForTab(win.gBrowser.selectedTab = this.addTab(win, url)) .addEventListener("pageshow", e => { var doc = e.target; var input = doc?.querySelector("input#about-config-search, search-textbox#textbox"); if (input && filter) { input.value = filter; input.focus(); input.dispatchEvent(new doc.defaultView.Event("input", { bubbles: true })); } if (nowarn) win.setTimeout(() => { Services.prefs.setBoolPref(pref, true); }, 200); }, { once: true }); }, openSelectedConfig(win, url, oldwin) { var clip = this.readFromClipboard(win); win.goDoCommand("cmd_copy"); win.setTimeout(() => { if (!oldwin) this.openClipboardConfigTab(win, clip, true, url); else this.openOldConfigWin(win, clip, true); }, 100); }, addTab(win, url, params = {}) { params.triggeringPrincipal = Services.scriptSecurityManager.getSystemPrincipal(); params.index = win.gBrowser.selectedTab._tPos + 1; return win.gBrowser.addTab(url, params); }, get configoldurl() { delete this.configoldurl; var mod = Cc[`@mozilla.org/network/protocol/about;1?what=${aboutoldurl.split(":")[1]}`].getService(Ci.nsIAboutModule); var url; try { url = mod.getChromeURI(Services.io.newURI(aboutoldurl)).spec; } catch (e) { url = mod.wrappedJSObject.uri?.spec; } return this.configoldurl = url || aboutoldurl; }, async openOldConfigWin(win, clip = "", copy) { var filter, input; if (copy) { filter = this.readFromClipboard(win); if (clip != filter) this.clipboardHelp.copyString(clip); } var type = "Preferences:ConfigManager", id = "config"; var w = Services.wm.getMostRecentWindow(type); if (!w) { let nowarn = false, pref = "general.warnOnAboutConfig"; if (copy && Services.prefs.getBoolPref(pref, true)) { Services.prefs.setBoolPref(pref, false); nowarn = true; } let url = this.configoldurl; let {xulStore: xs} = Services; let sx = +xs.getValue(url, id, "screenX") || xs.setValue(url, id, "screenX", 1) || 1; let sy = +xs.getValue(url, id, "screenY") || xs.setValue(url, id, "screenY", 1) || 1; let wh = +xs.getValue(url, id, "width") || xs.setValue(url, id, "width", 700) || 700; let ht = +xs.getValue(url, id, "height") || xs.setValue(url, id, "height", 600) || 600; let sm = xs.getValue(url, id, "sizemode"); let features = `chrome,dialog=no,resizable,${`screenX=${sx},screenY=${sy}`}${`,width=${wh},height=${ht}`}`; w = win.openDialog(url, type, features); await new Promise(resolve => { w.windowRoot.addEventListener("DOMContentLoaded", () => { w.windowRoot.addEventListener("MozUpdateWindowPos", () => { if (sm === "maximized") w.maximize(); }, { once: true, capture: true }); resolve(); }, { once: true }); }); let docEl = w.document.documentElement; docEl.setAttribute("windowtype", type); docEl.id = id; docEl.setAttribute("persist", "screenX screenY width height sizemode"); if (copy && nowarn) w.setTimeout(() => { Services.prefs.setBoolPref(pref, true); }, 200); } w.focus(); if (!copy || !(input = w.document.querySelector("search-textbox#textbox"))) return; input.value = filter; input.focus(); input.dispatchEvent(new w.Event("input", { bubbles: true })); }, } ) => { Services.io.getProtocolHandler("resource") .QueryInterface(Ci.nsIResProtocolHandler) .setSubstitution(`${id}-img`, Services.io.newURI(img)); CustomizableUI.createWidget({ id, type: "custom", label, tooltiptext, localized: false, defaultArea: CustomizableUI.AREA_NAVBAR, onBuild(doc) { var btn = doc.createXULElement("toolbarbutton"); var props = { id, label, context: "", tooltiptext, class: "toolbarbutton-1 chromeclass-toolbar-additional", }; for (let p in props) btn.setAttribute(p, props[p]); btn.style.setProperty("list-style-image", `url("resource://${id}-img")`, "important"); btn.addEventListener("click", e => { if (e.button == 0) { let win = e.view; if (e.getModifierState("Control")) about_config.openSelectedConfig(win); else win.gBrowser.selectedTab = about_config.addTab(win, "about:config"); } else if (e.button == 2) { e.preventDefault(); e.stopPropagation(); if (e.getModifierState("Control")) about_config.openSelectedConfig(e.view, undefined, true); else about_config.openOldConfigWin(e.view); } }); return btn; }, }); })();
Отредактировано Vitaliy V. (25-04-2024 14:44:51)
Отсутствует
Vitaliy V.
Спасибо.
aboutconfigOLDv3-mjs-115+.7z
Может подскажите еще как убрать этот отстойный салатовый цвет в старом about_config, вот это работает, для списка
:root {
--in-content-primary-button-text-color: white;
--in-content-primary-button-background: #0074E8;
а это, для поля поиска, нет
--in-content-focus-outline: #0074E8;
xul|search-textbox[focused] {
border: 1px solid #0074E8;
Отредактировано _zt (25-04-2024 17:18:56)
Отсутствует
fuchsfan
Farby
Да мой и так работал, даже на , просто, раз уж пошла такая пьянка, решил попросить обновить.
Добавлено 25-04-2024 18:47:09
DumbyQuickToggleAboutConfig перестал обновлять страницу на , можете поправить? - Регистр не исправил - win.BrowserCommands.reloadSkipCache()
И еще при активации пункта с перезагрузкой из второго меню, при отказе от перезагрузки (например, когда надо еще один пункт переключить) открывается первое меню. А ожидается открытие последнего использованного меню.
(async (name, id, func) => { if (name == "Object") return CustomizableUI.createWidget(func()); // Несовместимо с Fx 116+ // var win = name == "Window", g = Components.utils.import("resource://gre/modules/Services.jsm", {}); if (g[id]) {if (win) return;} else g[id] = func(); if (win) return CustomizableUI.createWidget(g[id]); addDestructor(r => r[5] == "e" && delete g[id]); g[id].onCreated(this); })(this.constructor.name, "QuickToggleAboutConfigSettings", () => { var {prefs} = Services, db = prefs.getDefaultBranch(""); var pv = parseInt(Services.appinfo.platformVersion); var xul_ns = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var primary = [{ pref: ["network.proxy.type", "Настройки прокси"], userChoice: 5, userAlt: 1, refresh: true, values: [ [0, "Не проксировать", "0"], [5, "Системные (IE)", "5"], [2, "Авто (proxi.pac)", "2"], [1, "Прописанные", "1"], [4, "Автоопределение", "4"] ]}, null, { pref: ["browser.zoom.full", "Масштабировать"], userChoice: false, userAlt: true, refresh: true, values: [[true, "Весь контент"], [false, "Только текст"]] }, null, { pref: ["permissions.default.image", "Загружать web-графику"], userChoice: 1, userAlt: 2, refresh: true, values: [ [1, "Да", "1"], [3, "С сайта", "3"], [2, "Нет", "2"] ]} ]; //============================================================================= var secondary = [{ pref: ["dom.security.https_only_mode", "Режим Только HTTS"], userChoice: false, refresh: true, values: [[true, "Скучно без проблем"], [false, "Нет"]] },{ pref: ["browser.display.use_document_fonts", "Загружать web-шрифты"], userChoice: 1, refresh: true, values: [[1, "Да"], [0, "Нет"]] },{ pref: ["layout.css.font-visibility", "Видимость лок.шрифтов"], userChoice: 1, refresh: true, values: [ [1, "Базовые"], [2, "+доп.яз.пак."], [3, "+уст.польз."], ]}, null, { pref: ["ui.prefersReducedMotion", "Анимация chrome"], userChoice: 1, userAlt: 0, values: [[1, "Отключена"], [0, "Включена"]] },{ pref: ["gfx.webrender.software", "• Software (also bug w7)"], userChoice: true, userAlt: false, restart: true, values: [[true, "Включен"], [false, "Отключен"]] } ]; return { id: "QuickToggleAboutConfigSettings", label: "Quick Toggle Settings", tooltiptext: "Quick Toggle Settings\n\nЛКМ Первое меню\nПКМ Второе меню", localized: false, image: "chrome://user_chrome_files/content/custom_styles/svg/QuickToggle.svg", onCreated(btn) { btn.setAttribute("image", this.image); var doc = btn.ownerDocument; btn.btn = true; btn.domParent = null; btn.popups = new btn.ownerGlobal.Array(); this.createPopup(doc, btn, "primary", primary); this.createPopup(doc, btn, "secondary", secondary); this.createCloseMenusOption(doc, btn); btn.linkedObject = this; for(var type of ["command", "contextmenu"]) btn.setAttribute("on" + type, `linkedObject.${type}(event)`); }, createPopup(doc, btn, name, data) { var popup = doc.createElementNS(xul_ns, "menupopup"); var prop = name + "Popup"; btn.popups.push(btn[prop] = popup); popup.id = this.id + "-" + prop; for (var type of ["popupshowing", "click"]) popup.setAttribute("on" + type, `parentNode.linkedObject.${type}(event)`); for(var obj of data) popup.append(this.createElement(doc, obj)); btn.append(popup); }, map: {b: "Bool", n: "Int", s: "String"}, createElement(doc, obj) { if (!obj) return doc.createElementNS(xul_ns, "menuseparator"); var pref = doc.ownerGlobal.Object.create(null), node, img, bool; for(var [key, val] of Object.entries(obj)) { if (key == "pref") { var [apref, lab, akey, ttt] = val; pref.pref = apref; pref.lab = lab || apref; if (ttt) pref.ttt = ttt; } else if (key == "image") img = val, pref.img = true; else if (key != "values") pref[key] = val; else pref.hasVals = true; } var type = prefs.getPrefType(pref.pref); var str = this.map[type == prefs.PREF_INVALID ? obj.values ? (typeof obj.values[0][0])[0] : "b" : type == prefs.PREF_BOOL ? "b" : type == prefs.PREF_INT ? "n" : "s" ]; pref.get = prefs[`get${str}Pref`]; pref.set = prefs[`set${str}Pref`]; node = doc.createElementNS(xul_ns, "menu"); node.className = "menu-iconic"; node.setAttribute("closemenu", "none"); img && node.setAttribute("image", img); akey && node.setAttribute("accesskey", akey); (node.pref = pref).vals = doc.ownerGlobal.Object.create(null); this.createRadios(doc, str.startsWith("B") && !pref.hasVals ? [[true, "true"], [false, "false"]] : obj.values, node.appendChild(doc.createElementNS(xul_ns, "menupopup")) ); if ("userChoice" in obj) pref.noAlt = !("userAlt" in obj); return node; }, createCloseMenusOption(doc, btn) { var pn = this.closePref = "QuickToggleAboutConfigSettings.closeMenus"; var data = [null, { pref: [pn, "Автозакрытие этого меню"], values: [[true, "Да"], [false, "Нет"]] }]; var setCloseMenus = e => { e.stopPropagation(); var trg = e.target, {pref, val} = trg, updPopup = true, clear; switch(e.type) { case "command": pref = (trg = trg.closest("menu")).pref; updPopup = false; break; case "click": if (e.button) return; break; case "contextmenu": e.preventDefault(); clear = pref; } if (!pref) return; if (clear) prefs.clearUserPref(pn); else if (!updPopup && val === pref.val) return; else pref.set(pn, val !== undefined ? val : !pref.val); this.upd(trg); updPopup && this.popupshowing(null, trg.querySelector("menupopup")); } (this.createCloseMenusOption = (doc, btn) => { for(var obj of data) btn.secondaryPopup.append(this.createElement(doc, obj)); var m = btn.secondaryPopup.lastChild; m.style.cssText = "fill: lightblue !important; list-style-image: url(chrome://browser/skin/menu.svg) !important;"; m.setAttribute("oncommand", "setCloseMenus(event)"); m.onclick = m.oncontextmenu = m.setCloseMenus = setCloseMenus; })(doc, btn); }, UserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHqSURBVDhPpVJBTxNBGH1LLakxVEJQQIkhlZCAJDYR/BGScNCDwZMcuEji2ZP+BD14MCGciDEaEw8e1At3QGLlwAUOFtm6tut2uwtb2t3p8GbZ0iXlVF/y5ttkv+/Nmzej5XI5/A+6otoxTh1ks9mwhniJHvRiBAHXLjRIEy7yeIqjqAPNuXYHS5jGVby7PTT27eHo7Or9zL3Va/19Xyj5FsuYjLpOcdbBG9xFGh+fZRaGJ5O3tB7tMrcXcGQZP+pb8tXuyjpdPcA89HYHynYazxdvzg5nkgOapFsPNleXP+uY6L6hzYxMT+EC5vCVa4SWAM880Ju4cyVxUXNkERUeuyJLIR1+O6wTqcEEUngEA5eiqZgAAxtMpfur0sIBLA7+hS2NkK5UGVpsqgEJjLMkT4biAkzbE27D5u7/ZAFWSB1l0iRtUokyEj+aCBEXMHcOA70Y/IElfsMUeyiJPIpBHiZZEvv4Vcsrge9Mi1ZO0BJQ98yw9w4tWT4yYNV1ki78AuyggHLNwLZjC1Txnpl60VRMQD2SBl5sGsHaT88XJd+DEzioCAd6rYpN1xf7Jj5T4BMe00eE9pf4GteZ8Ry6mbYKDDyzxAblP4TDT1BUbc2585+yumd1Vc201ZmV7djObQKdopVBRwCOAVyl9qcQtNEaAAAAAElFTkSuQmCC", notUserChoiceImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHqSURBVDhPpVJNSxtRFD1PJ9GMMVpaKyWhRGwRFy7Utv+gVFyUgoWif8Ct+APMsvQX+BuUWhdBcOvSDwi1XVhK0WgmTr4mmphoJvPRe5NnxhLdpAcO9828d869794nXNfF/6BLxo7RqiAcDjciYx3oDwFRBxikT4ey5CtAcg64aZ4ANE1rxDaDLeB176Aae/zx/ZR/NDqEuu1UD39oxsZ2wnIRmwV+8rl7DeLAGzXg+/pidSWivBwVCPQDvH91AfPot/tn6fOedW3NzTT0TYNWD7hsVfWtjH1ZjCjPggImFV25AKpE+xr+6CMxsvzpVXePmE8AipR5Bnzn4bcT0yJoCZSyQDkPXOrEDDHXYG8k0B18/nSBdvukzDPghqlB/xOUi4BBgiIJDUleF0lmVaEo7ngd8EnZP2N0uiolBwXKmksDegrISubovvyPWauR3kPLgBb5q+O8hnMyOD8jJoknTaZPKZLRSQp2+eaA6q9JmWcwTHPWv2cT0E0XGcqos4lkhgz4X7Jql3O1NZNaK2WewSQ9EtqIHcWPd5FybWQNoECNNApkdgmcwv61k47TbDbf0VykrP0hfaPlADAfCmFBERiHQN2sY79UwTqLP1BX+NyDL5HBc+ZR3Xab78xl383cZtAp7o6xAwB/AT+Y7GFJS/NjAAAAAElFTkSuQmCC", UserAltImg: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAH7SURBVDhPpVJLa1NBFP5mJolNcrWhtiq9Betjk0VFfNS1O7ciXbQguBDXxR9g3Lnown8g3SqCi24K/gCxVbqogiBaxdyY5nFrkt5H5j7GmZvxphDdxA8+Dgzn+86Zcw4RQuB/QHUcG2kHpmkmUWHtEo6DY55mUCIhYkHQOlXA97vv4esUWJaVxBGDp2Vcz54klakbN69kZ8wZRHHsVT9b7e2tHdFH5eEuPqi8vxqsLWDxmIGX5+8/mMufPkdA8zIBiMMuvNo3sbf+bCt2cWd1V+kHBukMVNuFE3h08d7SXHF6glC4oHFXGnTBmA9j1iBnb9+6xvJYfryIjJYdGaL889TlC1cLkyFhQQek3wThjYSUt8GCX9Iky/JniitGF0WtGhpQgdLEJJvO8AMpUgIbtK/JbflmI0cc2Y0oy/JZLRsaEIKYcCemXgvUlVXdOpj/c0Bnf0BXdhXxQEsSpAZqVU7NtkRPJh5aoAmrCYnzA9SpIbDr4G74Lsihr2VDA7Xn5kdvx2mGgnr7soNaSubXQb0GelUv8lt4Pj8rJ6yRGqgjERyVT68P3rarJIo6HojrJOS2h8Yejb6+OdyIe3i1tIlIy0YP6ckCTCOH5WIJKxmGsnwKeB/bbgcvlHj1Cxoq75+XqKD2rFb1Z9rqz6rto5VHDMZFOoPxAPwGQ077rbKVfhEAAAAASUVORK5CYII=", upd(node) { var {pref} = node, def = false, user = false, val; if (prefs.getPrefType(pref.pref) != prefs.PREF_INVALID) { var pn = pref.pref; try {val = pref.defVal = db[pref.get.name](pn); def = true} catch(ex) {def = false;} var user = prefs.prefHasUserValue(pn); if (user) try {val = pref.get(pn, undefined);} catch(ex) {} } if (val == pref.val && def == pref.def && user == pref.user) return; pref.val = val; pref.def = def; pref.user = user; var exists = def || user; var ttt = exists ? val : "Этот преф не существует"; if (ttt === "") ttt = "[ empty_string ]"; ttt += "\n" + pref.pref; if (pref.ttt) ttt += "\n" + pref.ttt; node.tooltipText = ttt; var img, alt = "userAlt" in pref && val == pref.userAlt; if (alt) img = this.UserAltImg; if ("userChoice" in pref) if (val == pref.userChoice) //node.style.removeProperty("color"), img = this.UserChoiceImg; else { //node.style.setProperty("color", "maroon", "important"); if (!alt) img = this.notUserChoiceImg; } if (!pref.img) img ? node.setAttribute("image", img) : node.removeAttribute("image"); user ? node.style.setProperty("font-style", "italic", "important") : node.style.removeProperty("font-style"); var {lab} = pref; if (exists && pref.hasVals) { if (val in pref.vals) var sfx = pref.vals[val] || val; else var sfx = user ? "Другое" : "По умолчанию"; lab += ` ${"restart" in pref ? "— ↯" : "refresh" in pref ? "— ⧖" : "— -"} "${sfx}"`; } node.setAttribute("label", lab); }, createRadios(doc, vals, popup) { for(var arr of vals) { if (!arr) { popup.append(doc.createElementNS(xul_ns, "menuseparator")); continue; } var [val, lab, key, ttt] = arr; var menuitem = doc.createElementNS(xul_ns, "menuitem"); menuitem.setAttribute("type", "radio"); menuitem.setAttribute("closemenu", "none"); menuitem.style.setProperty("font-style", "italic", "important"), menuitem.setAttribute("label", popup.parentNode.pref.vals[val] = lab); key && menuitem.setAttribute("accesskey", key); var tip = menuitem.val = val; if (ttt) tip += "\n" + ttt; menuitem.tooltipText = tip; popup.append(menuitem); } }, openPopup(popup) { var btn = popup.parentNode; if (btn.domParent != btn.parentNode) { btn.domParent = btn.parentNode; var pos; if (btn.matches(".widget-overflow-list > :scope")) pos = "after_start"; else var win = btn.ownerGlobal, {width, height, top, bottom, left, right} = btn.closest("toolbar").getBoundingClientRect(), pos = width > height ? `${win.innerHeight - bottom > top ? "after" : "before"}_start` : `${win.innerWidth - right > left ? "end" : "start"}_before`; for(var p of btn.popups) p.setAttribute("position", pos); } popup.openPopup(btn); }, maybeRestart(node, conf) { if (conf && !Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) return; var cancel = Cc["@mozilla.org/supports-PRBool;1"].createInstance(Ci.nsISupportsPRBool); Services.obs.notifyObservers(cancel, "quit-application-requested", "restart"); return cancel.data ? Services.prompt.alert(null, this.label, "Запрос на выход отменен.") : this.restart(); }, async restart() { var meth = Services.appinfo.inSafeMode ? "restartInSafeMode" : "quit"; Services.startup[meth](Ci.nsIAppStartup.eAttemptQuit | Ci.nsIAppStartup.eRestart); }, regexpRefresh: /^(?:view-source:)?(?:https?|ftp)/, maybeRe(node, fe) { var {pref} = node; if ("restart" in pref) { if (this.maybeRestart(node, pref.restart)) return; } else this.popupshowing(fe, node.parentNode); if ("refresh" in pref) { var win = node.ownerGlobal; if (this.regexpRefresh.test(win.gBrowser.currentURI.spec)) pref.refresh ? win.BrowserCommands.reloadSkipCache() : win.BrowserCommands.reload(); } }, maybeClosePopup(e, trg) { !e.ctrlKey && prefs.getBoolPref(this.closePref, undefined) && trg.parentNode.hidePopup(); }, command(e) { var trg = e.target; if (trg.btn) return trg.secondaryPopup.state == "closed" && this.openPopup(trg.primaryPopup); var menu = trg.closest("menu"), newVal = trg.val; this.maybeClosePopup(e, menu); if (newVal != menu.pref.val) menu.pref.set(menu.pref.pref, newVal), this.maybeRe(menu, true); }, popupshowing(e, trg = e.target) { if (trg.state == "closed") return; if (trg.id) { for(var node of trg.children) { if (node.nodeName.endsWith("r")) continue; this.upd(node); !e && node.open && this.popupshowing(null, node.querySelector("menupopup")); } return; } var {pref} = trg.closest("menu"), findChecked = true; var findDef = "defVal" in pref; var checked = trg.querySelector("[checked]"); if (checked) { if (checked.val == pref.val) { if (findDef) findChecked = false; else return; } else checked.removeAttribute("checked"); } if (findDef) { var def = trg.querySelector("menuitem:not([style*=font-style]"); if (def) if (def.val == pref.defVal) { if (findChecked) findDef = false; else return; } else def.style.setProperty("font-style", "italic", "important"); } for(var node of trg.children) if ("val" in node) { if (findChecked && node.val == pref.val) { node.setAttribute("checked", true); if (findDef) findChecked = false; else break; } if (findDef && node.val == pref.defVal) { node.style.removeProperty("font-style"); if (findChecked) findDef = false; else break; } } }, contextmenu(e) { var trg = e.target; if (trg.btn) { if (e.ctrlKey || e.shiftKey) return; if (e.detail == 2) return trg.secondaryPopup.hidePopup(); this.openPopup(trg.secondaryPopup); } else if ("pref" in trg) { this.maybeClosePopup(e, trg); if (trg.pref.user) prefs.clearUserPref(trg.pref.pref), this.maybeRe(trg); } e.preventDefault(); }, click(e) { if (e.button) return; var trg = e.target, {pref} = trg; if (!pref) return; this.maybeClosePopup(e, trg); if (!("noAlt" in pref)) return; if (pref.val == pref.userChoice) if (pref.noAlt) return; else pref.set(pref.pref, pref.userAlt); else pref.set(pref.pref, pref.userChoice); this.maybeRe(trg); } }; });
Отредактировано _zt (25-04-2024 20:45:55)
Отсутствует
ожидается открытие последнего использованного меню
Что-то я не припомню, чтобы после confirm'а
вообще ожидалось открытие каких-либо меню.
Но, раз ожидается, возможно, так подойдёт
/* if (conf && !Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) return; */ if (conf) { node.ownerGlobal.event.preventDefault(); if (!Services.prompt.confirm(null, this.label, "Перезапустить браузер?")) { var popup = node.closest("menupopup"); return popup.openPopup(popup.parentNode); } }
Отсутствует
Да мой и так работал, даже на
Ну и пользуйтесь на здоровье...
Vitaliy V. спасибо за ucf-open-about-config, классная идея передачи параметров, а я думал что так нельзя!!!!
Жизнь иногда такое выкидывает, что хочется подобрать...
На форуме
egorsemenov06
/* btn.image = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAk1BMVEX///8/Pz8BAQF8fHwJCQkCAgIJCQl8fHx9fX0AAABJSUkBAQENDQ0wMDBVVVUAAABra2t0dHR7e3thYWEBAQEAAAAAAAABAQEAAAAgICABAQEBAQH8/Pzw8PDp6en39/fj4+Pe3t41V9I/YeWKioqDg4N9fX0jRa8wUrVoaGhkhuxWeNx1dXVCZMhvb28kRqsqTL4KidXxAAAAHHRSTlMAAABndwAAAAA0blVZcm1naWhNa6hrcJ8AAKRU4jk/3gAAAHVJREFUeF6FyMUCwjAUBdEbaQupUMOjqMv/fx1dQN6yZ3aDcWnyw6ezoRWNYc15kqKQZCFlgTKQQwgllL/dn5f3+bPb+6P3CpWNw56srdCZOMzDmA61i8O9nKvRaHLVukEryFKIFtnkj7ENYxmNdd5v+5xj1BcJ/w9Kj6K7ZAAAAABJRU5ErkJggg=="; */ btn.image = this.icon; }, 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:context-fill rgb(142, 142, 152);fill-opacity:context-fill-opacity;' d='M0 6a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2H2a2 2 0 0 1-2-2V6zm13 .25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5a.25.25 0 0 0-.25.25zM2.25 8a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 3 8.75v-.5A.25.25 0 0 0 2.75 8h-.5zM4 8.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 5 8.75v-.5A.25.25 0 0 0 4.75 8h-.5a.25.25 0 0 0-.25.25zM6.25 8a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 7 8.75v-.5A.25.25 0 0 0 6.75 8h-.5zM8 8.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 9 8.75v-.5A.25.25 0 0 0 8.75 8h-.5a.25.25 0 0 0-.25.25zM13.25 8a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5zm0 2a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5zm-3-2a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h1.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-1.5zm.75 2.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5a.25.25 0 0 0-.25.25zM11.25 6a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5zM9 6.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5A.25.25 0 0 0 9.75 6h-.5a.25.25 0 0 0-.25.25zM7.25 6a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 8 6.75v-.5A.25.25 0 0 0 7.75 6h-.5zM5 6.25v.5c0 .138.112.25.25.25h.5A.25.25 0 0 0 6 6.75v-.5A.25.25 0 0 0 5.75 6h-.5a.25.25 0 0 0-.25.25zM2.25 6a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h1.5A.25.25 0 0 0 4 6.75v-.5A.25.25 0 0 0 3.75 6h-1.5zM2 10.25v.5c0 .138.112.25.25.25h.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-.5a.25.25 0 0 0-.25.25zM4.25 10a.25.25 0 0 0-.25.25v.5c0 .138.112.25.25.25h5.5a.25.25 0 0 0 .25-.25v-.5a.25.25 0 0 0-.25-.25h-5.5z'/></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;
Отсутствует